proof

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: 41 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// TaroFileSuffix is the main file suffix for the Taro proof files stored
	// on disk.
	TaroFileSuffix = ".taro"

	// ProofDirName is the name of the directory we'll use to store our
	// proofs.
	ProofDirName = "proofs"
)
View Source
const (
	PrevOutType          tlv.Type = 0
	BlockHeaderType      tlv.Type = 1
	AnchorTxType         tlv.Type = 2
	TxMerkleProofType    tlv.Type = 3
	AssetLeafType        tlv.Type = 4
	InclusionProofType   tlv.Type = 5
	ExclusionProofsType  tlv.Type = 6
	SplitRootProofType   tlv.Type = 7
	AdditionalInputsType tlv.Type = 8

	TaprootProofOutputIndexType     tlv.Type = 0
	TaprootProofInternalKeyType     tlv.Type = 1
	TaprootProofCommitmentProofType tlv.Type = 2
	TaprootProofTapscriptProofType  tlv.Type = 3

	CommitmentProofAssetProofType         tlv.Type = 0
	CommitmentProofTaroProofType          tlv.Type = 1
	CommitmentProofTapSiblingPreimageType tlv.Type = 2

	TapscriptProofTapPreimage1 tlv.Type = 0
	TapscriptProofTapPreimage2 tlv.Type = 1
	TapscriptProofBIP86        tlv.Type = 2

	AssetProofVersionType tlv.Type = 0
	AssetProofAssetIDType tlv.Type = 1
	AssetProofType        tlv.Type = 2

	TaroProofVersionType tlv.Type = 0
	TaroProofType        tlv.Type = 1
)
View Source
const Subsystem = "PROF"

Subsystem defines the logging code for this subsystem.

Variables

View Source
var (
	// ErrProofNotFound is returned when a user attempts to look up a proof
	// based on a Locator, but we can't find it on disk.
	ErrProofNotFound = fmt.Errorf("unable to find proof")

	// ErrInvalidLocatorID is returned when a specified has an invalid
	// asset ID.
	ErrInvalidLocatorID = fmt.Errorf("invalid asset ID locator")

	// ErrInvalidLocatorKey is returned when a specified locator script key
	// is invalid.
	ErrInvalidLocatorKey = fmt.Errorf("invalid script key locator")
)
View Source
var (
	// ErrInvalidChecksum is an error returned when an invalid proof file
	// checksum is detected while deserializing it.
	ErrInvalidChecksum = errors.New("invalid proof file checksum")

	// ErrNoProofAvailable is the error that's returned when a proof is
	// attempted to be fetched from an empty file.
	ErrNoProofAvailable = errors.New("no proof available")
)
View Source
var (
	// ErrInvalidTaprootProof is an error returned upon verifying an invalid
	// Taproot proof.
	ErrInvalidTaprootProof = errors.New("invalid taproot proof")

	// ErrInvalidTxMerkleProof is an error returned upon verifying an
	// invalid on-chain transaction merkle proof.
	ErrInvalidTxMerkleProof = errors.New("invalid transaction merkle proof")

	// ErrMissingExclusionProofs is an error returned upon noticing an
	// exclusion proof for a P2TR output is missing.
	ErrMissingExclusionProofs = errors.New("missing exclusion proof(s)")

	// ErrMissingSplitRootProof is an error returned upon noticing an
	// inclusion proof for a split root asset is missing.
	ErrMissingSplitRootProof = errors.New("missing split root proof")
)
View Source
var (
	// ErrInvalidCommitmentProof is an error returned upon attempting to
	// prove a malformed CommitmentProof.
	ErrInvalidCommitmentProof = errors.New("invalid taro commitment proof")

	// ErrInvalidTapscriptProof is an error returned upon attempting to
	// prove a malformed TapscriptProof.
	ErrInvalidTapscriptProof = errors.New("invalid tapscript proof")
)

Functions

func AdditionalInputsDecoder

func AdditionalInputsDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func AdditionalInputsEncoder

func AdditionalInputsEncoder(w io.Writer, val any, buf *[8]byte) error

func AdditionalInputsRecord

func AdditionalInputsRecord(inputs *[]File) tlv.Record

func AnchorTxRecord

func AnchorTxRecord(tx *wire.MsgTx) tlv.Record

func AppendTransition

func AppendTransition(blob Blob, params *TransitionParams) (Blob, *Proof,
	error)

AppendTransition appends a new proof for a state transition to the given encoded proof file. Because multiple assets can be committed to in the same on-chain output, this function takes the script key of the asset to return the proof for. This method returns both the encoded full provenance (proof chain) and the added latest proof.

func AssetLeafDecoder

func AssetLeafDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func AssetLeafEncoder

func AssetLeafEncoder(w io.Writer, val any, buf *[8]byte) error

func AssetLeafRecord

func AssetLeafRecord(asset *asset.Asset) tlv.Record

func AssetProofAssetIDRecord

func AssetProofAssetIDRecord(assetID *[32]byte) tlv.Record

func AssetProofDecoder

func AssetProofDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func AssetProofEncoder

func AssetProofEncoder(w io.Writer, val any, buf *[8]byte) error

func AssetProofRecord

func AssetProofRecord(proof *mssmt.Proof) tlv.Record

func AssetProofVersionRecord

func AssetProofVersionRecord(version *asset.Version) tlv.Record

func BlockHeaderDecoder

func BlockHeaderDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func BlockHeaderEncoder

func BlockHeaderEncoder(w io.Writer, val any, buf *[8]byte) error

func BlockHeaderRecord

func BlockHeaderRecord(header *wire.BlockHeader) tlv.Record

func BoolDecoder

func BoolDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func BoolEncoder

func BoolEncoder(w io.Writer, val any, buf *[8]byte) error

func CommitmentProofAssetProofRecord

func CommitmentProofAssetProofRecord(proof **commitment.AssetProof) tlv.Record

func CommitmentProofDecoder

func CommitmentProofDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func CommitmentProofEncoder

func CommitmentProofEncoder(w io.Writer, val any, buf *[8]byte) error

func CommitmentProofTapSiblingPreimageRecord

func CommitmentProofTapSiblingPreimageRecord(preimage **TapscriptPreimage,
) tlv.Record

func CommitmentProofTaroProofRecord

func CommitmentProofTaroProofRecord(proof *commitment.TaroProof) tlv.Record

func DisableLog

func DisableLog()

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

func ExclusionProofsRecord

func ExclusionProofsRecord(proofs *[]TaprootProof) tlv.Record

func ExtractTaprootKey

func ExtractTaprootKey(tx *wire.MsgTx,
	outputIndex uint32) (*btcec.PublicKey, error)

ExtractTaprootKey attempts to extract a Taproot tweaked key from the output found at `outputIndex`.

func InclusionProofRecord

func InclusionProofRecord(proof *TaprootProof) tlv.Record

func PrevOutRecord

func PrevOutRecord(prevOut *wire.OutPoint) tlv.Record

func SplitRootProofDecoder

func SplitRootProofDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func SplitRootProofEncoder

func SplitRootProofEncoder(w io.Writer, val any, buf *[8]byte) error

func SplitRootProofRecord

func SplitRootProofRecord(proof **TaprootProof) tlv.Record

func TaprootProofCommitmentProofRecord

func TaprootProofCommitmentProofRecord(proof **CommitmentProof) tlv.Record

func TaprootProofDecoder

func TaprootProofDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func TaprootProofEncoder

func TaprootProofEncoder(w io.Writer, val any, buf *[8]byte) error

func TaprootProofInternalKeyRecord

func TaprootProofInternalKeyRecord(internalKey **btcec.PublicKey) tlv.Record

func TaprootProofOutputIndexRecord

func TaprootProofOutputIndexRecord(idx *uint32) tlv.Record

func TaprootProofTapscriptProofRecord

func TaprootProofTapscriptProofRecord(proof **TapscriptProof) tlv.Record

func TaprootProofsDecoder

func TaprootProofsDecoder(r io.Reader, val any, buf *[8]byte, _ uint64) error

func TaprootProofsEncoder

func TaprootProofsEncoder(w io.Writer, val any, buf *[8]byte) error

func TapscriptPreimageDecoder

func TapscriptPreimageDecoder(r io.Reader, val any, buf *[8]byte,
	l uint64) error

func TapscriptPreimageEncoder

func TapscriptPreimageEncoder(w io.Writer, val any, buf *[8]byte) error

func TapscriptProofBIP86Record

func TapscriptProofBIP86Record(bip86 *bool) tlv.Record

func TapscriptProofDecoder

func TapscriptProofDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func TapscriptProofEncoder

func TapscriptProofEncoder(w io.Writer, val any, buf *[8]byte) error

func TapscriptProofTapPreimage1Record

func TapscriptProofTapPreimage1Record(preimage **TapscriptPreimage) tlv.Record

func TapscriptProofTapPreimage2Record

func TapscriptProofTapPreimage2Record(preimage **TapscriptPreimage) tlv.Record

func TaroProofDecoder

func TaroProofDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func TaroProofEncoder

func TaroProofEncoder(w io.Writer, val any, buf *[8]byte) error

func TaroProofRecord

func TaroProofRecord(proof *mssmt.Proof) tlv.Record

func TaroProofVersionRecord

func TaroProofVersionRecord(version *asset.Version) tlv.Record

func TreeProofDecoder

func TreeProofDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func TreeProofEncoder

func TreeProofEncoder(w io.Writer, val any, buf *[8]byte) error

func TxDecoder

func TxDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func TxEncoder

func TxEncoder(w io.Writer, val any, buf *[8]byte) error

func TxMerkleProofDecoder

func TxMerkleProofDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func TxMerkleProofEncoder

func TxMerkleProofEncoder(w io.Writer, val any, buf *[8]byte) error

func TxMerkleProofRecord

func TxMerkleProofRecord(proof *TxMerkleProof) tlv.Record

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 AnnotatedProof

type AnnotatedProof struct {
	Locator

	Blob

	*AssetSnapshot
}

AnnotatedProof an annotated proof contains the raw proof blob along with a locator that may convey additional information related to the proof.

type Archiver

type Archiver interface {
	// FetchProof fetches a proof for an asset uniquely identified by the
	// passed ProofIdentifier.
	//
	// If a proof cannot be found, then ErrProofNotFound should be
	// returned.
	FetchProof(ctx context.Context, id Locator) (Blob, error)

	// ImportProofs attempts to store fully populated proofs on disk. The
	// previous outpoint of the first state transition will be used as the
	// Genesis point. The final resting place of the asset will be used as
	// the script key itself.
	ImportProofs(ctx context.Context, proofs ...*AnnotatedProof) error
}

Archiver is the main storage backend the ProofArchiver uses to store and query for proof files.

TODO(roasbeef): other queries like fetching all proofs for a given asset?

type AssetBlobs

type AssetBlobs map[asset.SerializedKey]Blob

AssetBlobs is a data structure used to pass around the proof files for a set of assets which may have been created in the same batched transaction. This maps the script key of the asset to the serialized proof file blob.

func NewMintingBlobs

func NewMintingBlobs(params *MintParams) (AssetBlobs, error)

NewMintingBlobs takes a set of minting parameters, and produces a series of serialized proof files, which proves the creation/existence of each of the assets within the batch.

type AssetSnapshot

type AssetSnapshot struct {
	// Asset is the resulting asset of a valid proof.
	Asset *asset.Asset

	// OutPoint is the outpoint that commits to the asset specified above.
	OutPoint wire.OutPoint

	// AnchorBlockHash is the block hash that anchors the Bitcoin
	// transaction for this Taro state transition.
	AnchorBlockHash chainhash.Hash

	// AnchorBlockHeight is the height of the block hash above.
	AnchorBlockHeight uint32

	// AnchorTxIndex is the transaction index within the above block where
	// the AnchorTx can be found.
	AnchorTxIndex uint32

	// AnchorTx is the transaction that commits to the above asset.
	AnchorTx *wire.MsgTx

	// OutputIndex is the output index in the above transaction that
	// commits to the output.
	OutputIndex uint32

	// InternalKey is the internal key used to commit to the above asset in
	// the AnchorTx.
	InternalKey *btcec.PublicKey

	// ScriptRoot is the Taro commitment root committed to using the above
	// internal key in the Anchor transaction.
	ScriptRoot *commitment.TaroCommitment

	// SplitAsset is the optional indicator that the asset in the snapshot
	// resulted from splitting an asset. If this is true then the root asset
	// of the split can be found in the asset witness' split commitment.
	SplitAsset bool
}

AssetSnapshot commits to the result of a valid proof within a proof file. This represents the state of an asset's lineage at a given point in time.

type BaseProofParams

type BaseProofParams struct {
	// Block is the block that mined the transaction that minted the
	// specified assets.
	Block *wire.MsgBlock

	// Tx is the transaction that created the assets.
	Tx *wire.MsgTx

	// TxIndex is the index of the transaction within the block above.
	TxIndex int

	// OutputIndex is the index of the output in the above transaction that
	// holds the asset commitment.
	OutputIndex int

	// InternalKey is the internal key used to derive the taproot output
	// key in the above transaction.
	InternalKey *btcec.PublicKey

	// TaroRoot is the asset root that commits to all assets created in the
	// above transaction.
	TaroRoot *commitment.TaroCommitment

	// ExclusionProofs is the set of TaprootProofs proving the exclusion of
	// any assets from all other Taproot outputs within Tx.
	ExclusionProofs []TaprootProof
}

BaseProofParams holds the set of chain level information needed to create a proof.

type BaseVerifier

type BaseVerifier struct {
}

BaseVerifier implements a simple verifier that loads the entire proof file into memory and then verifies it all at once.

func (*BaseVerifier) Verify

func (b *BaseVerifier) Verify(ctx context.Context,
	blobReader io.Reader) (*AssetSnapshot, error)

Verify takes the passed serialized proof file, and returns a nil error if the proof file is valid. A valid file should return an AssetSnapshot of the final state transition of the file.

type Blob

type Blob []byte

Blob represents a serialized proof file, including the checksum.

type CommitmentProof

type CommitmentProof struct {
	commitment.Proof

	// TapSiblingPreimage is an optional preimage of a tap node used to
	// hash together with the Taro commitment leaf node to arrive at the
	// tapscript root of the expected output.
	TapSiblingPreimage *TapscriptPreimage
}

CommitmentProof represents a full commitment proof for an asset. It can either prove inclusion or exclusion of an asset within a Taro commitment.

func (*CommitmentProof) Decode

func (p *CommitmentProof) Decode(r io.Reader) error

Decode attempts to decode the CommitmentProof from the passed io.Reader.

func (*CommitmentProof) DecodeRecords

func (p *CommitmentProof) DecodeRecords() []tlv.Record

DecodeRecords returns the decoding records for the CommitmentProof.

func (CommitmentProof) Encode

func (p CommitmentProof) Encode(w io.Writer) error

Encode attempts to encode the CommitmentProof into the passed io.Writer.

func (CommitmentProof) EncodeRecords

func (p CommitmentProof) EncodeRecords() []tlv.Record

EncodeRecords returns the encoding records for the CommitmentProof.

type Courier

type Courier[Addr any] interface {
	// DeliverProof attempts to delivery a proof to the receiver, using the
	// information in the Addr type.
	DeliverProof(context.Context, Addr, *AnnotatedProof) error

	// ReceiveProof attempts to obtain a proof as identified by the passed
	// locator from the source encapsulated within the specified address.
	ReceiveProof(context.Context, Addr, Locator) (*AnnotatedProof, error)
}

Courier abstracts away from the final proof retrival/delivery process as part of the non-interactive send flow. A sender can use this given the abstracted Addr/source type to send a proof to the receiver. Conversely, a receiver can use this to fetch a proof from the sender.

TODO(roasbeef): FileSystemCourier, RpcCourier

type File

type File struct {
	// Version is the version of the proof file.
	Version Version
	// contains filtered or unexported fields
}

File represents a proof file comprised of proofs for all of an asset's state transitions back to its genesis state.

func NewEmptyFile

func NewEmptyFile(v Version) *File

NewEmptyFile returns a new empty file with the given version.

func NewFile

func NewFile(v Version, proofs ...Proof) (*File, error)

NewFile returns a new proof file given a version and a series of state transition proofs.

func (*File) AppendProof

func (f *File) AppendProof(proof Proof) error

AppendProof appends a proof to the file and calculates its chained hash.

func (*File) Decode

func (f *File) Decode(r io.Reader) error

Decode decodes a proof file from `r`.

func (*File) Encode

func (f *File) Encode(w io.Writer) error

Encode encodes the proof file into `w` including its checksum.

func (*File) IsEmpty

func (f *File) IsEmpty() bool

IsEmpty returns true if the file does not contain any proofs.

func (*File) LastProof

func (f *File) LastProof() (*Proof, error)

LastProof returns the last proof in the chain of proofs. If the file is empty, this return nil.

func (*File) NumProofs

func (f *File) NumProofs() int

NumProofs returns the number of proofs contained in this file.

func (*File) ProofAt

func (f *File) ProofAt(index uint32) (*Proof, error)

ProofAt returns the proof at the given index. If the file is empty, this returns nil.

func (*File) ReplaceLastProof

func (f *File) ReplaceLastProof(proof Proof) error

ReplaceLastProof attempts to replace the last proof in the file with another one, updating its chained hash in the process.

func (*File) Verify

func (f *File) Verify(ctx context.Context) (*AssetSnapshot, error)

Verify attempts to verify a full proof file starting from the asset's genesis.

The passed context can be used to exit early from the inner proof verification loop.

TODO(roasbeef): pass in the expected genesis point here?

type FileArchiver

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

FileArchiver implements proof Archiver backed by an on-disk file system. The archiver takes a single root directory then creates the following overlap mapping:

proofs/ ├─ asset_id1/ │ ├─ script_key1 │ ├─ script_key2

func NewFileArchiver

func NewFileArchiver(dirName string) (*FileArchiver, error)

NewFileArchiver creates a new file archive rooted at the passed specified directory.

TODO(roasbeef): use fs.FS instead?

TODO(roasbeef): option to memory map these instead? then don't need to lug around large blobs in user space as much

func (*FileArchiver) FetchProof

func (f *FileArchiver) FetchProof(ctx context.Context, id Locator) (Blob, error)

FetchProof fetches a proof for an asset uniquely identified by the passed ProofIdentifier.

If a proof cannot be found, then ErrProofNotFound should be returned.

NOTE: This implements the Archiver interface.

func (*FileArchiver) ImportProofs

func (f *FileArchiver) ImportProofs(ctx context.Context,
	proofs ...*AnnotatedProof) error

ImportProofs attempts to store fully populated proofs on disk. The previous outpoint of the first state transition will be used as the Genesis point. The final resting place of the asset will be used as the script key itself.

NOTE: This implements the Archiver interface.

type HashMailBox

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

HashMailBox is an implementation of the ProofMailbox interface backed by the hashmailrpc.HashMailClient.

func NewHashMailBox

func NewHashMailBox(serverAddr string) (*HashMailBox, error)

NewHashMailBox makes a new mailbox by dialing to the server specified by the address above.

func (*HashMailBox) AckProof

func (h *HashMailBox) AckProof(ctx context.Context, sid streamID) error

AckProof sends an ACK from the receiver to the sender that a proof has been recevied.

func (*HashMailBox) CleanUp

func (h *HashMailBox) CleanUp(ctx context.Context, sid streamID) error

CleanUp atempts to tear down the mailbox as specified by the passed sid.

func (*HashMailBox) Init

func (h *HashMailBox) Init(ctx context.Context, sid streamID) error

Init creates a mailbox given the specified stream ID.

func (*HashMailBox) ReadProof

func (h *HashMailBox) ReadProof(ctx context.Context,
	sid streamID) (Blob, error)

ReadProof reads a proof from the mailbox. This is a blocking method.

func (*HashMailBox) RecvAck

func (h *HashMailBox) RecvAck(ctx context.Context, sid streamID) error

RecvAck waits for the sender to receive the ack from the receiver.

func (*HashMailBox) WriteProof

func (h *HashMailBox) WriteProof(ctx context.Context, sid streamID,
	proof Blob) error

WriteProof writes the proof to the mailbox specified by the sid.

type HashMailCourier

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

HashMailCourier is an implementation of the Courier interfaces that

func NewHashMailCourier

func NewHashMailCourier(mailbox ProofMailbox) (*HashMailCourier, error)

NewHashMailCourier implements the Courier interface using the specified ProofMailbox. This instance of the Courier relies on the taro address itself as the parametrized address type.

func (*HashMailCourier) DeliverProof

func (h *HashMailCourier) DeliverProof(ctx context.Context, addr address.Taro,
	proof *AnnotatedProof) error

DeliverProof attempts to delivery a proof to the receiver, using the information in the Addr type.

TODO(roasbeef): other delivery context as type param?

func (*HashMailCourier) ReceiveProof

func (h *HashMailCourier) ReceiveProof(ctx context.Context, addr address.Taro,
	loc Locator) (*AnnotatedProof, error)

ReceiveProof attempts to obtain a proof as identified by the passed locator from the source encapsulated within the specified address.

type Locator

type Locator struct {
	// AssetID the asset ID of the proof to fetch. This is an optional field.
	AssetID *asset.ID

	// FamilyKey the family key of the asset to fetch. This is an optional
	// field.
	FamilyKey *btcec.PublicKey

	// ScriptKey specifies the script key of the asset to fetch/store. This
	// field MUST be specified.
	ScriptKey btcec.PublicKey
}

Locator is able to uniquely identify a proof in the extended Taro Universe by a combination of the: top-level asset ID, the family key, and also the script key.

type MintParams

type MintParams struct {
	// BaseProofParams houses the basic chain level parameters needed to
	// construct a proof.
	BaseProofParams

	// GenesisPoint is the genesis outpoint (first spent outpoint in the
	// transaction above).
	GenesisPoint wire.OutPoint
}

MintParams holds the set of chain level information needed to make a proof file for the set of assets minted in a batch.

type MockVerifier

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

func NewMockVerifier

func NewMockVerifier(t *testing.T) *MockVerifier

func (*MockVerifier) Verify

func (m *MockVerifier) Verify(_ context.Context, _ io.Reader) (*AssetSnapshot,
	error)

type MultiArchiver

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

MultiArchiver is an archive of archives. It contains several archives and attempts to use them either as a look-aside cache, or a write through cache for all incoming requests.

func NewMultiArchiver

func NewMultiArchiver(verifier Verifier, archiveTimeout time.Duration,
	backends ...Archiver) *MultiArchiver

NewMultiArchiver creates a new MultiArchiver based on the set of specified backends.

func (*MultiArchiver) FetchProof

func (m *MultiArchiver) FetchProof(ctx context.Context,
	loc Locator) (Blob, error)

FetchProof fetches a proof for an asset uniquely identified by the passed ProofIdentifier.

func (*MultiArchiver) ImportProofs

func (m *MultiArchiver) ImportProofs(ctx context.Context,
	proofs ...*AnnotatedProof) error

ImportProofs attempts to store fully populated proofs on disk. The previous outpoint of the first state transition will be used as the Genesis point. The final resting place of the asset will be used as the script key itself.

func (*MultiArchiver) RegisterSubscriber

func (m *MultiArchiver) RegisterSubscriber(
	receiver *chanutils.EventReceiver[Blob],
	deliverExisting bool, deliverFrom []*Locator) error

RegisterSubscriber adds a new subscriber for receiving events. The deliverExisting boolean indicates whether already existing items should be sent to the NewItemCreated channel when the subscription is started. An optional deliverFrom can be specified to indicate from which timestamp/index/ marker onward existing items should be delivered on startup. If deliverFrom is nil/zero/empty then all existing items will be delivered.

func (*MultiArchiver) RemoveSubscriber

func (m *MultiArchiver) RemoveSubscriber(
	subscriber *chanutils.EventReceiver[Blob]) error

RemoveSubscriber removes the given subscriber and also stops it from processing events.

type Proof

type Proof struct {
	// PrevOut is the previous on-chain outpoint of the asset.
	PrevOut wire.OutPoint

	// BlockHeader is the current block header committing to the on-chain
	// transaction attempting an asset state transition.
	BlockHeader wire.BlockHeader

	// AnchorTx is the on-chain transaction attempting the asset state
	// transition.
	AnchorTx wire.MsgTx

	// TxMerkleProof is the merkle proof for AnchorTx used to prove its
	// inclusion within BlockHeader.
	//
	// TODO(roasbeef): also store height+index information?
	TxMerkleProof TxMerkleProof

	// Asset is the resulting asset after its state transition.
	Asset asset.Asset

	// InclusionProof is the TaprootProof proving the new inclusion of the
	// resulting asset within AnchorTx.
	InclusionProof TaprootProof

	// ExclusionProofs is the set of TaprootProofs proving the exclusion of
	// the resulting asset from all other Taproot outputs within AnchorTx.
	ExclusionProofs []TaprootProof

	// SplitRootProof is an optional TaprootProof needed if this asset is
	// the result of a split. SplitRootProof proves inclusion of the root
	// asset of the split.
	SplitRootProof *TaprootProof

	// AdditionalInputs is a nested full proof for any additional inputs
	// found within the resulting asset.
	AdditionalInputs []File
}

Proof encodes all of the data necessary to prove a valid state transition for an asset has occurred within an on-chain transaction.

func CreateTransitionProof

func CreateTransitionProof(prevOut wire.OutPoint,
	params *TransitionParams) (*Proof, error)

CreateTransitionProof creates a proof for an asset transition, based on the last proof of the last asset state and the new asset in the params.

func (*Proof) Decode

func (p *Proof) Decode(r io.Reader) error

Decode decodes a Proof from `r`.

func (*Proof) DecodeRecords

func (p *Proof) DecodeRecords() []tlv.Record

DecodeRecords returns the set of known TLV records to decode a Proof.

func (*Proof) Encode

func (p *Proof) Encode(w io.Writer) error

Encode encodes a Proof into `w`.

func (*Proof) EncodeRecords

func (p *Proof) EncodeRecords() []tlv.Record

EncodeRecords returns the set of known TLV records to encode a Proof.

func (*Proof) UpdateTransitionProof

func (p *Proof) UpdateTransitionProof(params *BaseProofParams) error

UpdateTransitionProof computes a new transaction merkle proof from the given proof parameters, and updates a proof to be anchored at the given anchor transaction. This is needed to reflect confirmation of an anchor transaction.

func (*Proof) Verify

func (p *Proof) Verify(ctx context.Context,
	prev *AssetSnapshot) (*AssetSnapshot, error)

Verify verifies the proof by ensuring that:

  1. A transaction that spends the previous asset output has a valid merkle proof within a block in the chain.
  2. A valid inclusion proof for the resulting asset is included.
  3. A valid inclusion proof for the split root, if the resulting asset is a split asset.
  4. A set of valid exclusion proofs for the resulting asset are included.
  5. A set of asset inputs with valid witnesses are included that satisfy the resulting state transition.

type ProofMailbox

type ProofMailbox interface {
	// Init creates a mailbox given the specified stream ID.
	Init(ctx context.Context, sid streamID) error

	// WriteProof writes the proof to the mailbox specified by the sid.
	WriteProof(ctx context.Context, sid streamID, proof Blob) error

	// ReadProof reads a proof from the mailbox. This is a blocking method.
	ReadProof(ctx context.Context, sid streamID) (Blob, error)

	// AckProof sends an ACK from the receiver to the sender that a proof
	// has been recevied.
	AckProof(ctx context.Context, sid streamID) error

	// RecvAck waits for the sender to receive the ack from the receiver.
	RecvAck(ctx context.Context, sid streamID) error

	// CleanUp atempts to tear down the mailbox as specified by the passed
	// sid.
	CleanUp(ctx context.Context, sid streamID) error
}

ProofMailbox represents an abstract store-and-forward maillbox that can be used to send/receive proofs.

type TaprootProof

type TaprootProof struct {
	// OutputIndex is the index of the output for which the proof applies.
	OutputIndex uint32

	// InternalKey is the internal key of the taproot output at OutputIndex.
	InternalKey *btcec.PublicKey

	// CommitmentProof represents a commitment proof for an asset, proving
	// inclusion or exclusion of an asset within a Taro commitment.
	CommitmentProof *CommitmentProof

	// TapscriptProof represents a taproot control block to prove that a
	// taproot output is not committing to a Taro commitment.
	//
	// NOTE: This field will be set only if the output does NOT contain a
	// valid Taro commitment.
	TapscriptProof *TapscriptProof
}

TaprootProof represents a proof that reveals the partial contents to a tapscript tree within a taproot output. It can prove whether an asset is being included/excluded from a Taro commitment through a CommitmentProof, or that no Taro commitment exists at all through a TapscriptProof.

func (*TaprootProof) Decode

func (p *TaprootProof) Decode(r io.Reader) error

func (*TaprootProof) DecodeRecords

func (p *TaprootProof) DecodeRecords() []tlv.Record

func (TaprootProof) DeriveByAssetExclusion

func (p TaprootProof) DeriveByAssetExclusion(assetCommitmentKey,
	taroCommitmentKey [32]byte) (*btcec.PublicKey, error)

DeriveByAssetExclusion derives the possible taproot keys backing a Taro commitment by interpreting the TaprootProof as an asset exclusion proof. Asset exclusion proofs can take two forms: one where an asset proof proves that the asset no longer exists within its AssetCommitment, and another where the AssetCommitment corresponding to the excluded asset no longer exists within the TaroCommitment.

There are at most two possible keys to try if each leaf preimage matches the length of a branch preimage. However, based on the type of the sibling pre-image we'll derive just a single version of it.

func (TaprootProof) DeriveByAssetInclusion

func (p TaprootProof) DeriveByAssetInclusion(
	asset *asset.Asset) (*btcec.PublicKey, *commitment.TaroCommitment,
	error)

DeriveByAssetInclusion derives the unique taproot output key backing a Taro commitment by interpreting the TaprootProof as an asset inclusion proof.

There are at most two _possible_ keys that exist if each leaf preimage matches the length of a branch preimage. However, using the annotated type information we only need to derive a single key.

func (TaprootProof) DeriveByTapscriptProof

func (p TaprootProof) DeriveByTapscriptProof() (*btcec.PublicKey, error)

DeriveByTapscriptProof derives the possible taproot keys from a TapscriptProof backing a taproot output that does not include a Taro commitment.

NOTE: There are at most two possible keys to try if each leaf preimage matches the length of a branch preimage. However, we can derive only the one specified in the contained proof.

func (TaprootProof) Encode

func (p TaprootProof) Encode(w io.Writer) error

func (TaprootProof) EncodeRecords

func (p TaprootProof) EncodeRecords() []tlv.Record

type TapscriptPreimage

type TapscriptPreimage struct {
	// SiblingPreimage is the pre-image itself. This will be either 32 or
	// 64 bytes.
	SiblingPreimage []byte

	// SiblingType is the type of the pre-image.
	SiblingType TapscriptPreimageType
}

TapscriptPreimage wraps a pre-image byte slice with a type byte that self identifies what type of pre-image it is.

func (*TapscriptPreimage) IsEmpty

func (t *TapscriptPreimage) IsEmpty() bool

IsEmpty returns true if the sibling pre-image is empty.

type TapscriptPreimageType

type TapscriptPreimageType uint8

TapscriptPreimageType denotes the type of tapscript sibling preimage.

const (
	// LeafPreimage is a pre-image that's a leaf script.
	LeafPreimage TapscriptPreimageType = 0

	// BranchPreimage is a pre-image that's a branch, so it's actually
	// 64-bytes of two child pre-images.
	BranchPreimage TapscriptPreimageType = 1
)

func (TapscriptPreimageType) String

func (t TapscriptPreimageType) String() string

String returns a human-readable string for the TapscriptPreimageType.

type TapscriptProof

type TapscriptProof struct {
	// TapPreimage1 is the preimage for a TapNode at depth 0 or 1.
	TapPreimage1 *TapscriptPreimage

	// TapPreimage2, if specified, is the pair preimage for TapPreimage1 at
	// depth 1.
	TapPreimage2 *TapscriptPreimage

	// BIP86 indicates this is a normal BIP-86 wallet output (likely a
	// change output) that does not commit to any script or Taro root.
	BIP86 bool
}

TapscriptProof represents a proof of a Taproot output not including a Taro commitment. Taro commitments must exist at a leaf with depth 0 or 1, so we can guarantee that a Taro commitment doesn't exist by revealing the preimage of one node at depth 0 or two nodes at depth 1.

TODO(roasbeef): make *this* into the control block proof?

func (*TapscriptProof) Decode

func (p *TapscriptProof) Decode(r io.Reader) error

Decode attempts to decode the TapscriptProof to the passed io.Reader.

func (*TapscriptProof) DecodeRecords

func (p *TapscriptProof) DecodeRecords() []tlv.Record

DecodeRecords returns the decoding records for TapscriptProof.

func (TapscriptProof) DeriveTaprootKeys

func (p TapscriptProof) DeriveTaprootKeys(internalKey *btcec.PublicKey) (
	*btcec.PublicKey, error)

DeriveTaprootKeys derives the expected taproot key from a TapsscriptProof backing a taproot output that does not include a Taro commitment.

There are at most two possible keys to try if each leaf preimage matches the length of a branch preimage. However, based on the annotated type information, we only need to derive a single expected key.

func (TapscriptProof) Encode

func (p TapscriptProof) Encode(w io.Writer) error

Encode attempts to encode the TapscriptProof to the passed io.Writer.

func (TapscriptProof) EncodeRecords

func (p TapscriptProof) EncodeRecords() []tlv.Record

EncodeRecords returns the encoding records for TapscriptProof.

type TransitionParams

type TransitionParams struct {
	// BaseProofParams houses the basic chain level parameters needed to
	// construct a proof.
	//
	// TODO(roasbeef): assumes only 2 outputs in the TX (minting output and
	// change), need more information to make exclusion proofs for the
	// others.
	BaseProofParams

	// NewAsset is the new asset created by the asset transition.
	NewAsset *asset.Asset

	// RootOutputIndex is the index of the output that commits to the split
	// root asset, if present.
	RootOutputIndex uint32

	// RootInternalKey is the internal key of the output at RootOutputIndex.
	RootInternalKey *btcec.PublicKey

	// RootTaroRoot is the commitment root that commitments to the inclusion
	// of the root split asset at the RootOutputIndex.
	RootTaroTree *commitment.TaroCommitment
}

TransitionParams holds the set of chain level information needed to append a proof to an existing file for the given asset state transition.

type TxMerkleProof

type TxMerkleProof struct {
	// Nodes is the list of nodes to hash along with the transaction being
	// proved to arrive at the block's merkle root.
	Nodes []chainhash.Hash

	// Bits indicates the direction for each node found in Nodes above. A
	// 0 bit indicates a left direction or a right direction otherwise.
	Bits []bool
}

TxMerkleProof represents a simplified version of BIP-37 transaction merkle proofs for a single transaction.

func NewTxMerkleProof

func NewTxMerkleProof(txs []*wire.MsgTx, txIdx int) (*TxMerkleProof, error)

NewTxMerkleProof computes the merkle proof for a specific transaction found within a block's set of transactions.

func (*TxMerkleProof) Decode

func (p *TxMerkleProof) Decode(r io.Reader) error

Decode decodes a TxMerkleProof from `r`.

func (TxMerkleProof) Encode

func (p TxMerkleProof) Encode(w io.Writer) error

Encode encodes a TxMerkleProof into `w`.

func (TxMerkleProof) Verify

func (p TxMerkleProof) Verify(tx *wire.MsgTx, merkleRoot chainhash.Hash) bool

Verify verifies a merkle proof for `tx` by ensuring the end result matches the expected `merkleRoot`.

type Verifier

type Verifier interface {
	// Verify takes the passed serialized proof file, and returns a nil
	// error if the proof file is valid. A valid file should return an
	// AssetSnapshot of the final state transition of the file.
	Verify(c context.Context, blobReader io.Reader) (*AssetSnapshot, error)
}

Verifier abstracts away from the task of verifying a proof file blob.

type Version

type Version uint32

Version denotes the versioning scheme for proof files.

const (
	// V0 is the first version of the proof file.
	V0 Version = 0
)

Jump to

Keyboard shortcuts

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