reads

package
v1.14.1 Latest Latest
Warning

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

Go to latest
Published: Oct 8, 2025 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package reads implements chain read-handles.

These protect read results. The actual reads may still be disturbed, but the handle can be inspected at any time, to abort if needed. And the final result can inspect the read-handle, to determine if the combined reading result is valid.

Append-only writes to the state do not need any invalidation. And updates have parent-hash checks, and thus do not require any rewind-locking on the parent either.

But rewinds, replacements, etc. that do not append do need invalidation, to make sure other reads are not affected.

This approach was chosen over simpler global read-write ChainsDB locking for two main reasons: 1. Fine-grained invalidation: Only operations depending on rewound blocks are affected 2. Non-blocking reads: Rewinds don't block unrelated read operations

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Acquirer

type Acquirer interface {
	// AcquireHandle creates a new read handle.
	// Once the handle is no longer used, it must be released with readHandle.Release, or memory leaks.
	AcquireHandle() Handle
}

Acquirer creates read handles

type DerivedInvalidation

type DerivedInvalidation struct {
	Timestamp uint64
}

func (DerivedInvalidation) Apply

func (s DerivedInvalidation) Apply(h invalidationTarget)

type Handle

type Handle interface {
	// DependOnDerivedTime registers the given derived block timestamp as a dependency,
	// updating the current range if needed.
	DependOnDerivedTime(timestamp uint64)
	// DependOnSourceBlock registers the given derived block number as a dependency,
	// updating the current range if needed.
	DependOnSourceBlock(blockNum uint64)

	// Err is a convenience method to return a types.ErrInvalidatedRead whenever the read handle is not valid
	Err() error

	// IsValid inspects the dependencies we have seen so far, and the invalidations we have seen,
	// and determines if the reads thus far are still valid.
	// Once a Handle is invalid, it never becomes valid again.
	IsValid() bool

	// Release releases the read-handle: once released we no longer apply updates to the read handle.
	// rangeHandles must be released, otherwise they are tracked forever.
	Release()
	// contains filtered or unexported methods
}

Handle represents a read handle, to detect chain rewinds during multi-operation reads.

type InvalidHandle

type InvalidHandle struct{}

InvalidHandle is a test-util, to present a read-handle that is always invalid, to mock an inconsistency.

func (InvalidHandle) DependOnDerivedTime

func (i InvalidHandle) DependOnDerivedTime(timestamp uint64)

func (InvalidHandle) DependOnSourceBlock

func (i InvalidHandle) DependOnSourceBlock(blockNum uint64)

func (InvalidHandle) Err

func (i InvalidHandle) Err() error

func (InvalidHandle) IsValid

func (i InvalidHandle) IsValid() bool

func (InvalidHandle) Release

func (i InvalidHandle) Release()

type InvalidationRule

type InvalidationRule interface {
	Apply(h invalidationTarget)
}

type InvalidationRules

type InvalidationRules []InvalidationRule

func (InvalidationRules) Apply

func (rules InvalidationRules) Apply(h invalidationTarget)

type Invalidator

type Invalidator interface {
	TryInvalidate(rule InvalidationRule) (release func(), err error)
}

Invalidator invalidates read handles

type NoopHandle

type NoopHandle struct{}

NoopHandle implements Handle without offering actual protection. This can be used when access is known to be synchronous and safe.

func (NoopHandle) DependOnDerivedTime

func (n NoopHandle) DependOnDerivedTime(timestamp uint64)

func (NoopHandle) DependOnSourceBlock

func (n NoopHandle) DependOnSourceBlock(blockNum uint64)

func (NoopHandle) Err

func (n NoopHandle) Err() error

func (NoopHandle) IsValid

func (n NoopHandle) IsValid() bool

func (NoopHandle) Release

func (n NoopHandle) Release()

type NoopRegistry

type NoopRegistry struct{}

NoopRegistry implements Acquirer and Invalidator without offering actual protection. This can be used when access is known to be synchronous and safe.

func (NoopRegistry) AcquireHandle

func (n NoopRegistry) AcquireHandle() Handle

func (NoopRegistry) TryInvalidate

func (n NoopRegistry) TryInvalidate(rule InvalidationRule) (release func(), err error)

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry maintains a set of read handles (readHandle). Whenever the chain reorgs, the active handles are updated, to track what has been reorged. Any handles that have an overlapping usage and invalidation range are invalid and return an error.

func NewRegistry

func NewRegistry(logger log.Logger) *Registry

func (*Registry) AcquireHandle

func (r *Registry) AcquireHandle() Handle

AcquireHandle creates a new read handle. Once the handle is no longer used, it must be released with readHandle.Release, or memory leaks.

func (*Registry) TryInvalidate

func (r *Registry) TryInvalidate(rule InvalidationRule) (release func(), err error)

TryInvalidate invalidates all handles that depend on blocks with numbers >= blockNum. Any new read-handles will automatically be invalidated if they depend on blockNum or later. The invalidation of new reads (starting at the given number) will stop once it has been released by calling release.

type SourceInvalidation

type SourceInvalidation struct {
	Number uint64
}

func (SourceInvalidation) Apply

func (s SourceInvalidation) Apply(h invalidationTarget)

type TestInvalidator

type TestInvalidator struct {
	Invalidated                 bool
	InvalidatedDerivedTimestamp uint64
	InvalidatedSourceNum        uint64
}

func (*TestInvalidator) TryInvalidate

func (t *TestInvalidator) TryInvalidate(rule InvalidationRule) (release func(), err error)

Jump to

Keyboard shortcuts

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