derived

package
v0.29.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 25, 2023 License: AGPL-3.0 Imports: 9 Imported by: 0

Documentation

Index

Constants

View Source
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
)
View Source
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 RetryableError

type RetryableError interface {
	error
	IsRetryable() bool
}

type TableInvalidator

type TableInvalidator[TKey comparable, TVal any] interface {
	// This returns true if the this invalidates any data
	ShouldInvalidateEntries() bool

	// This returns true if the table entry should be invalidated.
	ShouldInvalidateEntry(TKey, TVal, *state.State) bool
}

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").

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL