Documentation
¶
Index ¶
- Constants
- Variables
- func IsIgnorableBroadcastError(err error) bool
- func IsIgnorableMempoolRejectReason(reason string) bool
- func MapBlockEpoch[Out actor.Message](targetRef actor.TellOnlyRef[Out], mapFn func(BlockEpoch) Out) actor.TellOnlyRef[BlockEpoch]
- func MapConfDoneEvent[Out actor.Message](targetRef actor.TellOnlyRef[Out], mapFn func(ConfDoneEvent) Out) actor.TellOnlyRef[ConfDoneEvent]
- func MapConfReorgedEvent[Out actor.Message](targetRef actor.TellOnlyRef[Out], mapFn func(ConfReorgedEvent) Out) actor.TellOnlyRef[ConfReorgedEvent]
- func MapConfirmationEvent[Out actor.Message](targetRef actor.TellOnlyRef[Out], mapFn func(ConfirmationEvent) Out) actor.TellOnlyRef[ConfirmationEvent]
- func MapSpendDoneEvent[Out actor.Message](targetRef actor.TellOnlyRef[Out], mapFn func(SpendDoneEvent) Out) actor.TellOnlyRef[SpendDoneEvent]
- func MapSpendEvent[Out actor.Message](targetRef actor.TellOnlyRef[Out], mapFn func(SpendEvent) Out) actor.TellOnlyRef[SpendEvent]
- func MapSpendReorgedEvent[Out actor.Message](targetRef actor.TellOnlyRef[Out], mapFn func(SpendReorgedEvent) Out) actor.TellOnlyRef[SpendReorgedEvent]
- type BestHeightRequest
- type BestHeightResponse
- type BlockEpoch
- type BlockEpochActor
- type BlockEpochConfig
- type BlockRegistration
- type BroadcastTxRequest
- type BroadcastTxResponse
- type ChainBackend
- type ChainSourceActor
- type ChainSourceConfig
- type ChainSourceMsg
- type ChainSourceResp
- type ConfActor
- type ConfActorConfig
- type ConfDoneEvent
- type ConfMsg
- type ConfRegistration
- type ConfReorgedEvent
- type ConfResp
- type ConfirmationEvent
- type EpochMsg
- type EpochResp
- type FeeEstimateRequest
- type FeeEstimateResponse
- type MempoolAcceptResult
- type PositiveDoneOrder
- type RegisterConfRequest
- type RegisterConfResponse
- type RegisterSpendRequest
- type RegisterSpendResponse
- type SpendActor
- type SpendActorConfig
- type SpendDetail
- type SpendDoneEvent
- type SpendEvent
- type SpendMsg
- type SpendRegistration
- type SpendReorgedEvent
- type SpendResp
- type SubmitPackageRequest
- type SubmitPackageResponse
- type SubscribeBlocksRequest
- type SubscribeBlocksResponse
- type TestMempoolAcceptRequest
- type TestMempoolAcceptResponse
- type TxConfirmation
- type UnregisterConfRequest
- type UnregisterConfResponse
- type UnregisterSpendRequest
- type UnregisterSpendResponse
- type UnsubscribeBlocksRequest
- type UnsubscribeBlocksResponse
Constants ¶
const ( // Subsystem defines the logging subsystem code for the chainsource // package. Subsystem = "CSRC" // ConfSubsystem defines the logging subsystem code for confirmation // monitoring actors. ConfSubsystem = "CONF" // SpendSubsystem defines the logging subsystem code for spend // monitoring actors. SpendSubsystem = "SPND" // EpochSubsystem defines the logging subsystem code for block epoch // monitoring actors. EpochSubsystem = "EPCH" )
const ( // DefaultFinalityDepth is the conventional Bitcoin reorg-safety // depth. After this many inclusive confirmations the ConfActor // and SpendActor synthesize their Done events when the backend // transport (notably lndclient over gRPC) does not surface one // of its own. Six is the value the wider Lightning stack treats // as final for the purposes of channel funding / settlement, so // using it here keeps the unroll subsystem's finality threshold // aligned with the rest of the daemon's chain assumptions. DefaultFinalityDepth uint32 = 6 )
Variables ¶
var ChainSourceKey = actor.NewServiceKey[ChainSourceMsg, ChainSourceResp](
"chainsource",
)
ChainSourceKey is the service key for the main ChainSource actor.
var ErrPackageMempoolAcceptUnsupported = errors.New("package " +
"testmempoolaccept not supported by backend")
ErrPackageMempoolAcceptUnsupported is returned by ChainBackend implementations whose underlying RPC cannot test a multi-transaction package for mempool acceptance. It is distinct from a per-tx "rejected" outcome: the backend never evaluated the package at all. Callers that treat package preflight as best-effort should downgrade this error to a soft-miss; callers that require package validation should surface it as a hard failure.
Functions ¶
func IsIgnorableBroadcastError ¶
IsIgnorableBroadcastError returns true if the error is expected to happen when broadcasting the same transaction multiple times.
func IsIgnorableMempoolRejectReason ¶
IsIgnorableMempoolRejectReason returns true if the mempool rejection reason indicates the transaction is already known (in mempool or chain).
func MapBlockEpoch ¶
func MapBlockEpoch[Out actor.Message]( targetRef actor.TellOnlyRef[Out], mapFn func(BlockEpoch) Out, ) actor.TellOnlyRef[BlockEpoch]
MapBlockEpoch creates a transformed TellOnlyRef that accepts BlockEpoch and transforms it to the caller's desired output message type. This is a convenience wrapper for the common pattern of adapting chainsource block notifications to caller-specific event types.
Example usage:
// roundActorRef accepts round.BlockEvent
adaptedRef := chainsource.MapBlockEpoch(
roundActorRef,
func(cs chainsource.BlockEpoch) round.BlockEvent {
return round.BlockEvent{
Height: cs.Height,
Hash: cs.Hash,
Timestamp: cs.Timestamp,
}
},
)
// Subscribe to blocks using the adapted ref.
chainSourceRef.Ask(ctx, &chainsource.SubscribeBlocksRequest{
NotifyActor: fn.Some(adaptedRef),
// ... other fields
})
func MapConfDoneEvent ¶
func MapConfDoneEvent[Out actor.Message]( targetRef actor.TellOnlyRef[Out], mapFn func(ConfDoneEvent) Out, ) actor.TellOnlyRef[ConfDoneEvent]
MapConfDoneEvent creates a transformed TellOnlyRef that accepts ConfDoneEvent and transforms it to the caller's desired output message type.
func MapConfReorgedEvent ¶
func MapConfReorgedEvent[Out actor.Message]( targetRef actor.TellOnlyRef[Out], mapFn func(ConfReorgedEvent) Out, ) actor.TellOnlyRef[ConfReorgedEvent]
MapConfReorgedEvent creates a transformed TellOnlyRef that accepts ConfReorgedEvent and transforms it to the caller's desired output message type.
func MapConfirmationEvent ¶
func MapConfirmationEvent[Out actor.Message]( targetRef actor.TellOnlyRef[Out], mapFn func(ConfirmationEvent) Out, ) actor.TellOnlyRef[ConfirmationEvent]
MapConfirmationEvent creates a transformed TellOnlyRef that accepts ConfirmationEvent and transforms it to the caller's desired output message type. This is a convenience wrapper for the common pattern of adapting chainsource confirmation notifications to caller-specific event types.
Example usage:
// roundActorRef accepts round.ConfirmationEvent
adaptedRef := chainsource.MapConfirmationEvent(
roundActorRef,
func(cs chainsource.ConfirmationEvent) round.ConfirmationEvent {
return round.ConfirmationEvent{
TxID: cs.Txid,
BlockHeight: cs.BlockHeight,
Confirmations: int32(cs.NumConfs),
}
},
)
// Register with chainsource using the adapted ref.
chainSourceRef.Ask(ctx, &chainsource.RegisterConfRequest{
NotifyActor: fn.Some(adaptedRef),
// ... other fields
})
func MapSpendDoneEvent ¶
func MapSpendDoneEvent[Out actor.Message]( targetRef actor.TellOnlyRef[Out], mapFn func(SpendDoneEvent) Out, ) actor.TellOnlyRef[SpendDoneEvent]
MapSpendDoneEvent creates a transformed TellOnlyRef that accepts SpendDoneEvent and transforms it to the caller's desired output message type.
func MapSpendEvent ¶
func MapSpendEvent[Out actor.Message]( targetRef actor.TellOnlyRef[Out], mapFn func(SpendEvent) Out, ) actor.TellOnlyRef[SpendEvent]
MapSpendEvent creates a transformed TellOnlyRef that accepts SpendEvent and transforms it to the caller's desired output message type. This is a convenience wrapper for the common pattern of adapting chainsource spend notifications to caller-specific event types.
Example usage:
// roundActorRef accepts round.SpendEvent
adaptedRef := chainsource.MapSpendEvent(
roundActorRef,
func(cs chainsource.SpendEvent) round.SpendEvent {
return round.SpendEvent{
Outpoint: cs.Outpoint,
SpendingTxid: cs.SpendingTxid,
SpendingTx: cs.SpendingTx,
}
},
)
// Register with chainsource using the adapted ref.
chainSourceRef.Ask(ctx, &chainsource.RegisterSpendRequest{
NotifyActor: fn.Some(adaptedRef),
// ... other fields
})
func MapSpendReorgedEvent ¶
func MapSpendReorgedEvent[Out actor.Message]( targetRef actor.TellOnlyRef[Out], mapFn func(SpendReorgedEvent) Out, ) actor.TellOnlyRef[SpendReorgedEvent]
MapSpendReorgedEvent creates a transformed TellOnlyRef that accepts SpendReorgedEvent and transforms it to the caller's desired output message type.
Types ¶
type BestHeightRequest ¶
type BestHeightRequest struct {
actor.BaseMessage
}
BestHeightRequest requests the current best known block height and hash from the blockchain backend.
func (*BestHeightRequest) MessageType ¶
func (m *BestHeightRequest) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type BestHeightResponse ¶
type BestHeightResponse struct {
actor.BaseMessage
// Height is the current best block height.
Height int32
// Hash is the current best block hash.
Hash chainhash.Hash
}
BestHeightResponse contains the current best block height and hash from the blockchain.
func (*BestHeightResponse) MessageType ¶
func (m *BestHeightResponse) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type BlockEpoch ¶
type BlockEpoch struct {
actor.BaseMessage
// Height is the block height.
Height int32
// Hash is the block hash.
Hash chainhash.Hash
// Timestamp is the block timestamp from the header.
Timestamp int64
}
BlockEpoch represents a new block connected to the blockchain. This event is sent for each new block and can include backfilled blocks if the client fell behind.
func (BlockEpoch) MessageType ¶
func (m BlockEpoch) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type BlockEpochActor ¶
type BlockEpochActor struct {
// contains filtered or unexported fields
}
BlockEpochActor is a single-subscription actor that monitors new blocks and delivers block epoch events. Each instance serves exactly one subscription.
The actor supports dual-mode operation: Iterator mode for range-based iteration, and Actor mode for asynchronous event delivery to a registered actor. Each actor creates its own backend registration (no sharing).
func NewBlockEpochActor ¶
func NewBlockEpochActor(cfg BlockEpochConfig) *BlockEpochActor
NewBlockEpochActor creates a new BlockEpochActor instance with the given configuration. The config must include Backend; use WithLogger() to inject a specific logger.
func (*BlockEpochActor) OnStop ¶
func (a *BlockEpochActor) OnStop(ctx context.Context) error
OnStop implements actor.Stoppable for proper cleanup when stopped via actor system. This is called after the actor's message loop exits.
func (*BlockEpochActor) Stop ¶
func (a *BlockEpochActor) Stop()
Stop gracefully shuts down the BlockEpochActor. It cancels the context and waits for the monitoring goroutine to complete.
type BlockEpochConfig ¶
type BlockEpochConfig struct {
// Backend is the blockchain backend used to monitor blocks.
Backend ChainBackend
// Log is an optional logger for this actor instance. If None, the actor
// falls back to extracting a logger from context via LoggerFromContext,
// or uses btclog.Disabled if no logger is found.
Log fn.Option[btclog.Logger]
// ReconnectBackoff is the initial delay before reconnecting a block
// epoch subscription whose backend stream closed after the initial
// registration succeeded. Zero uses defaultBlockEpochReconnectBackoff.
ReconnectBackoff time.Duration
// MaxReconnectBackoff caps the exponential reconnect delay. Zero uses
// defaultBlockEpochMaxReconnectBackoff.
MaxReconnectBackoff time.Duration
}
BlockEpochConfig holds configuration for BlockEpochActor.
func (BlockEpochConfig) WithLogger ¶
func (c BlockEpochConfig) WithLogger(log btclog.Logger) BlockEpochConfig
WithLogger returns a new config with the given logger set.
type BlockRegistration ¶
type BlockRegistration struct {
// Epochs is a channel that sends an event for each new block connected
// to the chain. The channel is buffered to handle bursts of blocks.
Epochs <-chan *BlockEpoch
// Cancel is a function that can be called to cancel this registration
// and clean up resources.
Cancel func()
}
BlockRegistration encapsulates the channels and control functions for a block subscription.
type BroadcastTxRequest ¶
type BroadcastTxRequest struct {
actor.BaseMessage
// Tx is the transaction to broadcast.
Tx *wire.MsgTx
// Label is an optional label for tracking this transaction in the
// wallet. Can be empty.
Label string
}
BroadcastTxRequest requests that a transaction be broadcast to the network. An optional label can be provided for wallet tracking purposes.
func (*BroadcastTxRequest) MessageType ¶
func (m *BroadcastTxRequest) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type BroadcastTxResponse ¶
type BroadcastTxResponse struct {
actor.BaseMessage
// Txid is the transaction ID of the broadcast transaction.
Txid chainhash.Hash
}
BroadcastTxResponse contains the transaction ID of the successfully broadcast transaction.
func (*BroadcastTxResponse) MessageType ¶
func (m *BroadcastTxResponse) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type ChainBackend ¶
type ChainBackend interface {
// EstimateFee returns the estimated fee rate in satoshis per vbyte for
// a transaction to confirm within the target number of blocks. Returns
// an error if fee estimation fails or is unavailable.
EstimateFee(ctx context.Context,
targetConf uint32) (btcutil.Amount, error)
// BestBlock returns the current best known block height and hash from
// the blockchain. This represents the tip of the longest valid chain
// according to the backend's view.
BestBlock(ctx context.Context) (int32, chainhash.Hash, error)
// TestMempoolAccept tests whether one or more transactions would be
// accepted by the mempool without actually broadcasting them. When
// len(txs) > 1 the backend must evaluate the transactions as a
// package (matching Bitcoin Core's testmempoolaccept JSON array
// form); backends that can only validate individual transactions
// must return ErrPackageMempoolAcceptUnsupported rather than
// silently evaluating the first tx in isolation.
//
// The returned slice has one entry per input tx, in the same
// order. Not all backends may support this operation at all; those
// should return a non-nil error from the single-tx call so callers
// can distinguish "rejected" from "not evaluated".
TestMempoolAccept(ctx context.Context,
txs ...*wire.MsgTx) ([]MempoolAcceptResult, error)
// BroadcastTx broadcasts a transaction to the network. The label
// parameter is optional and may be used for wallet tracking. Returns
// an error if the broadcast fails.
BroadcastTx(ctx context.Context, tx *wire.MsgTx, label string) error
// RegisterConf registers for confirmation notifications of a
// transaction. The registration returns a ConfRegistration that
// provides channels for receiving confirmation events.
//
// Parameters:
// - ctx: Context for cancellation
// - txid: The transaction ID to monitor (can be nil to match by
// script)
// - pkScript: The public key script to watch for
// - numConfs: Target number of confirmations
// - heightHint: Earliest block containing the tx (0 if unknown)
// - includeBlock: If true, include the full block in the confirmation
// event for merkle proof construction
//
// The returned ConfRegistration must have buffered channels and a
// Cancel function for cleanup.
RegisterConf(ctx context.Context, txid *chainhash.Hash, pkScript []byte,
numConfs uint32, heightHint uint32,
includeBlock bool) (*ConfRegistration, error)
// RegisterSpend registers for spend notifications of a transaction
// output. The registration returns a SpendRegistration that provides
// channels for receiving spend events.
//
// Parameters:
// - ctx: Context for cancellation
// - outpoint: The output to monitor (can be nil to match by script)
// - pkScript: The public key script to watch for
// - heightHint: Earliest block containing a spend (0 if unknown)
//
// The returned SpendRegistration must have buffered channels and a
// Cancel function for cleanup.
RegisterSpend(ctx context.Context, outpoint *wire.OutPoint,
pkScript []byte, heightHint uint32) (*SpendRegistration, error)
// RegisterBlocks registers for new block notifications. The
// registration returns a BlockRegistration that provides a channel for
// receiving block events.
//
// The returned BlockRegistration must have a buffered channel and a
// Cancel function for cleanup. The backend may optionally backfill
// missed blocks if the client provides a best known block.
RegisterBlocks(ctx context.Context) (*BlockRegistration, error)
// SubmitPackage atomically submits a parent+child transaction
// package to the network. This is required for V3 package relay
// where the child pays fees for otherwise non-relayable parents.
SubmitPackage(ctx context.Context, parents []*wire.MsgTx,
child *wire.MsgTx) error
// Start initializes the backend and any background processes. This
// must be called before using any other methods.
Start() error
// Stop shuts down the backend and cleans up all resources. All pending
// registrations will be cancelled.
Stop() error
}
ChainBackend defines the interface that must be implemented by all blockchain backend providers. This abstraction allows the ChainSource actor to work with different backends (lnd's chainntnfs, block explorers like mempool.space, or custom implementations) without coupling to any specific implementation.
All methods must be safe for concurrent use. Implementations should handle their own internal synchronization and connection management.
type ChainSourceActor ¶
type ChainSourceActor struct {
// contains filtered or unexported fields
}
ChainSourceActor is a stateless factory actor that provides blockchain interface functionality. It handles direct queries (fee estimation, best height, mempool testing, transaction broadcasting) and spawns dedicated sub-actors for event monitoring (confirmations, spends, blocks).
Each monitoring request spawns a new dedicated actor with a unique service key, enabling deterministic cancellation and eliminating shared state.
func NewChainSourceActor ¶
func NewChainSourceActor(cfg ChainSourceConfig) *ChainSourceActor
NewChainSourceActor creates a new ChainSourceActor instance with the given configuration. The config must include Backend and System; use WithLogger() to inject a specific logger.
func (*ChainSourceActor) Receive ¶
func (a *ChainSourceActor) Receive(actorCtx context.Context, msg ChainSourceMsg) fn.Result[ChainSourceResp]
Receive processes incoming messages for the ChainSourceActor. This handles direct backend queries and spawns dedicated sub-actors for event monitoring.
type ChainSourceConfig ¶
type ChainSourceConfig struct {
// Backend is the blockchain backend used for all chain operations.
Backend ChainBackend
// System is the actor system for spawning sub-actors.
System *actor.ActorSystem
// Log is an optional logger for this actor instance. If None, the actor
// falls back to extracting a logger from context via LoggerFromContext,
// or uses btclog.Disabled if no logger is found.
Log fn.Option[btclog.Logger]
// FinalityDepth is forwarded to each spawned sub-actor as the
// number of confirmations past the first observed positive event
// that the actor uses to synthesize a Done signal when the backend
// transport (notably lndclient over gRPC) cannot deliver one. Zero
// disables height-based finality synthesis. See
// ConfActorConfig.FinalityDepth / SpendActorConfig.FinalityDepth.
FinalityDepth uint32
}
ChainSourceConfig holds configuration for ChainSourceActor.
func (ChainSourceConfig) WithLogger ¶
func (c ChainSourceConfig) WithLogger(log btclog.Logger) ChainSourceConfig
WithLogger returns a new config with the given logger set.
type ChainSourceMsg ¶
ChainSourceMsg is the sealed interface for all messages that can be sent to the ChainSource actor. The sealed interface pattern ensures type safety by preventing external packages from implementing the interface.
type ChainSourceResp ¶
ChainSourceResp is the sealed interface for all response messages from the ChainSource actor.
type ConfActor ¶
type ConfActor struct {
// contains filtered or unexported fields
}
ConfActor is a single-subscription actor that monitors transaction confirmations and delivers an event when the transaction reaches its target confirmation count. Each instance serves exactly one subscription.
The actor supports dual-mode operation: Future mode for blocking await, and Actor mode for asynchronous event delivery. The actor exits after delivering the confirmation event.
func NewConfActor ¶
func NewConfActor(cfg ConfActorConfig) *ConfActor
NewConfActor creates a new ConfActor instance with the given configuration. The config must include Backend; use WithLogger() to inject a specific logger.
func (*ConfActor) OnStop ¶
OnStop implements actor.Stoppable for proper cleanup when stopped via actor system. This is called after the actor's message loop exits.
type ConfActorConfig ¶
type ConfActorConfig struct {
// Backend is the blockchain backend used to monitor confirmations.
Backend ChainBackend
// Log is an optional logger for this actor instance. If None, the actor
// falls back to extracting a logger from context via LoggerFromContext,
// or uses btclog.Disabled if no logger is found.
Log fn.Option[btclog.Logger]
// FinalityDepth is the number of confirmations past the first
// observed Confirmed event that the actor uses to synthesize a Done
// signal when the backend cannot deliver one. Zero disables
// height-based finality synthesis entirely; in that case the actor
// only fires ConfDoneEvent when the backend's own Done channel
// fires (e.g. an in-process lnd notifier). Non-zero values close
// the lndclient transport gap, where the gRPC layer does not
// surface lnd's internal "past reorg-safety depth" signal.
//
// The depth is counted inclusively (a tx confirmed at height H is
// at depth 1; height-based finality fires once the actor observes
// a block at H + FinalityDepth - 1). The conventional choice is 6.
FinalityDepth uint32
}
ConfActorConfig holds configuration for ConfActor.
func (ConfActorConfig) WithLogger ¶
func (c ConfActorConfig) WithLogger(log btclog.Logger) ConfActorConfig
WithLogger returns a new config with the given logger set.
type ConfDoneEvent ¶
type ConfDoneEvent struct {
actor.BaseMessage
// Txid is the transaction ID whose registration matured.
Txid chainhash.Hash
}
ConfDoneEvent is sent when a confirmation watch has matured past the backend's reorg-safety depth and will receive no further events. Consumers may use this signal to drop any reorg-recovery bookkeeping they were holding for the registration. Not all backends synthesize this event; consumers must treat its absence as a normal operating condition rather than an error.
func (ConfDoneEvent) MessageType ¶
func (m ConfDoneEvent) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type ConfMsg ¶
ConfMsg is the sealed interface for all messages that can be sent to a ConfActor sub-actor for confirmation monitoring.
type ConfRegistration ¶
type ConfRegistration struct {
// Confirmed fires every time the transaction reaches the target
// number of confirmations on the canonical chain. After a Reorged
// event it may fire again when the transaction re-confirms. The
// channel is buffered.
Confirmed <-chan *TxConfirmation
// Reorged fires when a previously delivered confirmation is reorged
// out of the canonical chain. The payload is the backend forwarder's
// monotonic sequence number (see TxConfirmation.Seq) rather than
// reorg depth or block identity, which the lndclient gRPC transport
// cannot preserve; the sequence lets the consumer order this signal
// against confirmations sharing the same sequence space even though
// they arrive on a different channel. Backends that cannot observe
// reorgs leave this channel nil-equivalent (allocated but never
// written to); reading from it is always safe.
Reorged <-chan uint64
// Done fires once when the confirmation watch is past the backend's
// reorg-safety depth and will receive no further events. Callers
// must still invoke Cancel to release client-side resources.
// Backends that cannot synthesize a safety-depth signal leave this
// channel nil-equivalent (allocated but never written to).
Done <-chan struct{}
// Cancel is a function that can be called to cancel this registration
// and clean up resources. After calling Cancel, no more events will be
// sent on any channels.
Cancel func()
}
ConfRegistration encapsulates the channels and control functions for a confirmation registration. This mirrors lnd's chainntnfs.ConfirmationEvent structure but provides a backend-agnostic interface.
The registration is reorg-aware: after a confirmation has been delivered on Confirmed, a subsequent reorg that buries the original block can cause a fresh send on Reorged. Once the transaction re-confirms on the new canonical chain another event arrives on Confirmed. The lifecycle is therefore Confirmed -> Reorged -> Confirmed -> ... terminated by either a send on Done (the confirmation is past the backend's reorg-safety depth) or a caller-driven Cancel. Backends that cannot observe reorgs leave Reorged and Done as never-firing channels; callers must not assume either will ever fire.
type ConfReorgedEvent ¶
type ConfReorgedEvent struct {
actor.BaseMessage
// Txid is the transaction ID whose confirmation was reorged. This
// matches the Txid carried on the originating ConfirmationEvent.
Txid chainhash.Hash
}
ConfReorgedEvent is sent when a previously reported confirmation is reorged out of the canonical chain. After receiving this event a consumer should consider the prior confirmation no longer valid; if the transaction re-confirms on the new canonical chain a fresh ConfirmationEvent will follow on the same registration.
No block hash, height, or reorg depth is carried because the lndclient gRPC transport does not preserve that information and we do not want to expose fields that are always zero in production. Consumers that need to invalidate cached block metadata should match on Txid and use the data from the most recent ConfirmationEvent they observed on this watch.
func (ConfReorgedEvent) MessageType ¶
func (m ConfReorgedEvent) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type ConfirmationEvent ¶
type ConfirmationEvent struct {
actor.BaseMessage
// Txid is the transaction ID.
Txid chainhash.Hash
// BlockHeight is the height of the block containing the transaction.
BlockHeight int32
// BlockHash is the hash of the block containing the transaction.
BlockHash chainhash.Hash
// NumConfs is the actual number of confirmations at the time of this
// event.
NumConfs uint32
// Tx is the confirmed transaction. This allows consumers to inspect
// transaction outputs without making additional chain queries.
Tx *wire.MsgTx
// Block is the full block containing the confirmed transaction. This
// is only populated when the confirmation was registered with
// IncludeBlock=true. Used for constructing merkle proofs.
Block *wire.MsgBlock
}
ConfirmationEvent is sent when a monitored transaction reaches the target number of confirmations. This can be delivered either via a Future (for blocking await) or by sending to a registered actor (for async notification).
func (ConfirmationEvent) MessageType ¶
func (m ConfirmationEvent) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type EpochMsg ¶
EpochMsg is the sealed interface for all messages that can be sent to a BlockEpochActor sub-actor for block subscription.
type EpochResp ¶
EpochResp is the sealed interface for all response messages from a BlockEpochActor.
type FeeEstimateRequest ¶
type FeeEstimateRequest struct {
actor.BaseMessage
// TargetConf is the desired number of blocks within which the
// transaction should confirm.
TargetConf uint32
}
FeeEstimateRequest requests a fee estimation for a given confirmation target. The fee estimator will provide the satoshis per vbyte needed to confirm within the target number of blocks.
func (*FeeEstimateRequest) MessageType ¶
func (m *FeeEstimateRequest) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type FeeEstimateResponse ¶
type FeeEstimateResponse struct {
actor.BaseMessage
// SatPerVByte is the estimated fee rate in satoshis per virtual byte.
SatPerVByte btcutil.Amount
}
FeeEstimateResponse contains the estimated fee rate in satoshis per vbyte for the requested confirmation target.
func (*FeeEstimateResponse) MessageType ¶
func (m *FeeEstimateResponse) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type MempoolAcceptResult ¶
type MempoolAcceptResult struct {
// Txid is the transaction hash the result applies to.
Txid chainhash.Hash
// Accepted reports whether the backend would accept the
// transaction into its mempool.
Accepted bool
// Reason carries the backend's human-readable rejection reason
// when Accepted is false. Empty on acceptance.
Reason string
}
MempoolAcceptResult is the per-transaction outcome of a TestMempoolAccept call. One result is returned for each input tx, in the same order.
type PositiveDoneOrder ¶
type PositiveDoneOrder struct {
// contains filtered or unexported fields
}
PositiveDoneOrder preserves the causal positive-before-Done contract when a backend exposes those lifecycle facts on independent buffered channels. Go selects randomly among ready channels, so every transport boundary uses this small state machine instead of treating the selected order as causal order.
func (*PositiveDoneOrder) ObserveDone ¶
func (o *PositiveDoneOrder) ObserveDone() bool
ObserveDone records a terminal signal and reports whether a positive observation has already been delivered. False means the caller must retain the signal and wait rather than forwarding Done without identity metadata.
func (*PositiveDoneOrder) ObservePositive ¶
func (o *PositiveDoneOrder) ObservePositive() bool
ObservePositive records delivery of the current positive observation and reports whether an earlier-selected Done signal may now be delivered.
func (*PositiveDoneOrder) ObserveReorg ¶
func (o *PositiveDoneOrder) ObserveReorg()
ObserveReorg clears current-positive and deferred-finality state. A Done selected before any positive is not allowed to survive an intervening reorg.
type RegisterConfRequest ¶
type RegisterConfRequest struct {
actor.BaseMessage
// CallerID is a unique identifier provided by the caller. This is used
// to construct the service key for the dedicated actor, enabling
// deterministic cancellation.
CallerID string
// Txid is the transaction ID to monitor. Can be nil to match by script
// only.
Txid *chainhash.Hash
// PkScript is the public key script to monitor.
PkScript []byte
// TargetConfs is the number of confirmations to wait for.
TargetConfs uint32
// HeightHint is an optional height hint indicating the earliest block
// that could contain the transaction. This is an optimization for
// light clients. Set to 0 if unknown.
HeightHint uint32
// IncludeBlock indicates whether the confirmation event should include
// the full block containing the transaction. This is needed for
// constructing merkle proofs. When true, the ConfirmationEvent.Block
// field will be populated.
IncludeBlock bool
// NotifyActor is an optional actor reference. If Some, confirmation
// events will be sent to this actor asynchronously. If None, a Future
// is returned in the response for blocking await.
NotifyActor fn.Option[actor.TellOnlyRef[ConfirmationEvent]]
// NotifyReorged is an optional actor reference for negative
// confirmation events. It is only used in async actor mode.
NotifyReorged fn.Option[actor.TellOnlyRef[ConfReorgedEvent]]
// NotifyDone is an optional actor reference notified when the
// confirmation watch is beyond the backend's reorg tracking horizon.
// It is only used in async actor mode.
NotifyDone fn.Option[actor.TellOnlyRef[ConfDoneEvent]]
}
RegisterConfRequest requests monitoring of a transaction for a specified number of confirmations. The actor supports dual-mode operation: if NotifyActor is None, a Future is returned for blocking await; if NotifyActor is Some, events are sent to that actor asynchronously.
func (*RegisterConfRequest) MessageType ¶
func (m *RegisterConfRequest) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type RegisterConfResponse ¶
type RegisterConfResponse struct {
actor.BaseMessage
// Future provides a blocking await interface for confirmation. Only
// present if NotifyActor was None in the request.
Future actor.Future[ConfirmationEvent]
}
RegisterConfResponse contains either a Future for blocking on confirmation or nothing if actor-mode notification was requested. The subscription can be cancelled later using UnregisterConfRequest with the original CallerID.
func (*RegisterConfResponse) MessageType ¶
func (m *RegisterConfResponse) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type RegisterSpendRequest ¶
type RegisterSpendRequest struct {
actor.BaseMessage
// CallerID is a unique identifier provided by the caller. This is used
// to construct the service key for the dedicated actor, enabling
// deterministic cancellation.
CallerID string
// Outpoint is the transaction output to monitor for spends. Can be nil
// to match by script only.
Outpoint *wire.OutPoint
// PkScript is the public key script of the output to monitor.
PkScript []byte
// HeightHint is an optional height hint indicating the earliest block
// that could contain a spending transaction. Set to 0 if unknown.
HeightHint uint32
// NotifyActor is an optional actor reference. If Some, spend events
// will be sent to this actor asynchronously. If None, a Future is
// returned for blocking await.
NotifyActor fn.Option[actor.TellOnlyRef[SpendEvent]]
// NotifyReorged is an optional actor reference for spend reorg events.
// It is only used in async actor mode.
NotifyReorged fn.Option[actor.TellOnlyRef[SpendReorgedEvent]]
// NotifyDone is an optional actor reference notified when the spend
// watch is beyond the backend's reorg tracking horizon. It is only used
// in async actor mode.
NotifyDone fn.Option[actor.TellOnlyRef[SpendDoneEvent]]
}
RegisterSpendRequest requests monitoring of an outpoint for spend events. The actor supports dual-mode operation similar to RegisterConfRequest.
func (*RegisterSpendRequest) MessageType ¶
func (m *RegisterSpendRequest) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type RegisterSpendResponse ¶
type RegisterSpendResponse struct {
actor.BaseMessage
// Future provides a blocking await interface for spend notification.
// Only present if NotifyActor was None in the request.
Future actor.Future[SpendEvent]
}
RegisterSpendResponse contains either a Future for blocking on spend notification or nothing if actor-mode notification was requested. The subscription can be cancelled later using UnregisterSpendRequest with the original CallerID.
func (*RegisterSpendResponse) MessageType ¶
func (m *RegisterSpendResponse) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type SpendActor ¶
type SpendActor struct {
// contains filtered or unexported fields
}
SpendActor is a single-subscription actor that monitors outpoint spends and delivers events when outputs are consumed by confirmed transactions. Each instance serves exactly one subscription.
The actor supports dual-mode operation: Future mode for blocking await (exits after first event), and Actor mode for asynchronous event delivery (continues monitoring for re-orgs).
func NewSpendActor ¶
func NewSpendActor(cfg SpendActorConfig) *SpendActor
NewSpendActor creates a new SpendActor instance with the given configuration. The config must include Backend; use WithLogger() to inject a specific logger.
func (*SpendActor) OnStop ¶
func (a *SpendActor) OnStop(ctx context.Context) error
OnStop implements actor.Stoppable for proper cleanup when stopped via actor system. This is called after the actor's message loop exits.
func (*SpendActor) Stop ¶
func (a *SpendActor) Stop()
Stop gracefully shuts down the SpendActor. It cancels the context and waits for the monitoring goroutine to complete.
type SpendActorConfig ¶
type SpendActorConfig struct {
// Backend is the blockchain backend used to monitor spends.
Backend ChainBackend
// Log is an optional logger for this actor instance. If None, the actor
// falls back to extracting a logger from context via LoggerFromContext,
// or uses btclog.Disabled if no logger is found.
Log fn.Option[btclog.Logger]
// FinalityDepth is the number of confirmations past the first
// observed Spend event that the actor uses to synthesize a Done
// signal when the backend cannot deliver one. See the matching
// field on ConfActorConfig for the rationale; the same constraint
// applies on the spend watch — lnd's chainntnfs.SpendEvent.Done
// does not survive the lndclient gRPC transport, so consumers
// that gate eviction on Done would otherwise leak per-spend state.
FinalityDepth uint32
}
SpendActorConfig holds configuration for SpendActor.
func (SpendActorConfig) WithLogger ¶
func (c SpendActorConfig) WithLogger(log btclog.Logger) SpendActorConfig
WithLogger returns a new config with the given logger set.
type SpendDetail ¶
type SpendDetail struct {
// SpentOutPoint is the outpoint that was spent.
SpentOutPoint *wire.OutPoint
// SpenderTxHash is the hash of the spending transaction.
SpenderTxHash *chainhash.Hash
// SpendingTx is the full spending transaction.
SpendingTx *wire.MsgTx
// SpenderInputIndex is the input index in the spending transaction
// that consumed the outpoint.
SpenderInputIndex uint32
// SpendingHeight is the block height where the spending transaction
// was confirmed.
SpendingHeight int32
// Seq is a per-registration monotonic sequence number stamped by the
// backend forwarder in the order it observed lifecycle events. Spend
// and Reorged share one sequence space so the consumer can order them
// even though they arrive on separate channels (a select over two
// ready channels picks at random and cannot recover order). The
// consumer applies an event only when its Seq exceeds the highest Seq
// seen so far, discarding a stale event that lost a cross-channel
// race. Zero means the backend does not stamp sequences (it never
// reorgs, so ordering is moot); such events are always applied.
Seq uint64
}
SpendDetail contains details about a spend of a monitored outpoint. This is sent when the outpoint is consumed by a confirmed transaction.
type SpendDoneEvent ¶
type SpendDoneEvent struct {
actor.BaseMessage
// Outpoint is the output whose spend registration matured.
Outpoint wire.OutPoint
}
SpendDoneEvent is sent when a spend watch has matured past the backend's reorg-safety depth and will receive no further events. Not all backends synthesize this event; consumers must treat its absence as a normal operating condition rather than an error.
func (SpendDoneEvent) MessageType ¶
func (m SpendDoneEvent) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type SpendEvent ¶
type SpendEvent struct {
actor.BaseMessage
// Outpoint is the output that was spent.
Outpoint wire.OutPoint
// SpendingTxid is the transaction ID of the spending transaction.
SpendingTxid chainhash.Hash
// SpendingTx is the full spending transaction.
SpendingTx *wire.MsgTx
// SpenderInputIndex is the input index within the spending transaction
// that consumes the monitored outpoint.
SpenderInputIndex uint32
// SpendingHeight is the block height where the spending transaction
// was confirmed.
SpendingHeight int32
}
SpendEvent is sent when a monitored outpoint is spent in a transaction with at least one confirmation.
func (SpendEvent) MessageType ¶
func (m SpendEvent) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type SpendMsg ¶
SpendMsg is the sealed interface for all messages that can be sent to a SpendActor sub-actor for spend monitoring.
type SpendRegistration ¶
type SpendRegistration struct {
// Spend fires every time the monitored outpoint is spent on the
// canonical chain. After a Reorged event it may fire again when a
// new spender confirms. The channel is buffered.
Spend <-chan *SpendDetail
// Reorged fires when a previously delivered spend is reorged out of
// the canonical chain. The payload is the backend forwarder's
// monotonic sequence number (see SpendDetail.Seq) rather than reorg
// depth or block identity, which the lndclient gRPC transport cannot
// preserve; the sequence lets the consumer order this signal against
// spends sharing the same sequence space even though they arrive on a
// different channel. Backends that cannot observe spend reorgs leave
// this channel nil-equivalent (allocated but never written to);
// reading from it is always safe.
Reorged <-chan uint64
// Done fires once when the spend watch is past the backend's
// reorg-safety depth and will receive no further events. Callers
// must still invoke Cancel to release client-side resources.
// Backends that cannot synthesize a safety-depth signal leave this
// channel nil-equivalent (allocated but never written to).
Done <-chan struct{}
// Cancel is a function that can be called to cancel this registration
// and clean up resources.
Cancel func()
}
SpendRegistration encapsulates the channels and control functions for a spend registration. This mirrors lnd's chainntnfs.SpendEvent structure.
The registration is reorg-aware: after a spend has been delivered on Spend, a subsequent reorg that buries the spending block can cause a fresh send on Reorged. If the outpoint is then re-spent on the new canonical chain (by the same or a different transaction) another event arrives on Spend. The lifecycle is therefore Spend -> Reorged -> Spend -> ... terminated by either a send on Done (the spend is past the backend's reorg-safety depth) or a caller-driven Cancel. Backends that cannot observe reorgs leave Reorged and Done as never-firing channels.
type SpendReorgedEvent ¶
type SpendReorgedEvent struct {
actor.BaseMessage
// Outpoint is the output whose spend was reorged.
Outpoint wire.OutPoint
}
SpendReorgedEvent is sent when a previously reported spend is reorged out of the canonical chain. After receiving this event a consumer should consider the prior spend no longer valid; if the outpoint is re-spent on the new canonical chain a fresh SpendEvent will follow on the same registration.
No spending txid, height, or block hash is carried because the lndclient gRPC transport does not preserve that information and we do not want to expose fields that are always zero in production. Consumers that need to invalidate cached spending metadata should match on Outpoint and use the data from the most recent SpendEvent they observed on this watch.
func (SpendReorgedEvent) MessageType ¶
func (m SpendReorgedEvent) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type SubmitPackageRequest ¶
type SubmitPackageRequest struct {
actor.BaseMessage
// Parents is the list of parent transactions in dependency order.
Parents []*wire.MsgTx
// Child is the fee-paying child transaction.
Child *wire.MsgTx
}
SubmitPackageRequest requests atomic submission of a parent+child transaction package. The parents must be in dependency order and the child pays the package fee.
func (*SubmitPackageRequest) MessageType ¶
func (m *SubmitPackageRequest) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type SubmitPackageResponse ¶
type SubmitPackageResponse struct {
actor.BaseMessage
}
SubmitPackageResponse indicates successful package submission.
func (*SubmitPackageResponse) MessageType ¶
func (m *SubmitPackageResponse) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type SubscribeBlocksRequest ¶
type SubscribeBlocksRequest struct {
actor.BaseMessage
// CallerID is a unique identifier provided by the caller. This is used
// to construct the service key for the dedicated actor, enabling
// deterministic cancellation.
CallerID string
// NotifyActor is an optional actor reference. If Some, block events
// will be sent to this actor asynchronously. If None, an iterator is
// returned for use in range loops.
NotifyActor fn.Option[actor.TellOnlyRef[BlockEpoch]]
}
SubscribeBlocksRequest requests subscription to new block notifications. The actor supports dual-mode operation: if NotifyActor is None, an iterator is returned for range loops; if NotifyActor is Some, events are sent to that actor asynchronously.
func (*SubscribeBlocksRequest) MessageType ¶
func (m *SubscribeBlocksRequest) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type SubscribeBlocksResponse ¶
type SubscribeBlocksResponse struct {
actor.BaseMessage
// Iterator provides an iterator for iterating over block epochs using
// Go's range-over-function feature (Go 1.23+). Only present if
// NotifyActor was None in the request.
Iterator iter.Seq[BlockEpoch]
// Cancel terminates the subscription and cleans up backend resources.
// It is safe to call multiple times.
Cancel func()
}
SubscribeBlocksResponse contains either an iterator for range loops or nothing if actor-mode notification was requested. The subscription can be cancelled later using UnsubscribeBlocksRequest with the original CallerID.
func (*SubscribeBlocksResponse) MessageType ¶
func (m *SubscribeBlocksResponse) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type TestMempoolAcceptRequest ¶
type TestMempoolAcceptRequest struct {
actor.BaseMessage
// Txs are the transactions to test for mempool acceptance. One
// transaction performs a single-tx test; multiple transactions
// request a package test.
Txs []*wire.MsgTx
}
TestMempoolAcceptRequest requests a test of whether one or more transactions would be accepted by the mempool without actually broadcasting them. Passing more than one transaction asks the backend to evaluate the set as a package (per Bitcoin Core's testmempoolaccept RPC).
func (*TestMempoolAcceptRequest) MessageType ¶
func (m *TestMempoolAcceptRequest) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type TestMempoolAcceptResponse ¶
type TestMempoolAcceptResponse struct {
actor.BaseMessage
// Results has one entry per tx in the original request, in the
// same order.
Results []MempoolAcceptResult
}
TestMempoolAcceptResponse contains the per-transaction results of a mempool acceptance test.
func (*TestMempoolAcceptResponse) MessageType ¶
func (m *TestMempoolAcceptResponse) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type TxConfirmation ¶
type TxConfirmation struct {
// BlockHash is the hash of the block containing the transaction.
BlockHash *chainhash.Hash
// BlockHeight is the height of the block containing the transaction.
BlockHeight uint32
// TxIndex is the position of the transaction within the block.
TxIndex uint32
// Tx is the confirmed transaction itself.
Tx *wire.MsgTx
// Block is the full block containing the transaction. Only populated
// when the confirmation was registered with IncludeBlock=true. This
// matches lnd's chainntnfs behavior.
Block *wire.MsgBlock
// Seq is a per-registration monotonic sequence number stamped by the
// backend forwarder in the order it observed lifecycle events.
// Confirmed and Reorged share one sequence space so the consumer can
// order them even though they arrive on separate channels (a select
// over two ready channels picks at random and cannot recover order).
// The consumer applies an event only when its Seq exceeds the highest
// Seq seen so far, discarding a stale event that lost a cross-channel
// race. Zero means the backend does not stamp sequences (it never
// reorgs, so ordering is moot); such events are always applied.
Seq uint64
}
TxConfirmation contains details about a confirmed transaction. This is sent when a monitored transaction reaches its target confirmation count.
type UnregisterConfRequest ¶
type UnregisterConfRequest struct {
actor.BaseMessage
// CallerID is the unique identifier provided in the original
// RegisterConfRequest. Required to reconstruct the service key.
CallerID string
// Txid is the transaction ID being monitored. Can be nil to match by
// script only (must match the original registration).
Txid *chainhash.Hash
// PkScript is the public key script being monitored. Required if Txid
// is nil.
PkScript []byte
// TargetConfs is the number of confirmations from the original
// request. Required to reconstruct the service key.
TargetConfs uint32
}
UnregisterConfRequest requests cancellation of a confirmation subscription. The ChainSource actor uses the fields to construct the service key and cancel the dedicated actor.
func (*UnregisterConfRequest) MessageType ¶
func (m *UnregisterConfRequest) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type UnregisterConfResponse ¶
type UnregisterConfResponse struct {
actor.BaseMessage
}
UnregisterConfResponse indicates successful cancellation.
func (*UnregisterConfResponse) MessageType ¶
func (m *UnregisterConfResponse) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type UnregisterSpendRequest ¶
type UnregisterSpendRequest struct {
actor.BaseMessage
// CallerID is the unique identifier provided in the original
// RegisterSpendRequest. Required to reconstruct the service key.
CallerID string
// Outpoint is the transaction output being monitored. Can be nil to
// match by script only (must match the original registration).
Outpoint *wire.OutPoint
// PkScript is the public key script being monitored. Required if
// Outpoint is nil.
PkScript []byte
}
UnregisterSpendRequest requests cancellation of a spend subscription. The ChainSource actor uses the fields to construct the service key and cancel the dedicated actor.
func (*UnregisterSpendRequest) MessageType ¶
func (m *UnregisterSpendRequest) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type UnregisterSpendResponse ¶
type UnregisterSpendResponse struct {
actor.BaseMessage
}
UnregisterSpendResponse indicates successful cancellation.
func (*UnregisterSpendResponse) MessageType ¶
func (m *UnregisterSpendResponse) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type UnsubscribeBlocksRequest ¶
type UnsubscribeBlocksRequest struct {
actor.BaseMessage
// CallerID is the unique identifier provided in the original
// SubscribeBlocksRequest. Required to reconstruct the service key.
CallerID string
}
UnsubscribeBlocksRequest requests cancellation of a block subscription. The ChainSource actor uses the CallerID to construct the service key and cancel the dedicated actor.
func (*UnsubscribeBlocksRequest) MessageType ¶
func (m *UnsubscribeBlocksRequest) MessageType() string
MessageType returns the message type identifier for logging and debugging.
type UnsubscribeBlocksResponse ¶
type UnsubscribeBlocksResponse struct {
actor.BaseMessage
}
UnsubscribeBlocksResponse indicates successful cancellation.
func (*UnsubscribeBlocksResponse) MessageType ¶
func (m *UnsubscribeBlocksResponse) MessageType() string
MessageType returns the message type identifier for logging and debugging.