fraud

package
v0.1.1-rc2 Latest Latest
Warning

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

Go to latest
Published: Jul 31, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package fraud detects recipient-side OOR ancestry materialization.

Index

Constants

View Source
const (
	// Subsystem is the logging subsystem label for recipient fraud watches.
	Subsystem = "CFRD"

	// ServiceKeyName is the receptionist key for the recipient fraud
	// watcher.
	ServiceKeyName = "recipient-fraud-watcher"
)

Variables

View Source
var (
	// ErrWatchUnavailable indicates local state is insufficient to arm
	// recipient fraud watches.
	ErrWatchUnavailable = fmt.Errorf("recipient fraud watch unavailable")

	// ErrWatchInvalid indicates persisted ancestry state is internally
	// inconsistent.
	ErrWatchInvalid = fmt.Errorf("recipient fraud watch invalid")
)

Functions

func ServiceKey

func ServiceKey() actor.ServiceKey[Msg, Resp]

ServiceKey returns the actor service key for the recipient fraud watcher. Callers that need to look the watcher up via the receptionist should use this rather than constructing the key themselves; it locks down a single concrete instantiation site.

func TrackVTXOs

func TrackVTXOs(ctx context.Context, tracker actor.TellOnlyRef[Msg],
	descs []*vtxo.Descriptor) error

TrackVTXOs asks tracker to arm passive fraud watches for live OOR VTXOs.

Types

type AckResp

type AckResp struct {
	actor.BaseMessage
}

AckResp is a generic acknowledgement.

func (*AckResp) MessageType

func (m *AckResp) MessageType() string

MessageType returns the stable actor message type.

type Msg

type Msg interface {
	actor.Message
	// contains filtered or unexported methods
}

Msg is the sealed fraud watcher message surface.

type Resp

type Resp interface {
	actor.Message
	// contains filtered or unexported methods
}

Resp is the sealed fraud watcher response surface.

type SpendObservedMsg

type SpendObservedMsg struct {
	actor.BaseMessage

	// Outpoint is the watched outpoint that was spent.
	Outpoint wire.OutPoint

	// SpendingTxid is the transaction that spent Outpoint.
	SpendingTxid chainhash.Hash

	// SpendingTx is the full spending transaction. Its witness is what
	// establishes which taproot path the spend took, which is the only
	// way to tell the operator's legitimate batch sweep apart from a
	// sender materializing ancestry.
	SpendingTx *wire.MsgTx

	// SpenderInputIndex is the input of SpendingTx that consumes Outpoint.
	SpenderInputIndex uint32

	// Height is the confirmation height of SpendingTxid.
	Height int32
}

SpendObservedMsg reports a spend of one watched ancestor outpoint.

func (*SpendObservedMsg) MessageType

func (m *SpendObservedMsg) MessageType() string

MessageType returns the stable actor message type.

type TrackVTXOsRequest

type TrackVTXOsRequest struct {
	actor.BaseMessage

	// VTXOs are locally materialized descriptors to consider for tracking.
	VTXOs []*vtxo.Descriptor
}

TrackVTXOsRequest asks the watcher to arm passive watches for descriptors.

func (*TrackVTXOsRequest) MessageType

func (m *TrackVTXOsRequest) MessageType() string

MessageType returns the stable actor message type.

type TrackVTXOsResp

type TrackVTXOsResp struct {
	actor.BaseMessage

	// Tracked is the number of descriptors that resulted in active watches.
	Tracked int
}

TrackVTXOsResp summarizes watcher admission.

func (*TrackVTXOsResp) MessageType

func (m *TrackVTXOsResp) MessageType() string

MessageType returns the stable actor message type.

type UntrackRequest

type UntrackRequest struct {
	actor.BaseMessage

	// TargetOutpoint identifies the no-longer-live target VTXO.
	TargetOutpoint wire.OutPoint
}

UntrackRequest asks the watcher to release one target's passive watches.

func (*UntrackRequest) MessageType

func (m *UntrackRequest) MessageType() string

MessageType returns the stable actor message type.

type UntrackResp

type UntrackResp struct {
	actor.BaseMessage

	// Removed reports whether an active target was removed.
	Removed bool
}

UntrackResp acknowledges an untrack request.

func (*UntrackResp) MessageType

func (m *UntrackResp) MessageType() string

MessageType returns the stable actor message type.

type WatchPlan

type WatchPlan struct {
	// TargetOutpoint is the VTXO to unroll if any watched ancestor spends.
	TargetOutpoint wire.OutPoint

	// Watches are the ancestor outpoints that indicate materialization has
	// started.
	Watches []WatchPoint
}

WatchPlan is the passive ancestry watch set for one locally-owned OOR VTXO.

func BuildWatchPlan

func BuildWatchPlan(desc *vtxo.Descriptor) (*WatchPlan, error)

BuildWatchPlan builds the passive fraud watch set for desc.

type WatchPoint

type WatchPoint struct {
	// Outpoint is the ancestor output to watch for a spend.
	Outpoint wire.OutPoint

	// PkScript is the script committed to Outpoint.
	PkScript []byte

	// HeightHint is the earliest plausible spend height.
	HeightHint uint32

	// SweepLeafHash is the tap hash of the operator's unilateral-CSV
	// timeout leaf committed in this output's taproot. A spend that
	// reveals exactly this leaf is the operator's legitimate batch sweep
	// rather than a sender materializing ancestry, so it is what
	// distinguishes the two. Empty when the tree carries no sweep script
	// (connector trees), in which case no spend can be attributed to the
	// operator and every spend escalates.
	SweepLeafHash []byte
}

WatchPoint identifies one outpoint the fraud watcher should monitor.

func (WatchPoint) IsOperatorSweepSpend

func (p WatchPoint) IsOperatorSweepSpend(tx *wire.MsgTx,
	inputIndex uint32) bool

IsOperatorSweepSpend reports whether the observed spend of this watch point took the operator's committed unilateral-CSV timeout leaf, i.e. whether it is the operator's legitimate batch sweep.

Provenance, not timing, is the test. Chain height only proves the timeout path has matured; it says nothing about which path a given transaction actually used, so a hostile expansion confirmed after expiry would pass a height check while being exactly the thing fraud response exists to answer. Matching the revealed tapleaf against the one committed in the watched output settles it.

type WatcherActor

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

WatcherActor is the recipient fraud watcher: a passive ancestor-spend monitor that forces the affected target into unilateral exit through the VTXO manager (ForceUnrollRequest under TriggerFraudSpend) when any watched ancestor of a tracked OOR VTXO is observed spent on chain. It is both the public handle (Ref / Stop) and the actor.ActorBehavior implementation; the runtime is driven through the embedded actor.

func NewWatcherActor

func NewWatcherActor(cfg WatcherConfig) *WatcherActor

NewWatcherActor creates and starts the recipient fraud watcher actor.

func (*WatcherActor) OnStop

func (w *WatcherActor) OnStop(ctx context.Context) error

OnStop releases every active spend watch. A failure on one outpoint must not abandon the rest, so each failure is logged and aggregated into the returned joined error.

func (*WatcherActor) Receive

func (w *WatcherActor) Receive(ctx context.Context, msg Msg) fn.Result[Resp]

Receive processes one watcher actor message.

func (*WatcherActor) Ref

func (w *WatcherActor) Ref() actor.ActorRef[Msg, Resp]

Ref returns the public watcher actor reference.

func (*WatcherActor) Stop

func (w *WatcherActor) Stop()

Stop stops the underlying watcher actor.

type WatcherConfig

type WatcherConfig struct {
	// ChainSource provides passive ancestor spend watches.
	ChainSource actor.ActorRef[
		chainsource.ChainSourceMsg, chainsource.ChainSourceResp,
	]

	// VTXOManagerRef drives affected targets into unilateral exit through
	// the VTXO manager's single admission gate. The manager transitions
	// the VTXO to UnilateralExitState (persisting it out of the live set)
	// and emits the chain-resolver notification that starts the durable
	// unroll job under TriggerFraudSpend, so fraud escalation converges on
	// the same path as manual and critical-expiry exits rather than
	// admitting the registry job behind the manager's back.
	VTXOManagerRef actor.ActorRef[vtxo.ManagerMsg, vtxo.ManagerResp]

	// Log is an optional logger.
	Log fn.Option[btclog.Logger]

	// MailboxSize overrides the watcher's actor mailbox capacity.
	// Zero or negative applies defaultWatcherMailboxSize. Sized to
	// absorb a burst of per-target spend notifications during a
	// chain reorganization without blocking the chainsource
	// publisher.
	MailboxSize int
}

WatcherConfig configures the recipient fraud watcher actor.

Jump to

Keyboard shortcuts

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