tarofreighter

package
v0.1.1-alpha Latest Latest
Warning

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

Go to latest
Published: Nov 9, 2022 License: MIT Imports: 28 Imported by: 0

Documentation

Index

Constants

View Source
const Subsystem = "FRTR"

Subsystem defines the logging code for this subsystem.

Variables

View Source
var (
	// ErrNoPossibleAssetInputs is returned when an instance of a
	// CommitmentSelector cannot satisfy the coin selection constraints.
	ErrNoPossibleAssetInputs = fmt.Errorf("unable to satisfy coin " +
		"selection constraints")
)

Functions

func DisableLog

func DisableLog()

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

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 AnchoredCommitment

type AnchoredCommitment struct {
	// AnchorPoint is the outpoint that the Commitment below is anchored on
	// in the main chain.
	AnchorPoint wire.OutPoint

	// AnchorOutputValue is output value of the anchor output.
	AnchorOutputValue btcutil.Amount

	// InternalKey is the internal key that's used to anchor the commitment
	// in the above out point.
	InternalKey keychain.KeyDescriptor

	// TapscriptSibling is the tapscript sibling of this asset. This will
	// usually be blank.
	TapscriptSibling []byte

	// Commitment is the full Taro commitment anchored at the above
	// outpoint. This includes both the asset to be used as an input, along
	// with any other assets that might be collocated in this commitment.
	Commitment *commitment.TaroCommitment

	// Asset is the asset that ratifies the above constraints, and should
	// be used as an input to a transaction.
	Asset *asset.Asset
}

AnchoredCommitment is the response to satisfying the set of CommitmentConstraints. This includes the asset itself, and also information needed to locate the asset on-chain and also prove its existence.

type AssetConfirmEvent

type AssetConfirmEvent struct {
	// AnchorPoint is the anchor point that was previously unconfirmed.
	AnchorPoint wire.OutPoint

	// BlockHash is the block hash that confirmed the above anchor point.
	BlockHash chainhash.Hash

	// BlockHeight is the height of the block hash above.
	BlockHeight int32

	// TxIndex is the location within the block that confirmed the anchor
	// point.
	TxIndex int32

	// FinalSenderProof is the final proof for the sender that includes the
	// chain information of the final confirmation point.
	FinalSenderProof []byte
}

AssetConfirmEvent is used to mark a batched spend as confirmed on disk.

type AssetInput

type AssetInput struct {
	// PrevID is the prev ID of the input.
	PrevID asset.PrevID

	// Amount is the amount stored in the target asset input.
	Amount btcutil.Amount
}

AssetInput represents a previous asset input.

type AssetOutput

type AssetOutput struct {
	AssetInput

	// NewBlob is the new proof blob of the asset.
	//
	// TODO(roasbeef): should just be the last transition, or mmap'd
	NewBlob proof.Blob

	// SplitCommitProof is an optional field of the split commitment proof.
	// If this is set, then this new asset was a split that resulted from a
	// send that needed change.
	SplitCommitProof *commitment.SplitCommitment
}

AssetOutput represents a new asset output created as a result of a transfer.

type AssetParcel

type AssetParcel struct {
	// Dest is the address that should be used to satisfy the transfer.
	Dest *address.Taro
	// contains filtered or unexported fields
}

AssetParcel is the main request to issue an asset transfer. This packages a destination address, and also response context.

type AssetSpendDelta

type AssetSpendDelta struct {
	// OldScriptKey is the old script key that uniquely identified the
	// spent asset on disk.
	OldScriptKey btcec.PublicKey

	// NewAmt is the new amount for the asset.
	NewAmt uint64

	// NewScriptKey is the new script key. We assume BIP 86 usage when
	// updating the script keys on disk.
	NewScriptKey asset.ScriptKey

	// WitnessData is the new witness data for this asset.
	WitnessData []asset.Witness

	// SplitCommitmentRoot is the root split commitment for this asset.
	// This will only be set if a split was required to complete the send.
	SplitCommitmentRoot mssmt.Node

	// SenderAssetProof is the fully serialized proof of the sender which
	// includes all the proof information other than the final chain
	// information.
	SenderAssetProof []byte

	// ReceiverAssetProof is the fully serialized proof for the receiver,
	// which commits to the receiver's asset with the split commitment
	// included.
	ReceiverAssetProof []byte
}

AssetSpendDelta describes the mutation of an asset as part of an outbound parcel (batched send). As we always require script keys to be unique, we simply need to know the old script key, and the new amount.

type ChainBridge

type ChainBridge = tarogarden.ChainBridge

ChainBridge aliases into the ChainBridge of the tarogarden package.

type ChainPorter

type ChainPorter struct {
	*chanutils.ContextGuard
	// contains filtered or unexported fields
}

ChainPorter is the main sub-system of the tarofreighter package. The porter is responsible for transferring your bags (assets). This porter is responsible for taking incoming delivery requests (parcels) and generating a final transfer transaction along with all the proofs needed to complete the transfer.

func NewChainPorter

func NewChainPorter(cfg *ChainPorterConfig) *ChainPorter

NewChainPorter creates a new instance of the ChainPorter given a valid config.

func (*ChainPorter) RequestShipment

func (p *ChainPorter) RequestShipment(req *AssetParcel) (*PendingParcel, error)

RequestShipment is the main external entry point to the porter. This request a new transfer take place.

func (*ChainPorter) Start

func (p *ChainPorter) Start() error

Start kicks off the chain porter and any goroutines it needs to carry out its duty.

func (*ChainPorter) Stop

func (p *ChainPorter) Stop() error

Stop signals that the chain porter should gracefully stop.

type ChainPorterConfig

type ChainPorterConfig struct {
	// CoinSelector is the interface used to select input coins (assets)
	// for the transfer.
	CoinSelector CommitmentSelector

	// Signer implements the Taro level signing we need to sign a virtual
	// transaction.
	Signer Signer

	// TxValidator allows us to validate each Taro virtual transaction we
	// create.
	TxValidator taroscript.TxValidator

	// ExportLog is used to log information about pending parcels to disk.
	ExportLog ExportLog

	// ChainBridge is our bridge to the chain we operate on.
	ChainBridge ChainBridge

	// Wallet is used to fund+sign PSBTs for the transfer transaction.
	Wallet WalletAnchor

	// KeyRing is used to generate new keys throughout the transfer
	// process.
	KeyRing KeyRing

	// ChainParams is the chain params of the chain we operate on.
	ChainParams *address.ChainParams

	// AssetProofs is used to write the proof files on disk for the
	// receiver during a transfer.
	//
	// TODO(roasbeef): replace with proof.Courier in the future/
	AssetProofs proof.Archiver

	// ProofCourier is used to optionally deliver the final proof to the
	// user using an asynchronous transport mechanism.
	ProofCourier proof.Courier[address.Taro]

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

ChainPorterConfig is the main config for the chain porter.

type CommitmentConstraints

type CommitmentConstraints struct {
	// FamilyKey is the required family key. This is an optional field, if
	// set then the asset returned may have a distinct asset ID to the one
	// specified below.
	FamilyKey *btcec.PublicKey

	// AssetID is the asset ID that needs to be satisfied.
	AssetID *asset.ID

	// MinAmt is the minimum amount that an asset commitment needs to hold
	// to satisfy the constraints.
	MinAmt uint64
}

CommitmentConstraints conveys the constraints on the type of Taro asset commitments needed to satisfy a send request. Typically for Bitcoin we just care about the amount. In the case of Taro, we also need to worry about the asset ID, and also the type of asset we need.

NOTE: Only the FamilyKey or the AssetID should be set.

type CommitmentSelector

type CommitmentSelector interface {
	// SelectCommitment takes the set of commitment constraints and returns
	// an AnchoredCommitment that returns all the information needed to use
	// the commitment as an input to an on chain taro transaction.
	//
	// If coin selection cannot be completed, then ErrNoPossibleAssetInputs
	// should be returned.
	SelectCommitment(context.Context,
		CommitmentConstraints) ([]*AnchoredCommitment, error)
}

CommitmentSelector attracts over the coin selection process needed to be able to execute moving taro assets on chain.

type ExportLog

type ExportLog interface {
	// LogPendingParcel marks an outbound parcel as pending on disk. This
	// commits the set of changes to disk (the asset deltas) but doesn't
	// mark the batched spend as being finalized.
	LogPendingParcel(context.Context, *OutboundParcelDelta) error

	// PendingParcels returns the set of parcels that haven't yet been
	// finalized. This can be used to query the set of unconfirmed
	// transactions for re-broadcast.
	PendingParcels(context.Context) ([]*OutboundParcelDelta, error)

	// ConfirmParcelDelivery marks a spend event on disk as confirmed. This
	// updates the on-chain reference information on disk to point to this
	// new spend.
	ConfirmParcelDelivery(context.Context, *AssetConfirmEvent) error
}

ExportLog is used to track the state of outbound taro parcels (batched spends). This log is used by the ChainPorter to mark pending outbound deliveries, and finally confirm the deliveries once they've been committed to the main chain.

type KeyRing

type KeyRing = tarogarden.KeyRing

KeyRing aliases into the KeyRing of the tarogarden package.

type OutboundParcelDelta

type OutboundParcelDelta struct {
	// OldAnchorPoint is the old/current location of the Taro commitment
	// that was spent as an input.
	OldAnchorPoint wire.OutPoint

	// NewAnchorPoint is the new location of the Taro commitment referenced
	// by the OldAnchorPoint.
	NewAnchorPoint wire.OutPoint

	// NewInternalKey is the new internal key that commits to the set of
	// assets anchored at the new outpoint.
	NewInternalKey keychain.KeyDescriptor

	// TaroRoot is the new Taro root that commits to the set of modified
	// and unmodified assets.
	TaroRoot []byte

	// TapscriptSibling is the tapscript sibling for the asset commitment
	// above.
	TapscriptSibling []byte

	// AnchorTx is the new transaction that commits to the set of Taro
	// assets found at the above NewAnchorPoint.
	AnchorTx *wire.MsgTx

	// AssetSpendDeltas describes the set of mutated assets that now live
	// at the new anchor tx point.
	AssetSpendDeltas []AssetSpendDelta

	// TransferTime holds the timestamp of the outbound spend.
	TransferTime time.Time

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

OutboundParcelDelta represents the database level delta of an outbound taro parcel (outbound spend). A spend will destroy a series of assets at the old anchor point, and re-create them at the new anchor point. Along the way some assets may have been split or sent to others. This is reflected in the set of AssetSpendDeltas.

type PendingParcel

type PendingParcel struct {
	// OldTaroRoot is the Taro commitment root of the old anchor point.
	OldTaroRoot []byte

	// NewAnchorPoint is the new anchor point that commits to our new change assets.
	NewAnchorPoint wire.OutPoint

	// NewTaroRoot is the Taro commitment root of the new anchor point.
	NewTaroRoot []byte

	// TransferTx is the transaction that completed the transfer.
	TransferTx *wire.MsgTx

	// AssetInputs are the set if inputs to the transfer transfer
	// transaction on the Taro layer.
	AssetInputs []AssetInput

	// AssetOutputs is the set of newly produced outputs.
	AssetOutputs []AssetOutput

	// TotalFees is the amount of on chain fees that the transfer
	// transaction required.
	TotalFees btcutil.Amount
}

PendingParcel is the response to an AssetParcel shipment request. This contains all the information of the pending transfer.

type Porter

type Porter interface {
	// RequestShipment attempts to request that a new send be funneled
	// through the chain porter. If successful, an initial response will be
	// returned with the pending transfer information.
	RequestShipment(req *AssetParcel) (*PendingParcel, 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
}

Porter is a high level interface that wraps the main caller execution point to the ChainPorter.

type SendState

type SendState uint8

SendState is an enum that describes the current state of a pending outbound parcel (asset transfer).

const (
	// SendStateInitializing is that staring state of a transfer. In this
	// state, the initial context needed for a transfer is created.
	SendStateInitializing SendState = iota

	// SendStateCommitmentSelect is the state for performing input coin
	// selection to pick out which assets inputs should be spent.
	SendStateCommitmentSelect

	// SendStateValidatedInput validates the inputs to ensure that the set
	// of selected commitments can satisfy the transfer.
	SendStateValidatedInput

	// SendStatePreparedSplit prepares the splits (if needed) for a
	// transfer that will create a change output.
	SendStatePreparedSplit

	// SendStatePreparedComplete is the alternative to
	// SendStatePreparedSplit. We enter this state when a split isn't
	// required.
	SendStatePreparedComplete

	// SendStateSigned is used to generate the Taro level witness data for
	// any inputs being spent.
	SendStateSigned

	// SendStateCommitmentsUpdated is the state we enter to after we sign
	// each of the new Taro asset leaves. In this state, we'll construct
	// the final commitments that both sides will find in the chain.
	SendStateCommitmentsUpdated

	// SendStatePsbtFund is the state we enter after we have all the Taro
	// level witness data created. In this state, we'll ask the wallet to
	// fund a PSBT with enough fund for the transfer transaction at the
	// specified fee rate.
	SendStatePsbtFund

	// SendStatePsbtSign is the state we enter after the PSBT has been
	// funded. In this state, we'll ask the wallet to sign the PSBT and
	// then finalize to place the necessary signatures in the transaction.
	SendStatePsbtSign

	// SendStateLogCommit is the final in memory state. In this state,
	// we'll extract the signed transaction from the PSBT and log the
	// transfer information to disk. At this point, after a restart, the
	// transfer can be resumed.
	SendStateLogCommit

	// SendStateBroadcast broadcasts the transfer transaction to the
	// network, and imports the taproot output back into the wallet to
	// ensure it properly tracks the coins allocated to the anchor output.
	SendStateBroadcast

	// SendStateWaitingConf is the final terminal state. In this state,
	// we'll register for a confirmation request, and also handle the final
	// proof transfer.
	SendStateWaitingConf
)

func (SendState) String

func (s SendState) String() string

String returns a human readable version of SendState.

type Signer

type Signer = taroscript.Signer

Signer aliases into the Signer interface of the taroscript package.

type WalletAnchor

type WalletAnchor interface {
	tarogarden.WalletAnchor

	// SignPsbt signs all the inputs it can in the passed PSBT packet,
	// returning a new one with updated signature/witness data.
	SignPsbt(ctx context.Context, packet *psbt.Packet) (*psbt.Packet, error)
}

WalletAnchor aliases into the WalletAnchor of the tarogarden package.

Jump to

Keyboard shortcuts

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