preconfirmed

package
v0.16.5-rc.0 Latest Latest
Warning

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

Go to latest
Published: Jul 8, 2026 License: Apache-2.0 Imports: 17 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrBaseTxCountMismatch = errors.New("pre-confirmed base transaction count mismatch")

ErrBaseTxCountMismatch is returned when a Delta update's baseTxCount hint doesn't match the targeted slot's current tx count. Defensive against any non-poller writer (or future race) that could drift the slot between the wire send and the storage apply.

Functions

This section is empty.

Types

type ChainReader

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

ChainReader is an immutable snapshot of a contiguous run of pre-confirmed blocks, ordered newest-first via parent pointers. Iteration must respect Length — head-aligned views (see ChainStorage.SnapshotForHead) may stop before the underlying linked list's nil terminator.

func NewChain

func NewChain(entries ...*pending.PreConfirmed) (ChainReader, error)

NewChain builds a ChainReader from non-nil pre-confirmed entries given in oldest-first order with contiguous block numbers. No args returns the zero-value ChainReader.

func (*ChainReader) Head

func (c *ChainReader) Head() *pending.PreConfirmed

Head returns the most recent pre-confirmed in the view, or nil if empty.

func (*ChainReader) Length

func (c *ChainReader) Length() int

Length is the number of entries in this chain view.

func (*ChainReader) NewestFirst

func (c *ChainReader) NewestFirst() iter.Seq[*pending.PreConfirmed]

NewestFirst yields entries from the most recent down to head+1, bounded by Length.

func (*ChainReader) OldestFirst

func (c *ChainReader) OldestFirst() iter.Seq[*pending.PreConfirmed]

OldestFirst yields entries from head+1 up to the most recent, bounded by Length.

func (*ChainReader) PreConfirmedStateAt

func (c *ChainReader) PreConfirmedStateAt(
	blockNumber uint64,
	bcReader blockchain.Reader,
) (core.StateReader, blockchain.StateCloser, error)

PreConfirmedStateAt returns the chain's view of state at blockNumber. The chain owns base resolution: it opens the canonical state immediately below its own bottom (derived from tip - length + 1).

Returns [pending.ErrPreConfirmedNotFound] if blockNumber falls outside the chain.

func (*ChainReader) PreConfirmedStateBeforeIndexAt

func (c *ChainReader) PreConfirmedStateBeforeIndexAt(
	blockNumber uint64,
	index uint,
	bcReader blockchain.Reader,
) (core.StateReader, blockchain.StateCloser, error)

PreConfirmedStateBeforeIndexAt returns the chain's view of state immediately before transaction `index` at blockNumber. See PreConfirmedStateAt for the base- resolution contract; here the chain additionally layers the target slot's per-transaction diffs up to (but not including) `index`. Returns pending.ErrPreConfirmedNotFound if blockNumber isn't in the chain, or pending.ErrTransactionIndexOutOfBounds if `index` exceeds the target's transaction count.

func (*ChainReader) ReceiptByHash

func (c *ChainReader) ReceiptByHash(

	hash *felt.Felt,
) (*core.TransactionReceipt, uint64, error)

ReceiptByHash scans every chain entry's Block.Receipts. Returns the receipt and the number of the block it lives in. ErrTransactionReceiptNotFound when missing.

func (*ChainReader) TransactionByHash

func (c *ChainReader) TransactionByHash(hash *felt.Felt) (core.Transaction, error)

TransactionByHash scans every chain entry's Block.Transactions.

Returns pending.ErrTransactionNotFound when missing.

type ChainStorage

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

ChainStorage holds a contiguous run of pre-confirmed blocks above the canonical head. Readers obtain a head-aligned view via SnapshotForHead. Single writer (polling loop) with many concurrent readers; reads are lock-free via atomic.Pointer.

func NewChainStorage

func NewChainStorage() *ChainStorage

func (*ChainStorage) AdvanceTo

func (s *ChainStorage) AdvanceTo(head *core.Header) bool

AdvanceTo realigns the chain to a new canonical head. Three outcomes:

  • wantBottom == bottom: chain already aligned, no-op.
  • wantBottom > mostRecent (head advanced past everything we stored) OR wantBottom < bottom (head reverted below us — every entry's parent now references a discarded block): drop the whole chain. The next poll bootstraps fresh against the new head.
  • bottom < wantBottom <= mostRecent: rebuild from the new bottom up so the surviving nodes nil-terminate cleanly and the dropped tail is GC-able.

Pre-pop readers retain their *ChainReader and walk the original (still intact) nodes; the new chain references only fresh nodes.

Single-writer: like ApplyUpdate, this assumes the pre-confirmed poller goroutine is the only writer.

func (*ChainStorage) ApplyUpdate

func (s *ChainStorage) ApplyUpdate(
	update starknet.PreConfirmedUpdate,
	blockNumber uint64,
	baseTxCount uint64,
	head *core.Header,
) (*pending.PreConfirmed, error)

ApplyUpdate atomically evolves the stored chain from a wire-side update. blockNumber is the height targeted by the update; baseTxCount is the knownTransactionCount the poller sent (consulted only for the Delta case as a defensive race-check against the targeted slot). head MUST be the canonical chain head, or nil at genesis. Returns the affected entry, or nil when the update was a no-op (NoChange, preserved, rejected at cap, etc.).

On CAS failure the chain changed between Load and CompareAndSwap; we return an error instead of retrying.

func (*ChainStorage) SnapshotForHead

func (s *ChainStorage) SnapshotForHead(head *core.Header) ChainReader

SnapshotForHead returns a head-aligned view of the pre-confirmed chain: its conceptual bottom is head.Number+1 (or 0 at genesis with head == nil), so entries at or below the canonical head are excluded via the reported length. If the stored chain briefly extends below head+1 (AdvanceTo hasn't run yet against this head advance), the view reports a shorter length, excluding the now-committed entries.

The view is uncapped: it exposes every stored entry from head+1 up to the stored tip, even when the chain runs more than core.BlockHashLag ahead of the canonical head. Reading pre-confirmed state at such a far-ahead block can fail at execution time, when a get_block_hash lookup falls outside the available window; that failure is intentionally left to the execution layer rather than masked by truncating the view here.

Returns the zero-value ChainReader (length 0) if the chain does not cover head+1 (head advanced past the stored tip, or the chain's bottom sits above head+1); callers should branch on Length().

type DataSource

type DataSource interface {
	PreConfirmedBlockLatest(
		ctx context.Context,
		identifier string,
		txCount uint64,
	) (starknet.PreConfirmedUpdate, uint64, error)
	PreConfirmedBlockByNumber(
		ctx context.Context,
		blockNumber uint64,
		identifier string,
		txCount uint64,
	) (starknet.PreConfirmedUpdate, error)
}

DataSource is the narrow surface the Poller needs from the wire side. Any type implementing both methods (e.g. sync.DataSource) satisfies it.

type Poller

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

Poller drives the pre-confirmed chain from a single goroutine.

One tick reads as: poll the server's latest pre-confirmed, backfill any gap below it, then insert the latest. backfill is a no-op when there's no gap; otherwise it finalises the current mostRecent (re-polls its number to capture the last delta before the sequencer moved past it) and then walks explicit-number polls up to latest-1. Same-height polls (latest matches our mostRecent) skip backfill and land in insert as delta / preserve / replace.

func NewPoller

func NewPoller(
	dataSource DataSource,
	storage *ChainStorage,
	bc *blockchain.Blockchain,
	out *feed.Feed[*pending.PreConfirmed],
	highestBlockHeader *atomic.Pointer[core.Header],
	interval time.Duration,
	logger log.StructuredLogger,
) *Poller

func (*Poller) Run

func (p *Poller) Run(ctx context.Context)

Jump to

Keyboard shortcuts

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