tapgarden

package
v0.3.3 Latest Latest
Warning

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

Go to latest
Published: Feb 7, 2024 License: MIT Imports: 41 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// GenesisAmtSats is the amount of sats we'll use to anchor created
	// assets within. This value just needs to be greater than dust, as for
	// now, we assume that the tapd client manages asset bearing UTXOs
	// distinctly from normal UTXOs.
	GenesisAmtSats = btcutil.Amount(1_000)

	// GenesisConfTarget is the confirmation target we'll use to query for
	// a fee estimate.
	GenesisConfTarget = 6

	// DefaultTimeout is the default timeout we use for RPC and database
	// operations.
	DefaultTimeout = 30 * time.Second
)
View Source
const Subsystem = "GRDN" // GRDN as in Garden.

Subsystem defines the logging code for this subsystem.

Variables

View Source
var (

	// DummyGenesisTxOut is the dummy TxOut we'll place in the PSBt funding
	// request to make sure we leave enough room for change and fees.
	DummyGenesisTxOut = wire.TxOut{
		PkScript: tapscript.GenesisDummyScript[:],
		Value:    int64(GenesisAmtSats),
	}

	// ErrGroupKeyUnknown is an error returned if an asset has a group key
	// attached that has not been previously verified.
	ErrGroupKeyUnknown = errors.New("group key not known")

	// ErrGenesisNotGroupAnchor is an error returned if an asset has a group
	// key attached, and the asset is not the anchor asset for the group.
	// This is true for any asset created via reissuance.
	ErrGenesisNotGroupAnchor = errors.New("genesis not group anchor")
)
View Source
var (
	// ErrInvalidAssetType is returned if an invalid asset type is passed
	// in.
	//
	// TODO(roasbeef): make proper error type struct?
	ErrInvalidAssetType = fmt.Errorf("invalid asset type")

	// ErrInvalidAssetAmt is returned in an asset request has an invalid
	// amount.
	ErrInvalidAssetAmt = fmt.Errorf("asset amt cannot be zero")
)

Functions

func AddrMatchesAsset

func AddrMatchesAsset(addr *address.AddrWithKeyInfo, a *asset.Asset) bool

AddrMatchesAsset returns true if the given asset state (ID, group key, script key) matches the state represented in the address.

func DisableLog

func DisableLog()

DisableLog disables all library log output. Logging output is disabled by default until UseLogger is called.

func EventMatchesProof added in v0.3.3

func EventMatchesProof(event *address.Event, p *proof.Proof) bool

EventMatchesProof returns true if the given event matches the given proof.

func GenGroupAnchorVerifier added in v0.3.0

func GenGroupAnchorVerifier(ctx context.Context,
	mintingStore MintingStore) func(*asset.Genesis, *asset.GroupKey) error

GenGroupAnchorVerifier generates a caching group anchor verification callback function given a DB handle.

func GenGroupVerifier added in v0.3.0

func GenGroupVerifier(ctx context.Context,
	mintingStore MintingStore) func(*btcec.PublicKey) error

GenGroupVerifier generates a group key verification callback function given a DB handle.

func GenHeaderVerifier

func GenHeaderVerifier(ctx context.Context,
	chainBridge ChainBridge) func(wire.BlockHeader, uint32) error

GenHeaderVerifier generates a block header on-chain verification callback function given a chain bridge.

func GenMockGroupVerifier added in v0.3.0

func GenMockGroupVerifier() func(*btcec.PublicKey) error

func GenRawGroupAnchorVerifier added in v0.3.0

func GenRawGroupAnchorVerifier(ctx context.Context) func(*asset.Genesis,
	*asset.GroupKey) error

GenRawGroupAnchorVerifier generates a group anchor verification callback function. This anchor verifier recomputes the tweaked group key with the passed genesis and compares that key to the given group key. This verifier is only used in the caretaker, before any asset groups are stored in the DB.

func GetTxFee

func GetTxFee(pkt *psbt.Packet) (int64, error)

GetTxFee returns the value of the on-chain fees paid by a finalized PSBT.

func RandSeedlings

func RandSeedlings(t testing.TB, numSeedlings int) map[string]*Seedling

RandSeedlings creates a new set of random seedlings for testing.

func SortAssets added in v0.3.0

func SortAssets(fullAssets []*asset.Asset,
	anchorVerifier proof.GroupAnchorVerifier) ([]*asset.Asset,
	[]*asset.Asset, error)

SortAssets sorts the batch assets such that assets that are group anchors are partitioned from all other assets.

func SortSeedlings

func SortSeedlings(seedlings []*Seedling) []string

SortSeedlings sorts the seedling names such that all seedlings that will be a group anchor are first.

func UseLogger

func UseLogger(logger btclog.Logger)

UseLogger uses a specified Logger to output package logging info. This should be used in preference to SetLogWriter if the caller is also using btclog.

Types

type AssetMetas

type AssetMetas map[asset.SerializedKey]*proof.MetaReveal

AssetMetas maps the serialized script key of an asset to the meta reveal for that asset, if it has one.

type AssetReceiveCompleteEvent added in v0.3.2

type AssetReceiveCompleteEvent struct {

	// Address is the address associated with the asset that was received.
	Address address.Tap

	// OutPoint is the outpoint of the transaction that was used to receive
	// the asset.
	OutPoint wire.OutPoint
	// contains filtered or unexported fields
}

AssetReceiveCompleteEvent is an event that is sent to a subscriber once the asset receive process has finished for a given address and outpoint.

func NewAssetRecvCompleteEvent added in v0.3.2

func NewAssetRecvCompleteEvent(addr address.Tap,
	outpoint wire.OutPoint) *AssetReceiveCompleteEvent

NewAssetRecvCompleteEvent creates a new AssetReceiveCompleteEvent.

func (*AssetReceiveCompleteEvent) Timestamp added in v0.3.2

func (e *AssetReceiveCompleteEvent) Timestamp() time.Time

Timestamp returns the timestamp of the event.

type BatchCaretaker

type BatchCaretaker struct {

	// ContextGuard provides a wait group and main quit channel that can be
	// used to create guarded contexts.
	*fn.ContextGuard
	// contains filtered or unexported fields
}

BatchCaretaker is the caretaker for a MintingBatch. It'll handle validating the batch, creating a transaction that mints all items in the batch, and waiting for enough confirmations for the batch to be considered finalized.

func NewBatchCaretaker

func NewBatchCaretaker(cfg *BatchCaretakerConfig) *BatchCaretaker

NewBatchCaretaker creates a new Taproot Asset caretaker based on the passed config.

TODO(roasbeef): rename to Cultivator?

func (*BatchCaretaker) Cancel

func (b *BatchCaretaker) Cancel() CancelResp

Cancel signals for a batch caretaker to stop advancing a batch if possible. A batch can only be cancelled if it has not reached BatchStateBroadcast yet.

func (*BatchCaretaker) Start

func (b *BatchCaretaker) Start() error

Start attempts to start a new batch caretaker.

func (*BatchCaretaker) Stop

func (b *BatchCaretaker) Stop() error

Stop signals for a batch caretaker to gracefully exit.

type BatchCaretakerConfig

type BatchCaretakerConfig struct {
	// Batch is the minting batch that this caretaker is responsible for?
	Batch *MintingBatch

	// BatchFeeRate is an optional manually-set feerate specified when
	// finalizing a batch.
	BatchFeeRate *chainfee.SatPerKWeight

	GardenKit

	// BroadcastCompleteChan is used to signal back to the caller that the
	// batch has been broadcast and is now waiting for confirmation. Either
	// this channel _or_ BroadcastErrChan is sent on, never both.
	BroadcastCompleteChan chan struct{}

	// BroadcastErrChan is used to signal back to the caller that while
	// attempting to proceed the batch to the state of broadcasting the
	// batch transaction, an error occurred. Either this channel _or_
	// BroadcastCompleteChan is sent on, never both.
	BroadcastErrChan chan error

	// SignalCompletion is used to signal back to the BatchPlanter that
	// their batch has been finalized.
	SignalCompletion func()

	// CancelChan is used by the BatchPlanter to signal that the caretaker
	// should stop advancing the batch.
	CancelReqChan chan struct{}

	// CancelRespChan is used by the BatchCaretaker to report the result of
	// attempted batch cancellation to the planter.
	CancelRespChan chan CancelResp

	// UpdateMintingProofs is used to update the minting proofs in the
	// database in case of a re-org. This cannot be done by the caretaker
	// itself, because its job is already done at the point that a re-org
	// can happen (the batch is finalized after a single confirmation).
	UpdateMintingProofs func([]*proof.Proof) error

	// ErrChan is the main error channel the caretaker will report back
	// critical errors to the main server.
	ErrChan chan<- error
}

BatchCaretakerConfig houses all the items that the BatchCaretaker needs to carry out its duties.

type BatchKey

type BatchKey = asset.SerializedKey

BatchKey is a type alias for a serialized public key.

type BatchState

type BatchState uint8

BatchState an enum that represents the various stages of a minting batch.

const (
	// BatchStatePending denotes that the batch is pending and may have
	// some assets allocated to it.
	BatchStatePending BatchState = 0

	// BatchStateFrozen denotes that a batch is frozen, and no new
	// seedlings can be added to it.
	BatchStateFrozen BatchState = 1

	// BatchStateCommitted denotes that a batch now has an unsigned genesis
	// PSBT packet and the set of seedlings have been made into sprouts
	// with all relevant fields populated.
	BatchStateCommitted BatchState = 2

	// BatchStateBroadcast denotes a batch now has a fully signed genesis
	// transaction and can be broadcast to the network.
	BatchStateBroadcast BatchState = 3

	// BatchStateConfirmed denotes that a batch has confirmed on chain, and
	// only needs a sufficient amount of confirmations before it can be
	// finalized.
	BatchStateConfirmed BatchState = 4

	// BatchStateFinalized is the final state for a batch. In this terminal
	// state the batch has been confirmed on chain, with all assets
	// created.
	BatchStateFinalized BatchState = 5

	// BatchStateSeedlingCancelled denotes that a batch has been cancelled,
	// and will not be passed to a caretaker.
	BatchStateSeedlingCancelled BatchState = 6

	// BatchStateSproutCancelled denotes that a batch has been cancelled
	// after being passed to a caretaker and sprouting.
	BatchStateSproutCancelled BatchState = 7
)

func NewBatchState added in v0.2.1

func NewBatchState(state uint8) (BatchState, error)

NewBatchState creates a BatchState from a uint8, returning an error if the input value does not map to a valid BatchState.

func (BatchState) String

func (b BatchState) String() string

String returns a human-readable string for the target batch state.

type CancelResp

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

CancelResp is the response from a caretaker attempting to cancel a batch.

type ChainBridge

type ChainBridge interface {
	// RegisterConfirmationsNtfn registers an intent to be notified once
	// txid reaches numConfs confirmations.
	RegisterConfirmationsNtfn(ctx context.Context, txid *chainhash.Hash,
		pkScript []byte, numConfs, heightHint uint32,
		includeBlock bool,
		reOrgChan chan struct{}) (*chainntnfs.ConfirmationEvent,
		chan error, error)

	// RegisterBlockEpochNtfn registers an intent to be notified of each
	// new block connected to the main chain.
	RegisterBlockEpochNtfn(ctx context.Context) (chan int32, chan error,
		error)

	// GetBlock returns a chain block given its hash.
	GetBlock(context.Context, chainhash.Hash) (*wire.MsgBlock, error)

	// GetBlockHash returns the hash of the block in the best blockchain at
	// the given height.
	GetBlockHash(context.Context, int64) (chainhash.Hash, error)

	// VerifyBlock returns an error if a block (with given header and
	// height) is not present on-chain. It also checks to ensure that block
	// height corresponds to the given block header.
	VerifyBlock(ctx context.Context, header wire.BlockHeader,
		height uint32) error

	// CurrentHeight return the current height of the main chain.
	CurrentHeight(context.Context) (uint32, error)

	// PublishTransaction attempts to publish a new transaction to the
	// network.
	PublishTransaction(context.Context, *wire.MsgTx) error

	// EstimateFee returns a fee estimate for the confirmation target.
	EstimateFee(ctx context.Context,
		confTarget uint32) (chainfee.SatPerKWeight, error)
}

ChainBridge is our bridge to the target chain. It's used to get confirmation notifications, the current height, publish transactions, and also estimate fees.

type ChainPlanter

type ChainPlanter struct {

	// ContextGuard provides a wait group and main quit channel that can be
	// used to create guarded contexts.
	*fn.ContextGuard
	// contains filtered or unexported fields
}

ChainPlanter is responsible for accepting new incoming requests to create taproot assets. The planter will periodically batch those requests into a new minting batch, which is handed off to a caretaker. While batches are progressing through maturity the planter will be responsible for sending notifications back to the relevant caller.

func NewChainPlanter

func NewChainPlanter(cfg PlanterConfig) *ChainPlanter

NewChainPlanter creates a new ChainPlanter instance given the passed config.

func (*ChainPlanter) CancelBatch

func (c *ChainPlanter) CancelBatch() (*btcec.PublicKey, error)

CancelBatch sends a signal to the planter to cancel the current batch.

func (*ChainPlanter) CancelSeedling

func (c *ChainPlanter) CancelSeedling() error

CancelSeedling attempts to cancel the creation of a new asset identified by its name. If the seedling has already progressed to a point where the genesis PSBT has been broadcasted, an error is returned.

NOTE: This is part of the Planter interface.

func (*ChainPlanter) FinalizeBatch

func (c *ChainPlanter) FinalizeBatch(
	feeRate *chainfee.SatPerKWeight) (*MintingBatch, error)

FinalizeBatch sends a signal to the planter to finalize the current batch.

func (*ChainPlanter) ListBatches

func (c *ChainPlanter) ListBatches(batchKey *btcec.PublicKey) ([]*MintingBatch,
	error)

ListBatches returns the single batch specified by the batch key, or the set of batches not yet finalized on disk.

func (*ChainPlanter) NumActiveBatches

func (c *ChainPlanter) NumActiveBatches() (int, error)

NumActiveBatches returns the total number of active batches that have an outstanding caretaker assigned.

func (*ChainPlanter) PendingBatch

func (c *ChainPlanter) PendingBatch() (*MintingBatch, error)

PendingBatch returns the current pending batch. If there's no pending batch, then an error is returned.

func (*ChainPlanter) QueueNewSeedling

func (c *ChainPlanter) QueueNewSeedling(req *Seedling) (SeedlingUpdates, error)

QueueNewSeedling attempts to queue a new seedling request (the intent for New asset creation or ongoing issuance) to the ChainPlanter. A channel is returned where future updates will be sent over. If an error is returned no issuance operation was possible.

NOTE: This is part of the Planter interface.

func (*ChainPlanter) Start

func (c *ChainPlanter) Start() error

Start starts the ChainPlanter and any goroutines it needs to carry out its duty.

func (*ChainPlanter) Stop

func (c *ChainPlanter) Stop() error

Stop signals the ChainPlanter to halt all operations gracefully.

type Custodian

type Custodian struct {

	// ContextGuard provides a wait group and main quit channel that can be
	// used to create guarded contexts.
	*fn.ContextGuard
	// contains filtered or unexported fields
}

Custodian is responsible for taking custody of an asset that is transferred to us on-chain. It watches the chain for incoming transfers defined by Taproot Asset addresses and then takes full custody of the transferred assets by collecting and validating their provenance proofs.

func NewCustodian

func NewCustodian(cfg *CustodianConfig) *Custodian

NewCustodian creates a new Taproot Asset custodian based on the passed config.

func (*Custodian) RegisterSubscriber added in v0.3.1

func (c *Custodian) RegisterSubscriber(receiver *fn.EventReceiver[fn.Event],
	deliverExisting bool, deliverFrom bool) error

RegisterSubscriber adds a new subscriber to the set of subscribers that will be notified of any new status update events.

TODO(ffranr): Add support for delivering existing events to new subscribers.

func (*Custodian) RemoveSubscriber added in v0.3.1

func (c *Custodian) RemoveSubscriber(
	subscriber *fn.EventReceiver[fn.Event]) error

RemoveSubscriber removes a subscriber from the set of status event subscribers.

func (*Custodian) Start

func (c *Custodian) Start() error

Start attempts to start a new custodian.

func (*Custodian) Stop

func (c *Custodian) Stop() error

Stop signals for a custodian to gracefully exit.

type CustodianConfig

type CustodianConfig struct {
	// ChainParams are the Taproot Asset specific chain parameters.
	ChainParams *address.ChainParams

	// WalletAnchor is the main interface for interacting with the on-chain
	// wallet.
	WalletAnchor WalletAnchor

	// ChainBridge is the main interface for interacting with the chain
	// backend.
	ChainBridge ChainBridge

	// GroupVerifier is used to verify the validity of the group key for an
	// asset.
	GroupVerifier proof.GroupVerifier

	// AddrBook is the storage backend for addresses.
	AddrBook *address.Book

	// ProofArchive is the storage backend for proofs to which we store new
	// incoming proofs.
	ProofArchive proof.Archiver

	// ProofNotifier is the storage backend for proofs from which we are
	// notified about new proofs. This can be the same as the ProofArchive
	// above but can also be different (for example if we should _store_ the
	// proofs to a multi archiver but only be notified about new proofs
	// being available in the relational database).
	ProofNotifier proof.NotifyArchiver

	// ProofCourierDispatcher is the dispatcher that is used to create new
	// proof courier handles for receiving proofs based on the protocol of
	// a proof courier address.
	ProofCourierDispatcher proof.CourierDispatch

	// ProofRetrievalDelay is the time duration the custodian waits having
	// identified an asset transfer on-chain and before retrieving the
	// corresponding proof via the proof courier service.
	ProofRetrievalDelay time.Duration

	// ProofWatcher is used to watch new proofs for their anchor transaction
	// to be confirmed safely with a minimum number of confirmations.
	ProofWatcher proof.Watcher

	// ErrChan is the main error channel the custodian will report back
	// critical errors to the main server.
	ErrChan chan<- error
}

CustodianConfig houses all the items that the Custodian needs to carry out its duties.

type FundedPsbt

type FundedPsbt struct {
	// Pkt is the PSBT packet itself.
	Pkt *psbt.Packet

	// ChangeOutputIndex denotes which output in the PSBT packet is the
	// change output. We use this to figure out which output will store our
	// Taproot Asset commitment (the non-change output).
	ChangeOutputIndex int32

	// ChainFees is the amount in sats paid in on-chain fees for this
	// transaction.
	ChainFees int64

	// LockedUTXOs is the set of UTXOs that were locked to create the PSBT
	// packet.
	LockedUTXOs []wire.OutPoint
}

FundedPsbt represents a fully funded PSBT transaction.

type GardenKit

type GardenKit struct {
	// Wallet is an active on chain wallet for the target chain.
	Wallet WalletAnchor

	// ChainBridge provides access to the chain for confirmation
	// notification, and other block related actions.
	ChainBridge ChainBridge

	// Log stores the current state of any active batch, throughout the
	// various states the planter will progress it through.
	Log MintingStore

	// KeyRing is used for obtaining internal keys for the anchor
	// transaction, as well as script keys for each asset and group keys
	// for assets created that permit ongoing emission.
	KeyRing KeyRing

	// GenSigner is used to generate signatures for the key group tweaked
	// by the genesis point when creating assets that permit on going
	// emission.
	GenSigner asset.GenesisSigner

	// GenTxBuilder is used to create virtual transactions for the group
	// witness generation process.
	GenTxBuilder asset.GenesisTxBuilder

	// TxValidator is used to validate group witnesses when creating assets
	// that support reissuance.
	TxValidator tapscript.TxValidator

	// ProofFiles stores the set of flat proof files.
	ProofFiles proof.Archiver

	// Universe is used to register new asset issuance with a local/remote
	// base universe instance.
	Universe universe.BatchRegistrar

	// ProofWatcher is used to watch new proofs for their anchor transaction
	// to be confirmed safely with a minimum number of confirmations.
	ProofWatcher proof.Watcher

	// UniversePushBatchSize is the number of minted items to push to the
	// local universe in a single batch.
	UniversePushBatchSize int
}

GardenKit holds the set of shared fundamental interfaces all sub-systems of the tapgarden need to function.

type KeyRing

type KeyRing interface {
	// DeriveNextKey attempts to derive the *next* key within the key
	// family (account in BIP-0043) specified. This method should return the
	// next external child within this branch.
	DeriveNextKey(context.Context,
		keychain.KeyFamily) (keychain.KeyDescriptor, error)

	// DeriveKey attempts to derive an arbitrary key specified by the
	// passed KeyLocator. This may be used in several recovery scenarios,
	// or when manually rotating something like our current default node
	// key.
	DeriveKey(context.Context,
		keychain.KeyLocator) (keychain.KeyDescriptor, error)

	// IsLocalKey returns true if the key is under the control of the wallet
	// and can be derived by it.
	IsLocalKey(context.Context, keychain.KeyDescriptor) bool
}

KeyRing is a mirror of the keychain.KeyRing interface, with the addition of a passed context which allows for cancellation of requests.

type MintingBatch

type MintingBatch struct {
	// CreationTime is the time that this batch was created.
	CreationTime time.Time

	// HeightHint is the recorded block height at time of creating this
	// batch. We use it to know where to start looking for the signed batch
	// transaction.
	HeightHint uint32

	// BatchKey is the unique identifier for a batch.
	BatchKey keychain.KeyDescriptor

	// Seedlings is the set of seedlings for this batch. This maps an
	// asset's name to the seedling itself.
	//
	// NOTE: This field is only set if the state is BatchStateFrozen or
	// BatchStatePending.
	Seedlings map[string]*Seedling

	// GenesisPacket is the funded genesis packet that may or may not be
	// fully signed. When broadcast, this will create all assets stored
	// within this batch.
	//
	// NOTE: This field is only set if the state is beyond
	// BatchStateCommitted.
	GenesisPacket *FundedPsbt

	// RootAssetCommitment is the root Taproot Asset commitment for all the
	// assets contained in this batch.
	//
	// NOTE: This field is only set if the state is beyond
	// BatchStateCommitted.
	RootAssetCommitment *commitment.TapCommitment

	// AssetMetas maps the serialized script key of an asset to the meta
	// reveal for that asset, if it has one.
	AssetMetas AssetMetas
	// contains filtered or unexported fields
}

MintingBatch packages the pending state of a batch, this includes the batch key, the state of the batch and the assets to be created.

TODO(roasbeef): split this up after all? into two struts? Either[A, B]?

func RandSeedlingMintingBatch

func RandSeedlingMintingBatch(t testing.TB, numSeedlings int) *MintingBatch

RandSeedlingMintingBatch creates a new minting batch with only random seedlings populated for testing.

func (*MintingBatch) MintingOutputKey

func (m *MintingBatch) MintingOutputKey() (*btcec.PublicKey, []byte, error)

MintingOutputKey derives the output key that once mined, will commit to the Taproot asset root, thereby creating the set of included assets.

func (*MintingBatch) State added in v0.2.1

func (m *MintingBatch) State() BatchState

State returns the private state of the batch.

func (*MintingBatch) UpdateState added in v0.2.1

func (m *MintingBatch) UpdateState(state BatchState)

UpdateState updates the state of a batch to a value that has been verified to be a valid batch state.

type MintingState

type MintingState uint8

MintingState is an enum that tracks an asset through the various minting stages.

const (
	// MintingStateNone is the default state, no actions have been taken.
	MintingStateNone MintingState = iota

	// MintingStateSeed denotes the seedling as been added to a batch.
	MintingStateSeed

	// MintingStateSeedling denotes that a seedling has been finalized in a
	// batch and now has a corresponding asset associated with it.
	MintingStateSeedling

	// MintingStateSprout denotes that a seedling has been paired with a
	// genesis transaction and broadcast for confirmation.
	MintingStateSprout

	// MintingStateAdult denotes that a seedling has been confirmed on
	// chain and reached full adulthood.
	MintingStateAdult
)

type MintingStore

type MintingStore interface {
	// CommitMintingBatch commits a new minting batch to disk, identified
	// by its batch key.
	CommitMintingBatch(ctx context.Context, newBatch *MintingBatch) error

	// UpdateBatchState updates the batch state on disk identified by the
	// batch key.
	UpdateBatchState(ctx context.Context, batchKey *btcec.PublicKey,
		newState BatchState) error

	// AddSeedlingsToBatch adds a new seedling to an existing batch. Once
	// added this batch should remain in the BatchStatePending state.
	//
	// TODO(roasbeef): assumption that only one pending batch at a time?
	AddSeedlingsToBatch(ctx context.Context, batchKey *btcec.PublicKey,
		seedlings ...*Seedling) error

	// FetchAllBatches fetches all the batches on disk.
	FetchAllBatches(ctx context.Context) ([]*MintingBatch, error)

	// FetchNonFinalBatches fetches all non-finalized batches, meaning
	// batches that haven't yet fully confirmed on chain.
	FetchNonFinalBatches(ctx context.Context) ([]*MintingBatch, error)

	// FetchMintingBatch is used to fetch a single minting batch specified
	// by the batch key.
	FetchMintingBatch(ctx context.Context,
		batchKey *btcec.PublicKey) (*MintingBatch, error)

	// AddSproutsToBatch adds a new set of sprouts to the batch, along with
	// a GenesisPacket, that once signed and broadcast with create the
	// set of assets on chain.
	//
	// NOTE: The BatchState should transition to BatchStateCommitted upon a
	// successful call.
	AddSproutsToBatch(ctx context.Context, batchKey *btcec.PublicKey,
		genesisPacket *FundedPsbt, assets *commitment.TapCommitment) error

	// CommitSignedGenesisTx adds a fully signed genesis transaction to the
	// batch, along with the Taproot Asset script root, which is the
	// left/right sibling for the Taproot Asset tapscript commitment in the
	// transaction.
	//
	// NOTE: The BatchState should transition to the BatchStateBroadcast
	// state upon a successful call.
	CommitSignedGenesisTx(ctx context.Context, batchKey *btcec.PublicKey,
		genesisTx *FundedPsbt, anchorOutputIndex uint32,
		tapRoot []byte) error

	// MarkBatchConfirmed marks the batch as confirmed on chain. The passed
	// block location information determines where exactly in the chain the
	// batch was confirmed.
	//
	// NOTE: The BatchState should transition to the BatchStateConfirmed
	// state upon a successful call.
	MarkBatchConfirmed(ctx context.Context, batchKey *btcec.PublicKey,
		blockHash *chainhash.Hash, blockHeight uint32,
		txIndex uint32, mintingProofs proof.AssetBlobs) error

	// FetchGroupByGenesis fetches the asset group created by the genesis
	// referenced by the given ID.
	FetchGroupByGenesis(ctx context.Context,
		genesisID int64) (*asset.AssetGroup, error)

	// FetchGroupByGroupKey fetches the asset group with a matching tweaked
	// key, including the genesis information used to create the group.
	FetchGroupByGroupKey(ctx context.Context,
		groupKey *btcec.PublicKey) (*asset.AssetGroup, error)
}

MintingStore is a log that stores information related to the set of pending minting batches. The ChainPlanter and ChainCaretaker use this log to record the process of seeding, planting, and finally maturing taproot assets that are a part of the batch.

type MockAssetSyncer added in v0.3.1

type MockAssetSyncer struct {
	Assets map[asset.ID]*asset.AssetGroup

	FetchedAssets chan *asset.AssetGroup

	FetchErrs bool
}

func NewMockAssetSyncer added in v0.3.1

func NewMockAssetSyncer() *MockAssetSyncer

func (*MockAssetSyncer) AddAsset added in v0.3.1

func (m *MockAssetSyncer) AddAsset(newAsset asset.Asset)

func (*MockAssetSyncer) EnableAssetSync added in v0.3.1

func (m *MockAssetSyncer) EnableAssetSync(_ context.Context,
	groupInfo *asset.AssetGroup) error

func (*MockAssetSyncer) FetchAsset added in v0.3.1

func (m *MockAssetSyncer) FetchAsset(id asset.ID) (*asset.AssetGroup, error)

func (*MockAssetSyncer) RemoveAsset added in v0.3.1

func (m *MockAssetSyncer) RemoveAsset(id asset.ID)

func (*MockAssetSyncer) SyncAssetInfo added in v0.3.1

func (m *MockAssetSyncer) SyncAssetInfo(_ context.Context,
	id *asset.ID) error

type MockChainBridge

type MockChainBridge struct {
	FeeEstimateSignal chan struct{}
	PublishReq        chan *wire.MsgTx
	ConfReqSignal     chan int
	BlockEpochSignal  chan struct{}

	NewBlocks chan int32

	ReqCount int
	ConfReqs map[int]*chainntnfs.ConfirmationEvent
}

func NewMockChainBridge

func NewMockChainBridge() *MockChainBridge

func (*MockChainBridge) CurrentHeight

func (m *MockChainBridge) CurrentHeight(_ context.Context) (uint32, error)

func (*MockChainBridge) EstimateFee

func (m *MockChainBridge) EstimateFee(ctx context.Context,
	_ uint32) (chainfee.SatPerKWeight, error)

func (*MockChainBridge) GetBlock

func (m *MockChainBridge) GetBlock(ctx context.Context,
	hash chainhash.Hash) (*wire.MsgBlock, error)

GetBlock returns a chain block given its hash.

func (*MockChainBridge) GetBlockHash added in v0.2.3

func (m *MockChainBridge) GetBlockHash(ctx context.Context,
	blockHeight int64) (chainhash.Hash, error)

GetBlockHash returns the hash of the block in the best blockchain at the given height.

func (*MockChainBridge) PublishTransaction

func (m *MockChainBridge) PublishTransaction(_ context.Context,
	tx *wire.MsgTx) error

func (*MockChainBridge) RegisterBlockEpochNtfn added in v0.3.0

func (m *MockChainBridge) RegisterBlockEpochNtfn(
	ctx context.Context) (chan int32, chan error, error)

func (*MockChainBridge) RegisterConfirmationsNtfn

func (m *MockChainBridge) RegisterConfirmationsNtfn(ctx context.Context,
	_ *chainhash.Hash, _ []byte, _, _ uint32, _ bool,
	_ chan struct{}) (*chainntnfs.ConfirmationEvent, chan error, error)

func (*MockChainBridge) SendConfNtfn

func (m *MockChainBridge) SendConfNtfn(reqNo int, blockHash *chainhash.Hash,
	blockHeight, blockIndex int, block *wire.MsgBlock,
	tx *wire.MsgTx)

func (*MockChainBridge) VerifyBlock added in v0.2.3

func (m *MockChainBridge) VerifyBlock(_ context.Context,
	_ wire.BlockHeader, _ uint32) error

VerifyBlock returns an error if a block (with given header and height) is not present on-chain. It also checks to ensure that block height corresponds to the given block header.

type MockGenSigner

type MockGenSigner struct {
	KeyRing *MockKeyRing
}

func NewMockGenSigner

func NewMockGenSigner(keyRing *MockKeyRing) *MockGenSigner

func (*MockGenSigner) SignVirtualTx added in v0.3.0

func (m *MockGenSigner) SignVirtualTx(signDesc *lndclient.SignDescriptor,
	virtualTx *wire.MsgTx, prevOut *wire.TxOut) (*schnorr.Signature,
	error)

type MockKeyRing

type MockKeyRing struct {
	FamIndex keychain.KeyFamily
	KeyIndex uint32

	Keys map[keychain.KeyLocator]*btcec.PrivateKey

	ReqKeys chan *keychain.KeyDescriptor
}

func NewMockKeyRing

func NewMockKeyRing() *MockKeyRing

func (*MockKeyRing) DeriveKey

func (*MockKeyRing) DeriveNextKey

func (m *MockKeyRing) DeriveNextKey(ctx context.Context,
	keyFam keychain.KeyFamily) (keychain.KeyDescriptor, error)

func (*MockKeyRing) DeriveNextTaprootAssetKey

func (m *MockKeyRing) DeriveNextTaprootAssetKey(
	ctx context.Context) (keychain.KeyDescriptor, error)

DeriveNextTaprootAssetKey attempts to derive the *next* key within the Taproot Asset key family.

func (*MockKeyRing) IsLocalKey

type MockProofArchive

type MockProofArchive struct {
}

func (*MockProofArchive) FetchProof

func (m *MockProofArchive) FetchProof(ctx context.Context,
	id proof.Locator) (proof.Blob, error)

func (*MockProofArchive) FetchProofs added in v0.3.0

func (m *MockProofArchive) FetchProofs(ctx context.Context,
	id asset.ID) ([]*proof.AnnotatedProof, error)

func (*MockProofArchive) HasProof added in v0.3.3

func (m *MockProofArchive) HasProof(ctx context.Context,
	id proof.Locator) (bool, error)

func (*MockProofArchive) ImportProofs

func (m *MockProofArchive) ImportProofs(ctx context.Context,
	headerVerifier proof.HeaderVerifier, groupVerifier proof.GroupVerifier,
	replace bool, proofs ...*proof.AnnotatedProof) error

type MockProofWatcher added in v0.3.0

type MockProofWatcher struct {
}

func (*MockProofWatcher) DefaultUpdateCallback added in v0.3.0

func (m *MockProofWatcher) DefaultUpdateCallback() proof.UpdateCallback

func (*MockProofWatcher) MaybeWatch added in v0.3.0

func (*MockProofWatcher) ShouldWatch added in v0.3.0

func (m *MockProofWatcher) ShouldWatch(*proof.Proof) bool

func (*MockProofWatcher) WatchProofs added in v0.3.0

func (m *MockProofWatcher) WatchProofs([]*proof.Proof,
	proof.UpdateCallback) error

type MockWalletAnchor

type MockWalletAnchor struct {
	FundPsbtSignal     chan *FundedPsbt
	SignPsbtSignal     chan struct{}
	ImportPubKeySignal chan *btcec.PublicKey
	ListUnspentSignal  chan struct{}
	SubscribeTxSignal  chan struct{}
	SubscribeTx        chan lndclient.Transaction
	ListTxnsSignal     chan struct{}

	Transactions  []lndclient.Transaction
	ImportedUtxos []*lnwallet.Utxo
}

func NewMockWalletAnchor

func NewMockWalletAnchor() *MockWalletAnchor

func (*MockWalletAnchor) FundPsbt

func (*MockWalletAnchor) ImportTaprootOutput

func (m *MockWalletAnchor) ImportTaprootOutput(ctx context.Context,
	pub *btcec.PublicKey) (btcutil.Address, error)

func (*MockWalletAnchor) ImportTapscript

func (m *MockWalletAnchor) ImportTapscript(_ context.Context,
	tapscript *waddrmgr.Tapscript) (btcutil.Address, error)

ImportTapscript imports a Taproot output script into the wallet to track it on-chain in a watch-only manner.

func (*MockWalletAnchor) ListTransactions

func (m *MockWalletAnchor) ListTransactions(ctx context.Context, _, _ int32,
	_ string) ([]lndclient.Transaction, error)

ListTransactions returns all known transactions of the backing lnd node. It takes a start and end block height which can be used to limit the block range that we query over. These values can be left as zero to include all blocks. To include unconfirmed transactions in the query, endHeight must be set to -1.

func (*MockWalletAnchor) ListUnspentImportScripts

func (m *MockWalletAnchor) ListUnspentImportScripts(
	ctx context.Context) ([]*lnwallet.Utxo, error)

ListUnspentImportScripts lists all UTXOs of the imported Taproot scripts.

func (*MockWalletAnchor) SignAndFinalizePsbt

func (m *MockWalletAnchor) SignAndFinalizePsbt(ctx context.Context,
	pkt *psbt.Packet) (*psbt.Packet, error)

func (*MockWalletAnchor) SubscribeTransactions

func (m *MockWalletAnchor) SubscribeTransactions(
	ctx context.Context) (<-chan lndclient.Transaction, <-chan error, error)

SubscribeTransactions creates a uni-directional stream from the server to the client in which any newly discovered transactions relevant to the wallet are sent over.

func (*MockWalletAnchor) UnlockInput

func (m *MockWalletAnchor) UnlockInput(_ context.Context) error

type Planter

type Planter interface {
	// QueueNewSeedling attempts to queue a new seedling request (the
	// intent for New asset creation or ongoing issuance) to the Planter.
	// A channel is returned where future updates will be sent over. If an
	// error is returned no issuance operation was possible.
	QueueNewSeedling(req *Seedling) (SeedlingUpdates, error)

	// ListBatches lists the set of batches submitted for minting, or the
	// details of a specific batch.
	ListBatches(batchKey *btcec.PublicKey) ([]*MintingBatch, error)

	// CancelSeedling attempts to cancel the creation of a new asset
	// identified by its name. If the seedling has already progressed to a
	// point where the genesis PSBT has been broadcasted, an error is
	// returned.
	CancelSeedling() error

	// FinalizeBatch signals that the asset minter should finalize
	// the current batch, if one exists.
	FinalizeBatch(feeRate *chainfee.SatPerKWeight) (*MintingBatch, error)

	// CancelBatch signals that the asset minter should cancel the
	// current batch, if one exists.
	CancelBatch() (*btcec.PublicKey, error)

	// Start signals that the asset minter should being operations.
	Start() error

	// Stop signals that the asset minter should attempt a graceful
	// shutdown.
	Stop() error
}

Planter is responsible for batching a set of seedlings into a minting batch that will eventually be confirmed on chain.

type PlanterConfig

type PlanterConfig struct {
	GardenKit

	// BatchTicker is used to notify the planter than it should assemble
	// all asset requests into a new batch.
	BatchTicker *ticker.Force

	// ProofUpdates is the storage backend for updated proofs.
	ProofUpdates proof.Archiver

	// ErrChan is the main error channel the planter will report back
	// critical errors to the main server.
	ErrChan chan<- error
}

PlanterConfig is the main config for the ChainPlanter.

type ReOrgWatcher added in v0.3.0

type ReOrgWatcher struct {

	// ContextGuard provides a wait group and main quit channel that can be
	// used to create guarded contexts.
	*fn.ContextGuard
	// contains filtered or unexported fields
}

ReOrgWatcher is responsible for watching initially confirmed transactions until they reach a safe confirmation depth. If a re-org happens, it will update the proof and store it in the proof archive.

func NewReOrgWatcher added in v0.3.0

func NewReOrgWatcher(cfg *ReOrgWatcherConfig) *ReOrgWatcher

NewReOrgWatcher creates a new re-org watcher based on the passed config.

func (*ReOrgWatcher) DefaultUpdateCallback added in v0.3.0

func (w *ReOrgWatcher) DefaultUpdateCallback() proof.UpdateCallback

DefaultUpdateCallback is the default implementation for the update callback that is called when a proof is updated. This implementation will replace the old proof in the proof archiver (multi-archive) with the new one.

func (*ReOrgWatcher) MaybeWatch added in v0.3.0

func (w *ReOrgWatcher) MaybeWatch(file *proof.File,
	onProofUpdate proof.UpdateCallback) error

MaybeWatch inspects the given proof file for any proofs that are not yet buried sufficiently deep and adds them to the re-org watcher.

func (*ReOrgWatcher) ShouldWatch added in v0.3.0

func (w *ReOrgWatcher) ShouldWatch(p *proof.Proof) bool

ShouldWatch returns true if the proof is for a block that is not yet sufficiently deep to be considered safe.

func (*ReOrgWatcher) Start added in v0.3.0

func (w *ReOrgWatcher) Start() error

Start attempts to start a new re-org watcher.

func (*ReOrgWatcher) Stop added in v0.3.0

func (w *ReOrgWatcher) Stop() error

Stop signals for a re-org watcher to gracefully exit.

func (*ReOrgWatcher) WatchProofs added in v0.3.0

func (w *ReOrgWatcher) WatchProofs(newProofs []*proof.Proof,
	onProofUpdate proof.UpdateCallback) error

WatchProofs adds new proofs to the re-org watcher for their anchor transaction to be watched until it reaches a safe confirmation depth.

type ReOrgWatcherConfig added in v0.3.0

type ReOrgWatcherConfig struct {
	// ChainBridge is the main interface for interacting with the chain
	// backend.
	ChainBridge ChainBridge

	// GroupVerifier is used to verify the validity of the group key for an
	// asset.
	GroupVerifier proof.GroupVerifier

	// ProofArchive is the storage backend for proofs to which we store
	// updated proofs.
	ProofArchive proof.Archiver

	// NonBuriedAssetFetcher is a function that returns all assets that are
	// not yet sufficiently deep buried.
	NonBuriedAssetFetcher func(ctx context.Context,
		minHeight int32) ([]*asset.ChainAsset, error)

	// SafeDepth is the number of confirmations we require before we
	// consider a transaction to be safely buried in the chain.
	SafeDepth int32

	// ErrChan is the main error channel the watcher will report back
	// critical errors to the main server.
	ErrChan chan<- error
}

ReOrgWatcherConfig houses all the items that the re-org watcher needs to carry out its duties.

type Seedling

type Seedling struct {
	// AssetVersion is the version of the asset to be created.
	AssetVersion asset.Version

	// AssetType is the type of the asset.
	AssetType asset.Type

	// AssetName is the name of the asset.
	AssetName string

	// Meta is the set of metadata associated with the asset.
	Meta *proof.MetaReveal

	// Amount is the total amount of the asset.
	Amount uint64

	// GroupInfo contains the information needed to link this asset to an
	// exiting group.
	GroupInfo *asset.AssetGroup

	// EnableEmission if true, then an asset group key will be specified
	// for this asset meaning future assets linked to it can be created.
	EnableEmission bool

	// GroupAnchor is the name of another seedling in the pending batch that
	// will anchor an asset group. This seedling will be minted with the
	// same group key as the anchor asset.
	GroupAnchor *string
	// contains filtered or unexported fields
}

Seedling is an adolescent Taproot asset that will one day bloom into a fully grown plant.

func (Seedling) HasGroupKey

func (c Seedling) HasGroupKey() bool

HasGroupKey checks if a seedling specifies a particular group key.

func (Seedling) String

func (c Seedling) String() string

String returns a human-readable representation for the AssetSeedling.

type SeedlingUpdate

type SeedlingUpdate struct {
	// NewState is the new state a seedling has transitioned to.
	NewState MintingState

	// PendingBatch is the current pending batch that the seedling has been
	// added to.
	PendingBatch *MintingBatch

	// Error if non-nil, denotes that an terminal error state has been
	// reached.
	Error error
}

SeedlingUpdate is a struct used to send notifications w.r.t the state of a seedling back to the caller.

type SeedlingUpdates

type SeedlingUpdates chan SeedlingUpdate

SeedlingUpdates is a channel that will be used to send updates for each seedling back to the caller.

type WalletAnchor

type WalletAnchor interface {
	// FundPsbt attaches enough inputs to the target PSBT packet for it to
	// be valid.
	FundPsbt(ctx context.Context, packet *psbt.Packet, minConfs uint32,
		feeRate chainfee.SatPerKWeight) (FundedPsbt, error)

	// SignAndFinalizePsbt fully signs and finalizes the target PSBT
	// packet.
	SignAndFinalizePsbt(context.Context, *psbt.Packet) (*psbt.Packet, error)

	// ImportTaprootOutput imports a new public key into the wallet, as a
	// P2TR output.
	ImportTaprootOutput(context.Context, *btcec.PublicKey) (btcutil.Address, error)

	// UnlockInput unlocks the set of target inputs after a batch is
	// abandoned.
	UnlockInput(context.Context) error

	// ListUnspentImportScripts lists all UTXOs of the imported Taproot
	// scripts.
	ListUnspentImportScripts(ctx context.Context) ([]*lnwallet.Utxo, error)

	// ListTransactions returns all known transactions of the backing lnd
	// node. It takes a start and end block height which can be used to
	// limit the block range that we query over. These values can be left
	// as zero to include all blocks. To include unconfirmed transactions
	// in the query, endHeight must be set to -1.
	ListTransactions(ctx context.Context, startHeight, endHeight int32,
		account string) ([]lndclient.Transaction, error)

	// SubscribeTransactions creates a uni-directional stream from the
	// server to the client in which any newly discovered transactions
	// relevant to the wallet are sent over.
	SubscribeTransactions(context.Context) (<-chan lndclient.Transaction,
		<-chan error, error)
}

WalletAnchor is the main wallet interface used to managed PSBT packets, and import public keys into the wallet.

Jump to

Keyboard shortcuts

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