Documentation ¶
Index ¶
- Constants
- type DerivedBlockData
- func (block *DerivedBlockData) GetProgramForTestingOnly(addressLocation common.AddressLocation) *invalidatableEntry[*interpreter.Program]
- func (block *DerivedBlockData) NewChildDerivedBlockData() *DerivedBlockData
- func (block *DerivedBlockData) NewDerivedTransactionData(snapshotTime LogicalTime, executionTime LogicalTime) (*DerivedTransactionData, error)
- func (block *DerivedBlockData) NewSnapshotReadDerivedTransactionData(snapshotTime LogicalTime, executionTime LogicalTime) (*DerivedTransactionData, error)
- func (block *DerivedBlockData) NextTxIndexForTestingOnly() uint32
- type DerivedChainData
- func (chain *DerivedChainData) Get(currentBlockId flow.Identifier) *DerivedBlockData
- func (chain *DerivedChainData) GetOrCreateDerivedBlockData(currentBlockId flow.Identifier, parentBlockId flow.Identifier) *DerivedBlockData
- func (chain *DerivedChainData) NewDerivedBlockDataForScript(currentBlockId flow.Identifier) *DerivedBlockData
- type DerivedDataTable
- func (table *DerivedDataTable[TKey, TVal]) EntriesForTestingOnly() map[TKey]*invalidatableEntry[TVal]
- func (table *DerivedDataTable[TKey, TVal]) GetForTestingOnly(key TKey) *invalidatableEntry[TVal]
- func (table *DerivedDataTable[TKey, TVal]) InvalidatorsForTestingOnly() chainedTableInvalidators[TKey, TVal]
- func (table *DerivedDataTable[TKey, TVal]) LatestCommitExecutionTimeForTestingOnly() LogicalTime
- func (table *DerivedDataTable[TKey, TVal]) NewChildTable() *DerivedDataTable[TKey, TVal]
- func (table *DerivedDataTable[TKey, TVal]) NewSnapshotReadTableTransaction(snapshotTime LogicalTime, executionTime LogicalTime) (*TableTransaction[TKey, TVal], error)
- func (table *DerivedDataTable[TKey, TVal]) NewTableTransaction(snapshotTime LogicalTime, executionTime LogicalTime) (*TableTransaction[TKey, TVal], error)
- func (table *DerivedDataTable[TKey, TVal]) NextTxIndexForTestingOnly() uint32
- type DerivedTransactionData
- func (transaction *DerivedTransactionData) AddInvalidator(invalidator TransactionInvalidator)
- func (transaction *DerivedTransactionData) Commit() error
- func (transaction *DerivedTransactionData) GetMeterParamOverrides(txnState *state.TransactionState, ...) (MeterParamOverrides, error)
- func (transaction *DerivedTransactionData) GetProgram(addressLocation common.AddressLocation) (*interpreter.Program, *state.State, bool)
- func (transaction *DerivedTransactionData) SetProgram(addressLocation common.AddressLocation, program *interpreter.Program, ...)
- func (transaction *DerivedTransactionData) Validate() error
- type LogicalTime
- type MeterParamOverrides
- type MeterParamOverridesInvalidator
- type ProgramInvalidator
- type RetryableError
- type TableInvalidator
- type TableTransaction
- func (txn *TableTransaction[TKey, TVal]) AddInvalidator(invalidator TableInvalidator[TKey, TVal])
- func (txn *TableTransaction[TKey, TVal]) Commit() RetryableError
- func (txn *TableTransaction[TKey, TVal]) Get(key TKey) (TVal, *state.State, bool)
- func (txn *TableTransaction[TKey, TVal]) GetOrCompute(txnState *state.TransactionState, key TKey, computer ValueComputer[TKey, TVal]) (TVal, error)
- func (txn *TableTransaction[TKey, TVal]) Set(key TKey, value TVal, state *state.State)
- func (txn *TableTransaction[TKey, TVal]) Validate() RetryableError
- type TransactionInvalidator
- type ValueComputer
Constants ¶
const ( // All events associated with the parent block is assigned the same value. // // Note that we can assign the time to any value in the range // [math.MinInt64, -1]. ParentBlockTime = LogicalTime(-1) // All events associated with a child block is assigned the same value. // // Note that we can assign the time to any value in the range // (math.MaxUint32 + 1, math.MaxInt64]. (The +1 is needed for assigning // EndOfBlockExecutionTime a unique value) ChildBlockTime = LogicalTime(math.MaxInt64) // EndOfBlockExecutionTime is used when the real tx index is unavailable, // such as during script execution. EndOfBlockExecutionTime = ChildBlockTime - 1 // A snapshot read transaction may occur at any time within the range // [0, EndOfBlockExecutionTime] LargestSnapshotReadTransactionExecutionTime = EndOfBlockExecutionTime // A normal transaction cannot commit to EndOfBlockExecutionTime. // // Note that we can assign the time to any value in the range // [max.MathUInt32, EndOfBlockExecutionTime) LargestNormalTransactionExecutionTime = EndOfBlockExecutionTime - 1 )
const DefaultDerivedDataCacheSize = 1000
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type DerivedBlockData ¶
type DerivedBlockData struct {
// contains filtered or unexported fields
}
DerivedBlockData is a simple fork-aware OCC database for "caching" derived data for a particular block.
func NewEmptyDerivedBlockData ¶
func NewEmptyDerivedBlockData() *DerivedBlockData
func NewEmptyDerivedBlockDataWithTransactionOffset ¶
func NewEmptyDerivedBlockDataWithTransactionOffset(offset uint32) *DerivedBlockData
This variant is needed by the chunk verifier, which does not start at the beginning of the block.
func (*DerivedBlockData) GetProgramForTestingOnly ¶
func (block *DerivedBlockData) GetProgramForTestingOnly( addressLocation common.AddressLocation, ) *invalidatableEntry[*interpreter.Program]
func (*DerivedBlockData) NewChildDerivedBlockData ¶
func (block *DerivedBlockData) NewChildDerivedBlockData() *DerivedBlockData
func (*DerivedBlockData) NewDerivedTransactionData ¶
func (block *DerivedBlockData) NewDerivedTransactionData( snapshotTime LogicalTime, executionTime LogicalTime, ) ( *DerivedTransactionData, error, )
func (*DerivedBlockData) NewSnapshotReadDerivedTransactionData ¶
func (block *DerivedBlockData) NewSnapshotReadDerivedTransactionData( snapshotTime LogicalTime, executionTime LogicalTime, ) ( *DerivedTransactionData, error, )
func (*DerivedBlockData) NextTxIndexForTestingOnly ¶
func (block *DerivedBlockData) NextTxIndexForTestingOnly() uint32
type DerivedChainData ¶
type DerivedChainData struct {
// contains filtered or unexported fields
}
DerivedChainData is a cache of DerivedBlockData databases used for speeding up cadence execution.
Since programs are derived from external source, the DerivedBlockData databases need not be durable and can be recreated on the fly.
func NewDerivedChainData ¶
func NewDerivedChainData(chainCacheSize uint) (*DerivedChainData, error)
func (*DerivedChainData) Get ¶
func (chain *DerivedChainData) Get( currentBlockId flow.Identifier, ) *DerivedBlockData
func (*DerivedChainData) GetOrCreateDerivedBlockData ¶
func (chain *DerivedChainData) GetOrCreateDerivedBlockData( currentBlockId flow.Identifier, parentBlockId flow.Identifier, ) *DerivedBlockData
func (*DerivedChainData) NewDerivedBlockDataForScript ¶
func (chain *DerivedChainData) NewDerivedBlockDataForScript( currentBlockId flow.Identifier, ) *DerivedBlockData
type DerivedDataTable ¶
type DerivedDataTable[TKey comparable, TVal any] struct { // contains filtered or unexported fields }
DerivedDataTable is a rudimentary fork-aware OCC database table for "caching" homogeneous (TKey, TVal) pairs for a particular block.
The database table enforces atomicity and isolation, but not consistency and durability. Consistency depends on the user correctly implementing the table's invalidator. Durability is not needed since the values are derived from ledger and can be computed on the fly (This assumes that recomputation is idempotent).
Furthermore, because data are derived, transaction validation looks a bit unusual when compared with a textbook OCC implementation. In particular, the transaction's invalidator represents "real" writes to the canonical source, whereas the transaction's readSet/writeSet entries represent "real" reads from the canonical source.
Multiple tables are grouped together via Validate/Commit 2 phase commit to form the complete derived data database.
func NewEmptyTable ¶
func NewEmptyTable[TKey comparable, TVal any]() *DerivedDataTable[TKey, TVal]
func NewEmptyTableWithOffset ¶
func NewEmptyTableWithOffset[TKey comparable, TVal any](offset uint32) *DerivedDataTable[TKey, TVal]
This variant is needed by the chunk verifier, which does not start at the beginning of the block.
func (*DerivedDataTable[TKey, TVal]) EntriesForTestingOnly ¶
func (table *DerivedDataTable[TKey, TVal]) EntriesForTestingOnly() map[TKey]*invalidatableEntry[TVal]
func (*DerivedDataTable[TKey, TVal]) GetForTestingOnly ¶
func (table *DerivedDataTable[TKey, TVal]) GetForTestingOnly( key TKey, ) *invalidatableEntry[TVal]
func (*DerivedDataTable[TKey, TVal]) InvalidatorsForTestingOnly ¶
func (table *DerivedDataTable[TKey, TVal]) InvalidatorsForTestingOnly() chainedTableInvalidators[TKey, TVal]
func (*DerivedDataTable[TKey, TVal]) LatestCommitExecutionTimeForTestingOnly ¶
func (table *DerivedDataTable[TKey, TVal]) LatestCommitExecutionTimeForTestingOnly() LogicalTime
func (*DerivedDataTable[TKey, TVal]) NewChildTable ¶
func (table *DerivedDataTable[TKey, TVal]) NewChildTable() *DerivedDataTable[TKey, TVal]
func (*DerivedDataTable[TKey, TVal]) NewSnapshotReadTableTransaction ¶
func (table *DerivedDataTable[TKey, TVal]) NewSnapshotReadTableTransaction( snapshotTime LogicalTime, executionTime LogicalTime, ) ( *TableTransaction[TKey, TVal], error, )
func (*DerivedDataTable[TKey, TVal]) NewTableTransaction ¶
func (table *DerivedDataTable[TKey, TVal]) NewTableTransaction( snapshotTime LogicalTime, executionTime LogicalTime, ) ( *TableTransaction[TKey, TVal], error, )
func (*DerivedDataTable[TKey, TVal]) NextTxIndexForTestingOnly ¶
func (table *DerivedDataTable[TKey, TVal]) NextTxIndexForTestingOnly() uint32
type DerivedTransactionData ¶
type DerivedTransactionData struct {
// contains filtered or unexported fields
}
DerivedTransactionData is the derived data scratch space for a single transaction.
func (*DerivedTransactionData) AddInvalidator ¶
func (transaction *DerivedTransactionData) AddInvalidator( invalidator TransactionInvalidator, )
func (*DerivedTransactionData) Commit ¶
func (transaction *DerivedTransactionData) Commit() error
func (*DerivedTransactionData) GetMeterParamOverrides ¶
func (transaction *DerivedTransactionData) GetMeterParamOverrides( txnState *state.TransactionState, getMeterParamOverrides ValueComputer[struct{}, MeterParamOverrides], ) ( MeterParamOverrides, error, )
func (*DerivedTransactionData) GetProgram ¶
func (transaction *DerivedTransactionData) GetProgram( addressLocation common.AddressLocation, ) ( *interpreter.Program, *state.State, bool, )
func (*DerivedTransactionData) SetProgram ¶
func (transaction *DerivedTransactionData) SetProgram( addressLocation common.AddressLocation, program *interpreter.Program, state *state.State, )
func (*DerivedTransactionData) Validate ¶
func (transaction *DerivedTransactionData) Validate() error
type LogicalTime ¶
type LogicalTime int64
We will use txIndex as logical time for the purpose of "caching" derived data.
Execution time refers to the transaction's start time. Snapshot time refers to the time when the snapshot first becomes readable (i.e., the "snapshot time - 1" transaction committed the snapshot view). The snapshot is where the derived value is computed from if no cached value is available. Each transaction's snapshot time must be smaller than or equal to its execution time.
Normal transaction advances the time clock and must be committed to DerivedBlockData in monotonically increasing execution time order.
Snapshot read transaction (aka script) does not advance the time clock. Its execution and snapshot time must be set to the latest snapshot time (or EndOfBlockExecutionTime in case the real logical time is unavailable).
Note that the "real" txIndex range is [0, math.MaxUint32], but we have expanded the range to support events that are not part of the block execution.
type MeterParamOverrides ¶
type MeterParamOverrides struct { ComputationWeights meter.ExecutionEffortWeights // nil indicates no override MemoryWeights meter.ExecutionMemoryWeights // nil indicates no override MemoryLimit *uint64 // nil indicates no override }
type MeterParamOverridesInvalidator ¶
type MeterParamOverridesInvalidator TableInvalidator[ struct{}, MeterParamOverrides, ]
type ProgramInvalidator ¶
type ProgramInvalidator TableInvalidator[ common.AddressLocation, *interpreter.Program, ]
type RetryableError ¶
type TableInvalidator ¶
type TableTransaction ¶
type TableTransaction[TKey comparable, TVal any] struct { // contains filtered or unexported fields }
func (*TableTransaction[TKey, TVal]) AddInvalidator ¶
func (txn *TableTransaction[TKey, TVal]) AddInvalidator( invalidator TableInvalidator[TKey, TVal], )
func (*TableTransaction[TKey, TVal]) Commit ¶
func (txn *TableTransaction[TKey, TVal]) Commit() RetryableError
func (*TableTransaction[TKey, TVal]) Get ¶
func (txn *TableTransaction[TKey, TVal]) Get(key TKey) ( TVal, *state.State, bool, )
Note: use GetOrCompute instead of Get/Set whenever possible.
func (*TableTransaction[TKey, TVal]) GetOrCompute ¶
func (txn *TableTransaction[TKey, TVal]) GetOrCompute( txnState *state.TransactionState, key TKey, computer ValueComputer[TKey, TVal], ) ( TVal, error, )
GetOrCompute returns the key's value. If a pre-computed value is available, then the pre-computed value is returned and the cached state is replayed on txnState. Otherwise, the value is computed using valFunc; both the value and the states used to compute the value are captured.
Note: valFunc must be an idempotent function and it must not modify txnState's values.
func (*TableTransaction[TKey, TVal]) Set ¶
func (txn *TableTransaction[TKey, TVal]) Set( key TKey, value TVal, state *state.State, )
Note: use GetOrCompute instead of Get/Set whenever possible.
func (*TableTransaction[TKey, TVal]) Validate ¶
func (txn *TableTransaction[TKey, TVal]) Validate() RetryableError
type TransactionInvalidator ¶
type TransactionInvalidator interface { ProgramInvalidator() ProgramInvalidator MeterParamOverridesInvalidator() MeterParamOverridesInvalidator }
type ValueComputer ¶
type ValueComputer[TKey any, TVal any] interface { Compute(txnState *state.TransactionState, key TKey) (TVal, error) }
ValueComputer is used by DerivedDataTable's GetOrCompute to compute the derived value when the value is not in DerivedDataTable (i.e., "cache miss").