proof

package
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: Jul 25, 2024 License: MIT Imports: 54 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// TaprootAssetsFileEnding is the main file suffix for the Taproot Asset
	// proof files stored on disk, without the dot.
	TaprootAssetsFileEnding = "assetproof"

	// TaprootAssetsFileSuffix is the main file suffix for the Taproot Asset
	// proof files stored on disk, including the dot.
	TaprootAssetsFileSuffix = "." + TaprootAssetsFileEnding

	// ProofDirName is the name of the directory we'll use to store our
	// proofs.
	ProofDirName = "proofs"
)
View Source
const (
	// DisabledCourier is the default courier type that is used when no
	// courier is specified.
	DisabledCourier CourierType = "disabled_courier"

	// HashmailCourierType is a courier that uses the hashmail protocol to
	// deliver proofs.
	HashmailCourierType = "hashmail"

	// UniverseRpcCourierType is a courier that uses the daemon universe RPC
	// endpoints to deliver proofs.
	UniverseRpcCourierType = "universerpc"
)
View Source
const (
	// V0 is the first version of the proof file.
	V0 Version = 0

	// FileMaxNumProofs is the maximum number of proofs we expect/allow to
	// be encoded within a single proof file. Given that there can only be
	// one transfer per block, this value would be enough to transfer an
	// asset every 10 minutes for 8 years straight. This limitation might be
	// lifted at some point when proofs can be compressed into a single
	// zero-knowledge proof.
	FileMaxNumProofs = 420000

	// FileMaxProofSizeBytes is the maximum size of a single proof in a
	// proof file. The maximum size of a meta reveal is 1 MiB, so this value
	// would cap the number of additional inputs within a proof to roughly
	// 128 of assets with such large meta data.
	FileMaxProofSizeBytes = 128 * MetaDataMaxSizeBytes

	// FileMaxSizeBytes is the maximum size of a single proof file. This is
	// not just FileMaxNumProofs * FileMaxProofSizeBytes as only the minting
	// proof can commit to a large chunk of meta data. The other proofs are
	// much smaller, assuming they don't all have additional inputs. But we
	// must cap this value somewhere to avoid OOM attacks.
	FileMaxSizeBytes = 500 * 1024 * 1024
)
View Source
const (
	// MetaDataMaxSizeBytes is the maximum length of the meta data. We limit
	// this to 1MiB for now. This should be of sufficient size to commit to
	// any JSON data or even medium resolution images. If there is need to
	// commit to even more data, it would make sense to instead commit to an
	// annotated hash of the data instead. The reason for the limit is that
	// the meta data will be part of the genesis proof, which is stored in
	// the universe and needs to be validated by all senders and receivers
	// of the asset.
	MetaDataMaxSizeBytes = 1024 * 1024

	// MetadataDecDisplayKey is the JSON key used in the metadata field of a
	// minted asset to express the decimal display of the minted asset.
	MetadataDecDisplayKey = "decimal_display"

	// maxDecDisplay is the maximum value of decimal display that a user can
	// define when minting assets. Since the uint64 max value has 19 decimal
	// places we will allow for a max of 12 decimal places.
	MaxDecDisplay = uint32(12)
)
View Source
const (
	// PrefixMagicBytesLength is the length of the magic bytes that are
	// prefixed to individual proofs or proof files.
	PrefixMagicBytesLength = 4

	// MaxNumTaprootProofs is the maximum number of Taproot proofs there can
	// be in a proof. This limit represents the maximum block size in vBytes
	// divided by the size of a single P2TR output and is therefore only a
	// theoretical limit that can never be reached in practice.
	MaxNumTaprootProofs uint64 = blockchain.MaxBlockBaseSize /
		input.P2TRSize

	// MaxTaprootProofSizeBytes is the maximum size of a single Taproot
	// proof. A Taproot proof can contain a commitment proof which at
	// maximum can contain two MS-SMT proofs that max out at around 10k
	// bytes each (in the worst case).
	MaxTaprootProofSizeBytes = tlv.MaxRecordSize

	// MerkleProofMaxNodes is the maximum number of nodes a merkle proof can
	// contain. This is log2(max_num_txs_in_block) + 1, where max number of
	// transactions in a block is limited to be 17k (theoretical smallest
	// transaction that can be serialized, which is 1 input + 1 output +
	// transaction overhead = 59 bytes, then 1MB block size divided by that
	// and rounded up).
	MerkleProofMaxNodes = 15
)
View Source
const (
	VersionType          tlv.Type = 0
	PrevOutType          tlv.Type = 2
	BlockHeaderType      tlv.Type = 4
	AnchorTxType         tlv.Type = 6
	TxMerkleProofType    tlv.Type = 8
	AssetLeafType        tlv.Type = 10
	InclusionProofType   tlv.Type = 12
	ExclusionProofsType  tlv.Type = 13
	SplitRootProofType   tlv.Type = 15
	MetaRevealType       tlv.Type = 17
	AdditionalInputsType tlv.Type = 19
	ChallengeWitnessType tlv.Type = 21
	BlockHeightType      tlv.Type = 22
	GenesisRevealType    tlv.Type = 23
	GroupKeyRevealType   tlv.Type = 25

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

	// CommitmentProofTapSiblingPreimageType is the type of the TLV record
	// for the CommitmentProof's SiblingPreimage field. It continues the
	// count from where commitment.ProofTaprootAssetProofType left off.
	CommitmentProofTapSiblingPreimageType tlv.Type = 5

	TapscriptProofTapPreimage1 tlv.Type = 1
	TapscriptProofTapPreimage2 tlv.Type = 3
	TapscriptProofBip86        tlv.Type = 4

	MetaRevealEncodingType tlv.Type = 0
	MetaRevealDataType     tlv.Type = 2
)
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")

	// ErrOutPointMissing is returned when a specified locator does not
	// contain an outpoint. The outpoint is required when storing a proof.
	ErrOutPointMissing = fmt.Errorf("outpoint missing in key locator")

	// ErrMultipleProofs is returned if looking up a proof with only the
	// asset ID and script key results in multiple proofs being found.
	ErrMultipleProofs = fmt.Errorf(
		"multiple proofs found with asset ID and script key, specify " +
			"outpoint to disambiguate",
	)

	// OutPointFileNamePattern is the regular expression we use to find out
	// if a proof file on disk already has the new naming scheme. The first
	// number (66) is the number of hex characters in the compressed script
	// key, the second number (32) is the number of hex characters in the
	// truncated outpoint txid (16 bytes of the txid). The last part is the
	// variable length outpoint index (at least one digit).
	OutPointFileNamePattern = regexp.MustCompile(
		`^[0-9a-f]{66}-[0-9a-f]{32}-[0-9]+\.` +
			TaprootAssetsFileEnding + "$",
	)
)
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")

	// ErrUnknownVersion is returned when a proof with an unknown proof
	// version is being used.
	ErrUnknownVersion = errors.New("proof: unknown proof version")

	// ErrProofFileInvalid is the error that's returned when a proof file is
	// invalid.
	ErrProofFileInvalid = errors.New("proof file is invalid")
)
View Source
var (
	// ErrMetaDataMissing signals that the meta data is missing.
	ErrMetaDataMissing = errors.New("meta data missing")

	// ErrMetaDataTooLarge signals that the meta data is too large.
	ErrMetaDataTooLarge = errors.New("meta data too large")

	// ErrMetaTypeNegative signals that the given value is an invalid meta
	// type because it is negative.
	ErrMetaTypeNegative = errors.New("meta type cannot be negative")

	// ErrMetaTypeTooLarge signals that the given value is an invalid meta
	// type because it is too large.
	ErrMetaTypeTooLarge = errors.New("meta type above limit of 255")

	// ErrInvalidJSON signals that the meta data is not a valid JSON.
	ErrInvalidJSON = errors.New("invalid JSON")

	// ErrNotJSON is returned if the metadata is expected to be JSON but
	// is another meta type.
	ErrNotJSON = errors.New("metadata is not JSON")

	// ErrDecDisplayInvalid is returned if the decimal display value is
	// invalid.
	ErrDecDisplayInvalid = errors.New("invalid decimal display")

	// ErrDecDisplayTooLarge is returned if the decimal display value
	// exceeds the current limit.
	ErrDecDisplayTooLarge = errors.New("decimal display too large")

	// ErrDecDisplayInvalidType is returned if the value in a JSON object
	// assigned to the decimal display key is not a uint32.
	ErrDecDisplayInvalidType = errors.New("decimal display JSON field is " +
		"not a number")

	// ErrDecDisplayMissing is returned if the decimal display key is
	// not present in a JSON object.
	ErrDecDisplayMissing = errors.New("decimal display field missing")
)
View Source
var (
	// 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")

	// ErrNonGenesisAssetWithMetaReveal is an error returned if an asset
	// proof has a meta reveal but isn't itself a genesis asset.
	ErrNonGenesisAssetWithMetaReveal = errors.New("non genesis asset has " +
		"meta reveal")

	// ErrNonGenesisAssetWithGenesisReveal is an error returned if an asset
	// proof for a non-genesis asset contains a genesis reveal.
	ErrNonGenesisAssetWithGenesisReveal = errors.New("non genesis asset " +
		"has genesis reveal")

	// ErrGenesisRevealRequired is an error returned if an asset proof for a
	// genesis asset is missing a genesis reveal.
	ErrGenesisRevealRequired = errors.New("genesis reveal required")

	// ErrGenesisRevealAssetIDMismatch is an error returned if an asset
	// proof for a genesis asset has a genesis reveal that is inconsistent
	// with the asset ID.
	ErrGenesisRevealAssetIDMismatch = errors.New("genesis reveal asset " +
		"ID mismatch")

	// ErrGenesisRevealPrevOutMismatch is an error returned if an asset
	// proof for a genesis asset has a genesis reveal where the prev out
	// doesn't match the proof TLV field.
	ErrGenesisRevealPrevOutMismatch = errors.New("genesis reveal prev " +
		"out mismatch")

	// ErrGenesisRevealMetaRevealRequired is an error returned if an asset
	// proof for a genesis asset has a non-zero meta hash, but doesn't have
	// a meta reveal.
	ErrGenesisRevealMetaRevealRequired = errors.New("genesis meta reveal " +
		"required")

	// ErrGenesisRevealMetaHashMismatch is an error returned if an asset
	// proof for a genesis asset has a genesis reveal where the meta hash
	// doesn't match the proof TLV field.
	ErrGenesisRevealMetaHashMismatch = errors.New("genesis reveal meta " +
		"hash mismatch")

	// ErrGenesisRevealOutputIndexMismatch is an error returned if an asset
	// proof for a genesis asset has a genesis reveal where the output index
	// doesn't match the proof TLV field.
	ErrGenesisRevealOutputIndexMismatch = errors.New("genesis reveal " +
		"output index mismatch")

	// ErrNonGenesisAssetWithGroupKeyReveal is an error returned if an asset
	// proof for a non-genesis asset contains a group key reveal.
	ErrNonGenesisAssetWithGroupKeyReveal = errors.New("non genesis asset " +
		"has group key reveal")

	// ErrGroupKeyRevealMismatch is an error returned if an asset proof for
	// a genesis asset has a group key reveal that doesn't match the group
	// key.
	ErrGroupKeyRevealMismatch = errors.New("group key reveal doesn't " +
		"match group key")

	// ErrGroupKeyRevealRequired is an error returned if an asset proof for
	// a genesis asset with a group key is missing a group key reveal.
	ErrGroupKeyRevealRequired = errors.New("group key reveal required")

	// ErrGroupKeyRequired is an error returned if an asset proof for a
	// genesis asset is missing a group key when it should have one.
	ErrGroupKeyRequired = errors.New("group key required")

	// ErrGroupKeyUnknown is an error returned if an asset proof for a
	// group asset references an asset group that has not been previously
	// verified. This can apply to genesis proofs for reissaunces into a
	// group, and any further transfer of a grouped asset.
	ErrGroupKeyUnknown = errors.New("group key not known")

	// ErrProofInvalid is the error that's returned when a proof file is
	// invalid.
	ErrProofInvalid = errors.New("proof is invalid")

	// RegtestTestVectorName is the name of the test vector file that is
	// generated/updated by an actual integration test run on regtest. It is
	// exported here, so we can use it in the integration tests.
	RegtestTestVectorName = "proof_tlv_encoding_regtest.json"

	// RegtestProofFileName is the name of the file that is generated/
	// updated by an actual integration test run on regtest. It is exported
	// here, so we can use it in the integration tests.
	RegtestProofFileName = "proof-file.hex"

	// RegtestProofName is the name of the file that is generated/updated by
	// an actual integration test run on regtest. It is exported here, so we
	// can use it in the integration tests.
	RegtestProofName = "proof.hex"

	// RegtestOwnershipProofName is the name of the ownership proof that is
	// generated/updated by an actual integration test run on regtest. It is
	// exported here, so we can use it in the integration tests.
	RegtestOwnershipProofName = "ownership-proof.hex"
)
View Source
var (
	// PrefixMagicBytes are the magic bytes that are prefixed to an
	// individual transition or mint proof when encoding it. This is the
	// ASCII encoding of the string "TAPP" (Taproot Assets Protocol Proof)
	// in hex.
	PrefixMagicBytes = [PrefixMagicBytesLength]byte{0x54, 0x41, 0x50, 0x50}

	// FilePrefixMagicBytes are the magic bytes that are prefixed to a proof
	// file when encoding it. This is the ASCII encoding of the string
	// "TAPF" (Taproot Assets Protocol File) in hex.
	FilePrefixMagicBytes = [PrefixMagicBytesLength]byte{
		0x54, 0x41, 0x50, 0x46,
	}
)
View Source
var (
	// ErrInvalidCommitmentProof is an error returned upon attempting to
	// prove a malformed CommitmentProof.
	ErrInvalidCommitmentProof = errors.New(
		"invalid Taproot Asset commitment proof",
	)
)
View Source
var MockChainLookup = &mockChainLookup{}

MockChainLookup is a mock for the ChainLookup interface.

Functions

func AddExclusionProofs

func AddExclusionProofs(baseProof *BaseProofParams, finalTx *wire.MsgTx,
	finalTxPacketOutputs []psbt.POutput, isAnchor func(uint32) bool) error

AddExclusionProofs adds exclusion proofs to the base proof for each P2TR output in the given PSBT that isn't an anchor output itself. To determine which output is the anchor output, the passed isAnchor function should return true for the output index that houses the anchor TX.

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,
	headerVerifier HeaderVerifier, merkleVerifier MerkleVerifier,
	groupVerifier GroupVerifier, chainLookup asset.ChainLookup) (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 AssetLeafRecord

func AssetLeafRecord(a *asset.Asset) 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 BlockHeightRecord added in v0.2.3

func BlockHeightRecord(height *uint32) 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 ChallengeWitnessRecord

func ChallengeWitnessRecord(challengeWitness *wire.TxWitness) tlv.Record

func CheckMaxFileSize added in v0.3.0

func CheckMaxFileSize(blob Blob) error

CheckMaxFileSize checks that the given blob is not larger than the maximum file size.

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 **commitment.TapscriptPreimage) tlv.Record

func CreateOwnershipProofAsset added in v0.4.0

func CreateOwnershipProofAsset(
	ownedAsset *asset.Asset) (asset.PrevID, *asset.Asset)

CreateOwnershipProofAsset creates a virtual asset that can be used to prove ownership of an asset. The virtual asset is created by spending the full asset into a NUMS key.

func DecodeMetaJSON added in v0.4.0

func DecodeMetaJSON(jBytes []byte) (map[string]interface{}, error)

DecodeMetaJSON decodes bytes as a JSON object, after checking that the bytes could be valid metadata.

func Decoder added in v0.4.0

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

Decoder decodes a proof from the given reader.

func DefaultMerkleVerifier added in v0.4.0

func DefaultMerkleVerifier(tx *wire.MsgTx, proof *TxMerkleProof,
	merkleRoot [32]byte) error

DefaultMerkleVerifier is a default implementation of the MerkleVerifier callback function. It verifies the merkle proof by checking that the transaction hash is included in the merkle tree with the given merkle root.

func DisableLog

func DisableLog()

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

func Encode added in v0.4.0

func Encode(p *Proof) ([]byte, error)

Encode encodes a proof into a byte slice.

func EncodeFile added in v0.4.0

func EncodeFile(f *File) ([]byte, error)

EncodeFile encodes a proof file into a byte slice.

func EncodeMetaJSON added in v0.4.0

func EncodeMetaJSON(jMeta map[string]interface{}) ([]byte, error)

EncodeMetaJSON encodes a JSON object as bytes and checks that the resulting bytes are below the maximum metadata size.

func Encoder added in v0.4.0

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

Encoder encodes a proof to the given writer.

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 ExtractTaprootKeyFromScript

func ExtractTaprootKeyFromScript(pkScript []byte) (*btcec.PublicKey, error)

ExtractTaprootKeyFromScript attempts to extract a Taproot tweaked key from the given output script.

func GenesisRevealDecoder added in v0.3.0

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

func GenesisRevealEncoder added in v0.3.0

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

func GenesisRevealRecord added in v0.3.0

func GenesisRevealRecord(genesis **asset.Genesis) tlv.Record

func GroupKeyRevealDecoder added in v0.3.0

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

func GroupKeyRevealEncoder added in v0.3.0

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

func GroupKeyRevealRecord added in v0.3.0

func GroupKeyRevealRecord(reveal **asset.GroupKeyReveal) tlv.Record

func InclusionProofRecord

func InclusionProofRecord(proof *TaprootProof) tlv.Record

func IsProofFile added in v0.3.0

func IsProofFile(blob Blob) bool

IsProofFile returns true if the given blob is an encoded proof file.

func IsSingleProof added in v0.3.0

func IsSingleProof(blob Blob) bool

IsSingleProof returns true if the given blob is an encoded individual mint/transition proof.

func IsValidDecDisplay added in v0.4.0

func IsValidDecDisplay(decDisplay uint32) error

IsValidDecDisplay checks if the decimal display value is below the maximum.

func IsValidMetaSize added in v0.4.0

func IsValidMetaSize(mBytes []byte, maxSize int) error

IsValidMetaSize checks if the passed data is non-empty and below the maximum size.

func MetaRevealDataRecord

func MetaRevealDataRecord(data *[]byte) tlv.Record

func MetaRevealDecoder

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

func MetaRevealEncoder

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

func MetaRevealRecord

func MetaRevealRecord(reveal **MetaReveal) tlv.Record

func MetaRevealTypeRecord

func MetaRevealTypeRecord(metaType *MetaType) tlv.Record

func MetaTypeDecoder

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

func MetaTypeEncoder

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

func MockGroupAnchorVerifier added in v0.3.0

func MockGroupAnchorVerifier(gen *asset.Genesis,
	groupKey *asset.GroupKey) error

MockGroupAnchorVerifier is a mock verifier which approves of all group anchor geneses.

Group anchor verification usually involves accurately computing a group key, and many unit tests are not focused on group key functionality but still use functions that require a group anchor verifier. This function is used in those cases.

func MockGroupVerifier added in v0.3.0

func MockGroupVerifier(groupKey *btcec.PublicKey) error

MockGroupVerifier is a mock verifier which approves of all group keys.

Group key verification usually involves having imported the group anchor before verification, and many unit tests are not focused on group key functionality but still use functions that require a group verifier. This function is used in those cases.

func MockHeaderVerifier

func MockHeaderVerifier(header wire.BlockHeader, height uint32) error

MockHeaderVerifier is a mock verifier which approves of all block headers.

Header verification usually involves cross-referencing with chain data. Chain data is not available in unit tests. This function is useful for unit tests which are not primarily concerned with block header verification.

func MockMerkleVerifier added in v0.4.0

func MockMerkleVerifier(*wire.MsgTx, *TxMerkleProof, [32]byte) error

MockMerkleVerifier is a mock verifier which approves of all merkle proofs.

func ParseCourierAddress added in v0.3.3

func ParseCourierAddress(addr string) (*url.URL, error)

ParseCourierAddress attempts to parse the given string as a proof courier address, validates that all required fields are present and ensures the protocol is one of the supported protocols.

func PrevOutRecord

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

func ReplaceProofInBlob added in v0.3.0

func ReplaceProofInBlob(ctx context.Context, p *Proof, archive Archiver,
	headerVerifier HeaderVerifier, merkleVerifier MerkleVerifier,
	groupVerifier GroupVerifier,
	chainLookupGen ChainLookupGenerator) error

ReplaceProofInBlob attempts to replace a proof in all proof files we have for assets of the same ID. This is useful when we want to update the proof with a new one after a re-org.

func SparseDecode added in v0.3.1

func SparseDecode(r io.Reader, records ...tlv.Record) error

SparseDecode can be used to decode a proof from a reader without decoding and parsing the entire thing. This handles ignoring the magic bytes, and will decode directly into the target records.

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 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 **commitment.TapscriptPreimage) tlv.Record

func TapscriptProofTapPreimage2Record

func TapscriptProofTapPreimage2Record(
	preimage **commitment.TapscriptPreimage) tlv.Record

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.

func ValidateCourierAddress added in v0.3.3

func ValidateCourierAddress(addr *url.URL) error

ValidateCourierAddress validates that all required fields are present and ensures the protocol is one of the supported protocols.

func VersionDecoder added in v0.3.0

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

func VersionEncoder added in v0.3.0

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

func VersionRecord added in v0.3.0

func VersionRecord(version *TransitionVersion) tlv.Record

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. If multiple proofs exist for the given fields of the
	// locator then ErrMultipleProofs should be returned to indicate more
	// specific fields need to be set in the Locator (e.g. the OutPoint).
	FetchProof(ctx context.Context, id Locator) (Blob, error)

	// FetchIssuanceProof fetches the issuance proof for an asset, given the
	// anchor point of the issuance (NOT the genesis point for the asset).
	//
	// If a proof cannot be found, then ErrProofNotFound should be returned.
	FetchIssuanceProof(ctx context.Context, id asset.ID,
		anchorOutpoint wire.OutPoint) (Blob, error)

	// HasProof returns true if the proof for the given locator exists. This
	// is intended to be a performance optimized lookup compared to fetching
	// a proof and checking for ErrProofNotFound.
	HasProof(ctx context.Context, id Locator) (bool, error)

	// FetchProofs fetches all proofs for assets uniquely identified by the
	// passed asset ID.
	FetchProofs(ctx context.Context, id asset.ID) ([]*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. If replace is specified, we expect a proof to
	// already be present, and we just update (replace) it with the new
	// proof.
	ImportProofs(ctx context.Context, headerVerifier HeaderVerifier,
		merkleVerifier MerkleVerifier, groupVerifier GroupVerifier,
		chainLookupGen ChainLookupGenerator, replace bool,
		proofs ...*AnnotatedProof) error
}

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

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.

type AssetProofs added in v0.3.0

type AssetProofs map[asset.SerializedKey]*Proof

AssetProofs is a data structure used to pass around the native proof suffix structures for a set of assets which may have been created in the same batch transaction. This maps the script key of the asset to the proof suffix.

func NewMintingBlobs

func NewMintingBlobs(params *MintParams, headerVerifier HeaderVerifier,
	merkleVerifier MerkleVerifier, groupVerifier GroupVerifier,
	anchorVerifier GroupAnchorVerifier, chainLookupGen ChainLookupGenerator,
	blobOpts ...MintingBlobOption) (AssetProofs, 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 Taproot Asset 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 Taproot Asset commitment root committed to using
	// the above internal key in the Anchor transaction.
	ScriptRoot *commitment.TapCommitment

	// TapscriptSibling is the pre-image to the tapscript hash of the
	// sibling to the Taproot Asset root. If this is nil then it means the
	// Taproot Asset root is the only tapscript leaf in the tree.
	TapscriptSibling *commitment.TapscriptPreimage

	// 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

	// MetaReveal is the pre-image to the meta data hash of the above
	// asset. This is only populated if the asset is a genesis asset, and
	// the proof had a valid meta reveal.
	MetaReveal *MetaReveal
}

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 BackoffCfg

type BackoffCfg struct {
	// SkipInitDelay is a flag that indicates whether we should skip the
	// initial delay before attempting to deliver the proof to the receiver
	// or receiving from the sender.
	SkipInitDelay bool `` /* 142-byte string literal not displayed */

	// BackoffResetWait is the amount of time we'll wait before
	// resetting the backoff counter to its initial state.
	BackoffResetWait time.Duration `long:"backoffresetwait" description:"The amount of time to wait before resetting the backoff counter."`

	// NumTries is the number of times we'll try to deliver the proof to the
	// receiver before the BackoffResetWait delay is enforced.
	NumTries int `long:"numtries" description:"The number of proof delivery attempts before the backoff counter is reset."`

	// InitialBackoff is the initial backoff time we'll use to wait before
	// retrying to deliver the proof to the receiver.
	InitialBackoff time.Duration `long:"initialbackoff" description:"The initial backoff time to wait before retrying to deliver the proof to the receiver."`

	// MaxBackoff is the maximum backoff time we'll use to wait before
	// retrying to deliver the proof to the receiver.
	MaxBackoff time.Duration `long:"maxbackoff" description:"The maximum backoff time to wait before retrying to deliver the proof to the receiver."`
}

BackoffCfg configures the behaviour of the proof delivery backoff procedure.

type BackoffExecError

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

BackoffExecError is an error returned when the backoff execution fails. This error wraps the underlying error returned by the execution function. It allows the porter to determine whether the state machine should be halted or not.

func (*BackoffExecError) Error

func (e *BackoffExecError) Error() string

type BackoffHandler added in v0.3.1

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

BackoffHandler is a handler for the backoff procedure.

func NewBackoffHandler added in v0.3.1

func NewBackoffHandler(cfg *BackoffCfg,
	deliveryLog TransferLog) *BackoffHandler

NewBackoffHandler creates a new backoff procedure handle.

func (*BackoffHandler) Exec added in v0.3.1

func (b *BackoffHandler) Exec(ctx context.Context, proofLocator Locator,
	transferType TransferType, transferFunc func() error,
	subscriberEvent func(fn.Event)) error

Exec attempts to execute the given proof transfer function using a repeating backoff time delayed strategy. The backoff strategy is used to ensure that we don't spam the courier service with proof transfer attempts.

type BackoffWaitEvent added in v0.3.1

type BackoffWaitEvent struct {

	// Backoff is the current backoff wait duration.
	Backoff time.Duration

	// TriesCounter is the number of tries we've made so far during the
	// course of the current Backoff procedure to deliver the proof to the
	// receiver.
	TriesCounter int64

	// TransferType is the type of proof transfer attempt. The transfer is
	// either a proof delivery to the transfer counterparty or receiving a
	// proof from the transfer counterparty. Note that the transfer
	// counterparty is usually the proof courier service.
	TransferType TransferType
	// contains filtered or unexported fields
}

BackoffWaitEvent is an event that is sent to a subscriber each time we wait via the Backoff procedure before retrying to deliver a proof to the receiver.

func NewBackoffWaitEvent added in v0.3.1

func NewBackoffWaitEvent(
	backoff time.Duration, triesCounter int64,
	transferType TransferType) *BackoffWaitEvent

NewBackoffWaitEvent creates a new BackoffWaitEvent.

func (*BackoffWaitEvent) Timestamp added in v0.3.1

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

Timestamp returns the timestamp of the event.

type BaseProofParams

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

	// BlockHeight is the height of the block that mined the transaction
	// which minted the specified assets.
	BlockHeight uint32

	// 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

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

	// TapscriptSibling is the pre-image to the tapscript hash of the
	// sibling to the Taproot Asset root. If this is nil then it means the
	// Taproot Asset root is the only tapscript leaf in the tree.
	TapscriptSibling *commitment.TapscriptPreimage

	// 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.

func (*BaseProofParams) HaveExclusionProof

func (p *BaseProofParams) HaveExclusionProof(anchorOutputIndex uint32) bool

HaveExclusionProof returns true if the set of exclusion proofs already contains a proof for the given anchor output index.

func (*BaseProofParams) HaveInclusionProof added in v0.4.0

func (p *BaseProofParams) HaveInclusionProof(anchorOutputIndex uint32) bool

HaveInclusionProof returns true if the inclusion proof is for the given anchor output index.

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,
	headerVerifier HeaderVerifier, merkleVerifier MerkleVerifier,
	groupVerifier GroupVerifier,
	chainLookupGen ChainLookupGenerator) (*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 either represents a serialized proof file, including the checksum or a single serialized issuance/transition proof. Which one it is can be found out from the leading magic bytes (or the helper methods that inspect those).

func EncodeAsProofFile added in v0.3.0

func EncodeAsProofFile(proof *Proof) (Blob, error)

EncodeAsProofFile encodes the passed proof into a blob.

func (Blob) AsFile added in v0.3.3

func (b Blob) AsFile() (*File, error)

AsFile returns the blob as a parsed file. If the blob is a single proof, it will be parsed as a file with a single proof.

func (Blob) AsSingleProof added in v0.3.3

func (b Blob) AsSingleProof() (*Proof, error)

AsSingleProof returns the blob as a parsed single proof. If the blob is a full proof file, the parsed last proof of that file will be returned.

func (Blob) IsFile added in v0.3.3

func (b Blob) IsFile() bool

IsFile returns true if the blob is a serialized proof file.

func (Blob) IsSingleProof added in v0.3.3

func (b Blob) IsSingleProof() bool

IsSingleProof returns true if the blob is a serialized single proof.

type ChainLookupGenerator added in v0.4.0

type ChainLookupGenerator interface {
	// GenFileChainLookup generates a chain lookup interface for the given
	// proof file that can be used to validate proofs.
	GenFileChainLookup(f *File) asset.ChainLookup

	// GenProofChainLookup generates a chain lookup interface for the given
	// single proof that can be used to validate proofs.
	GenProofChainLookup(p *Proof) (asset.ChainLookup, error)
}

ChainLookupGenerator is an interface that allows the creation of a chain lookup interface for a given proof file or single proof.

type CommitmentProof

type CommitmentProof struct {
	commitment.Proof

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

CommitmentProof represents a full commitment proof for an asset. It can either prove inclusion or exclusion of an asset within a Taproot Asset 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 interface {
	// DeliverProof attempts to delivery a proof to the receiver, using the
	// information in the Addr type.
	DeliverProof(context.Context, *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, Locator) (*AnnotatedProof, error)

	// SetSubscribers sets the set of subscribers that will be notified
	// of proof courier related events.
	SetSubscribers(map[uint64]*fn.EventReceiver[fn.Event])

	// Close stops the courier instance.
	Close() error
}

Courier abstracts away from the final proof retrieval/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.

type CourierCfg added in v0.3.0

type CourierCfg struct {
	// HashMailCfg contains hashmail protocol specific config parameters.
	HashMailCfg *HashMailCourierCfg

	// UniverseRpcCfg contains universe RPC protocol specific config
	// parameters.
	UniverseRpcCfg *UniverseRpcCourierCfg

	// TransferLog is a log for recording proof delivery and retrieval
	// attempts.
	TransferLog TransferLog

	// LocalArchive is an archive that can be used to fetch proofs from the
	// local archive.
	LocalArchive Archiver
}

CourierCfg contains general config parameters applicable to all proof couriers.

type CourierDispatch added in v0.3.3

type CourierDispatch interface {
	// NewCourier instantiates a new courier service handle given a service
	// URL address.
	NewCourier(addr *url.URL, recipient Recipient) (Courier, error)
}

CourierDispatch is an interface that abstracts away the different proof courier services that are supported.

type CourierHarness added in v0.2.1

type CourierHarness interface {
	// Start starts the proof courier service.
	Start(chan error) error

	// Stop stops the proof courier service.
	Stop() error
}

CourierHarness interface is an integration testing harness for a proof courier service.

type CourierType added in v0.2.1

type CourierType string

CourierType is an enum that represents the different proof courier services protocols that are supported.

type ErrorTestCase added in v0.3.0

type ErrorTestCase struct {
	Proof   *TestProof `json:"proof"`
	Error   string     `json:"error"`
	Comment string     `json:"comment"`
}

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 DecodeFile added in v0.4.0

func DecodeFile(blob []byte) (*File, error)

DecodeFile decodes a proof file from a byte slice.

func FetchProofProvenance added in v0.3.3

func FetchProofProvenance(ctx context.Context, localArchive Archiver,
	originLocator Locator,
	fetchSingleProof func(context.Context, Locator) (Blob, error)) (*File,
	error)

FetchProofProvenance iterates backwards through the main chain of proofs until it reaches the genesis point (the asset is the genesis asset) and then returns the full proof file with the full provenance for the asset.

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) AppendProofRaw added in v0.3.3

func (f *File) AppendProofRaw(proof []byte) error

AppendProofRaw appends a raw 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) IsUnknownVersion added in v0.3.0

func (f *File) IsUnknownVersion() bool

IsUnknownVersion returns true if a proof has a version that is not recognized by this implementation of tap.

func (*File) IsValid added in v0.3.0

func (f *File) IsValid() error

IsValid combines multiple sanity checks for proof file validity.

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) LocateProof added in v0.3.0

func (f *File) LocateProof(cb func(*Proof) bool) (*Proof, uint32, error)

LocateProof calls the given predicate for each proof in the file and returns the first proof (and the index) where the predicate returns true, starting from the end of the file. If no proof is found, this returns ErrNoProofAvailable.

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 ErrNoProofAvailable.

func (*File) RawLastProof

func (f *File) RawLastProof() ([]byte, error)

RawLastProof returns the raw last proof in the chain of proofs as a byte slice. If the file is empty, this return nil.

func (*File) RawProofAt

func (f *File) RawProofAt(index uint32) ([]byte, error)

RawProofAt returns the raw proof at the given index as a byte slice. 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) ReplaceProofAt added in v0.3.0

func (f *File) ReplaceProofAt(index uint32, proof Proof) error

ReplaceProofAt attempts to replace the proof at the given index with another one, updating its chained hash in the process.

func (*File) Verify

func (f *File) Verify(ctx context.Context, headerVerifier HeaderVerifier,
	merkleVerifier MerkleVerifier, groupVerifier GroupVerifier,
	chainLookup asset.ChainLookup) (*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/
│  ├─ scriptKey1-outpointTxid[:32]-outpointIndex.assetproof
│  ├─ scriptKey2-outpointTxid[:32]-outpointIndex.assetproof

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) FetchIssuanceProof added in v0.4.0

func (f *FileArchiver) FetchIssuanceProof(ctx context.Context, id asset.ID,
	anchorOutpoint wire.OutPoint) (Blob, error)

FetchIssuanceProof fetches the issuance proof for an asset, given the anchor point of the issuance (NOT the genesis point for the asset).

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

NOTE: This implements the Archiver interface.

func (*FileArchiver) FetchProof

func (f *FileArchiver) FetchProof(_ 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. If multiple proofs exist for the given fields of the locator then ErrMultipleProofs is returned to indicate more specific fields need to be set in the Locator (e.g. the OutPoint).

NOTE: This implements the Archiver interface.

func (*FileArchiver) FetchProofs added in v0.3.0

func (f *FileArchiver) FetchProofs(_ context.Context,
	id asset.ID) ([]*AnnotatedProof, error)

FetchProofs fetches all proofs for assets uniquely identified by the passed asset ID.

func (*FileArchiver) HasProof added in v0.3.3

func (f *FileArchiver) HasProof(_ context.Context, id Locator) (bool, error)

HasProof returns true if the proof for the given locator exists. This is intended to be a performance optimized lookup compared to fetching a proof and checking for ErrProofNotFound.

func (*FileArchiver) ImportProofs

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. If replace is specified, we expect a proof to already be present, and we just update (replace) it with the new proof.

NOTE: This implements the Archiver interface.

func (*FileArchiver) RegisterSubscriber

func (f *FileArchiver) RegisterSubscriber(
	receiver *fn.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 (*FileArchiver) RemoveSubscriber

func (f *FileArchiver) RemoveSubscriber(
	subscriber *fn.EventReceiver[Blob]) error

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

type GroupAnchorVerifier added in v0.3.0

type GroupAnchorVerifier func(gen *asset.Genesis,
	groupKey *asset.GroupKey) error

GroupAnchorVerifier is a callback function which returns an error if the given genesis is not the asset genesis of the group anchor. This callback should return an error for any reissuance into an existing group.

type GroupVerifier added in v0.3.0

type GroupVerifier func(groupKey *btcec.PublicKey) error

GroupVerifier is a callback function which returns an error if the given group key has not been imported by the tapd daemon. This can occur if the issuance proof for the group anchor has not been imported or synced.

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(courierAddr *url.URL) (*HashMailBox,
	error)

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

NOTE: The TLS certificate path argument (tlsCertPath) is optional. If unset, then the system's TLS trust store is used.

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 received.

func (*HashMailBox) CleanUp

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

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

func (*HashMailBox) Close added in v0.3.3

func (h *HashMailBox) Close() error

Close closes the underlying connection to the hashmail server.

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 a hashmail proof courier service handle. It implements the Courier interface.

func (*HashMailCourier) Close added in v0.3.3

func (h *HashMailCourier) Close() error

Close closes the underlying connection to the hashmail server.

func (*HashMailCourier) DeliverProof

func (h *HashMailCourier) DeliverProof(ctx context.Context,
	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,
	loc Locator) (*AnnotatedProof, error)

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

func (*HashMailCourier) SetSubscribers

func (h *HashMailCourier) SetSubscribers(
	subscribers map[uint64]*fn.EventReceiver[fn.Event])

SetSubscribers sets the subscribers for the courier. This method is thread-safe.

type HashMailCourierCfg

type HashMailCourierCfg struct {
	// ReceiverAckTimeout is the maximum time we'll wait for the receiver to
	// acknowledge the proof.
	ReceiverAckTimeout time.Duration `long:"receiveracktimeout" description:"The maximum time to wait for the receiver to acknowledge the proof."`

	// BackoffCfg configures the behaviour of the proof delivery
	// functionality.
	BackoffCfg *BackoffCfg
}

HashMailCourierCfg is the config for the hashmail proof courier.

type HeaderVerifier

type HeaderVerifier func(blockHeader wire.BlockHeader, blockHeight uint32) error

HeaderVerifier is a callback function which returns an error if the given block header is invalid (usually: not present on chain).

type Locator

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

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

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

	// OutPoint is the outpoint of the associated asset. This field is
	// optional.
	OutPoint *wire.OutPoint
}

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

func (*Locator) Hash

func (l *Locator) Hash() ([32]byte, error)

Hash returns a SHA256 hash of the bytes serialized locator.

type MerkleVerifier added in v0.4.0

type MerkleVerifier func(tx *wire.MsgTx, proof *TxMerkleProof,
	merkleRoot [32]byte) error

MerkleVerifier is a callback function which returns an error if the given merkle proof is invalid.

type MetaReveal

type MetaReveal struct {
	// Type is the type of the metadata.
	Type MetaType

	// Data is the committed data being revealed.
	Data []byte
}

MetaReveal is an optional TLV type that can be added to the proof of a genesis asset to reveal pre-image to the metadata hash. If present, then the following equality must hold for the genesis proof to be valid:

  • sha256(tlvEncode(metaReveal)) == metaHash

func (*MetaReveal) Decode

func (m *MetaReveal) Decode(r io.Reader) error

Decode decodes the meta reveal from the given reader.

func (*MetaReveal) DecodeRecords

func (m *MetaReveal) DecodeRecords() []tlv.Record

DecodeRecords returns the TLV decode records for the meta reveal.

func (*MetaReveal) Encode

func (m *MetaReveal) Encode(w io.Writer) error

Encode encodes the meta reveal to the given writer.

func (*MetaReveal) EncodeRecords

func (m *MetaReveal) EncodeRecords() []tlv.Record

EncodeRecords returns the TLV encode records for the meta reveal.

func (*MetaReveal) GetDecDisplay added in v0.4.0

func (m *MetaReveal) GetDecDisplay() (map[string]interface{}, uint32, error)

GetDecDisplay attempts to decode metadata as JSON and return the decimal display value. If the metadata is not JSON, or the decimal display key is missing, the default decimal display value of 0 is returned.

func (*MetaReveal) MetaHash

func (m *MetaReveal) MetaHash() [asset.MetaHashLen]byte

MetaHash returns the computed meta hash based on the TLV serialization of the meta data itself.

func (*MetaReveal) SetDecDisplay added in v0.4.0

func (m *MetaReveal) SetDecDisplay(decDisplay uint32) (*MetaReveal, error)

SetDecDisplay attempts to set the decimal display value in existing JSON metadata. It checks that the new metadata is below the maximum metadata size.

func (*MetaReveal) Validate added in v0.3.0

func (m *MetaReveal) Validate() error

Validate validates the meta reveal.

type MetaType

type MetaType uint8

MetaType is the type of the meta data being revealed.

const (
	// MetaOpaque signals that the meta data is simply a set of opaque
	// bytes without any specific interpretation.
	MetaOpaque MetaType = 0

	// MetaJson signals that the meta data is a JSON object.
	MetaJson MetaType = 1
)

func IsValidMetaType added in v0.4.0

func IsValidMetaType[T SizableInteger](num T) (MetaType, error)

IsValidMetaType checks if the passed value is a valid meta type.

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 MintingBlobOption

type MintingBlobOption func(*mintingBlobOpts)

MintingBlobOption allows the caller to modify how the final set of minting blobs is created. This can be used to attach optional data to the proof file.

func WithAssetMetaReveals

func WithAssetMetaReveals(
	metaReveals map[asset.SerializedKey]*MetaReveal) MintingBlobOption

WithAssetMetaReveals is a MintingBlobOption that allows the caller to attach meta reveal information to the initial minting blob created.

func WithSiblingPreimage added in v0.4.0

func WithSiblingPreimage(
	sibling *commitment.TapscriptPreimage) MintingBlobOption

WithSiblingPreimage is a MintingBlobOption that allows the caller to provide a tapscript sibling preimage to be used when building the initial minting blob.

type MockProofArchive added in v0.4.0

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

MockProofArchive is a map that implements the Archiver interface.

func NewMockProofArchive added in v0.4.0

func NewMockProofArchive() *MockProofArchive

NewMockProofArchive creates a new mock proof archive.

func (*MockProofArchive) FetchIssuanceProof added in v0.4.0

func (m *MockProofArchive) FetchIssuanceProof(_ context.Context,
	id asset.ID, anchorOutpoint wire.OutPoint) (Blob, error)

FetchIssuanceProof fetches the issuance proof for an asset, given the anchor point of the issuance (NOT the genesis point for the asset).

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

func (*MockProofArchive) FetchProof added in v0.4.0

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

FetchProof fetches a proof for an asset uniquely identified by the passed Locator. If a proof cannot be found, then ErrProofNotFound is returned.

func (*MockProofArchive) FetchProofs added in v0.4.0

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

FetchProofs would fetch all proofs for a specific asset ID, but will always err for the mock proof archive.

func (*MockProofArchive) HasProof added in v0.4.0

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

HasProof returns true if the proof for the given locator exists.

func (*MockProofArchive) ImportProofs added in v0.4.0

ImportProofs will store the given proofs, without performing any validation.

type MockProofCourier added in v0.3.3

type MockProofCourier struct {
	sync.Mutex
	// contains filtered or unexported fields
}

MockProofCourier is a mock proof courier which stores the last proof it received.

func NewMockProofCourier added in v0.3.3

func NewMockProofCourier() *MockProofCourier

NewMockProofCourier returns a new mock proof courier.

func (*MockProofCourier) Close added in v0.3.3

func (m *MockProofCourier) Close() error

Close stops the courier instance.

func (*MockProofCourier) DeliverProof added in v0.3.3

func (m *MockProofCourier) DeliverProof(_ context.Context,
	proof *AnnotatedProof) error

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

func (*MockProofCourier) ReceiveProof added in v0.3.3

func (m *MockProofCourier) ReceiveProof(_ context.Context,
	loc Locator) (*AnnotatedProof, error)

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

func (*MockProofCourier) SetSubscribers added in v0.3.3

func (m *MockProofCourier) SetSubscribers(
	subscribers map[uint64]*fn.EventReceiver[fn.Event])

SetSubscribers sets the set of subscribers that will be notified of proof courier related events.

func (*MockProofCourier) Start added in v0.3.3

func (m *MockProofCourier) Start(chan error) error

Start starts the proof courier service.

func (*MockProofCourier) Stop added in v0.3.3

func (m *MockProofCourier) Stop() error

Stop stops the proof courier service.

type MockProofCourierDispatcher added in v0.3.3

type MockProofCourierDispatcher struct {
	Courier Courier
}

MockProofCourierDispatcher is a mock proof courier dispatcher which returns the same courier for all requests.

func (*MockProofCourierDispatcher) NewCourier added in v0.3.3

NewCourier instantiates a new courier service handle given a service URL address.

type MockVerifier

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

func NewMockVerifier

func NewMockVerifier(t *testing.T) *MockVerifier

type MultiArchiveNotifier added in v0.3.3

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

MultiArchiveNotifier is a NotifyArchiver that wraps several other archives and notifies subscribers about new proofs that are added to any of the archives.

func NewMultiArchiveNotifier added in v0.3.3

func NewMultiArchiveNotifier(archives ...NotifyArchiver) *MultiArchiveNotifier

NewMultiArchiveNotifier creates a new MultiArchiveNotifier based on the set of specified backends.

func (*MultiArchiveNotifier) FetchProof added in v0.3.3

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

FetchProof fetches a proof for an asset uniquely identified by the passed Identifier. The returned proof can either be a full proof file or just a single proof.

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

NOTE: This is part of the NotifyArchiver interface.

func (*MultiArchiveNotifier) RegisterSubscriber added in v0.3.3

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

RegisterSubscriber adds a new subscriber for receiving events. The registration request is forwarded to all registered archives.

func (*MultiArchiveNotifier) RemoveSubscriber added in v0.3.3

func (m *MultiArchiveNotifier) RemoveSubscriber(
	subscriber *fn.EventReceiver[Blob]) error

RemoveSubscriber removes the given subscriber and also stops it from processing events. The removal request is forwarded to all registered archives.

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) FetchIssuanceProof added in v0.4.0

func (m *MultiArchiver) FetchIssuanceProof(ctx context.Context,
	id asset.ID, anchorOutpoint wire.OutPoint) (Blob, error)

FetchIssuanceProof fetches the issuance proof for an asset, given the anchor point of the issuance (NOT the genesis point for the asset).

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) FetchProofs added in v0.3.0

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

FetchProofs fetches all proofs for assets uniquely identified by the passed asset ID.

func (*MultiArchiver) HasProof added in v0.3.3

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

HasProof returns true if the proof for the given locator exists. This is intended to be a performance optimized lookup compared to fetching a proof and checking for ErrProofNotFound. The multi archiver only considers a proof to be present if all backends have it.

func (*MultiArchiver) ImportProofs

func (m *MultiArchiver) ImportProofs(ctx context.Context,
	headerVerifier HeaderVerifier, merkleVerifier MerkleVerifier,
	groupVerifier GroupVerifier, chainLookupGen ChainLookupGenerator,
	replace bool, 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 *fn.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 *fn.EventReceiver[Blob]) error

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

type NotifyArchiver

type NotifyArchiver interface {
	// FetchProof fetches a proof for an asset uniquely identified by the
	// passed Identifier. The returned blob is expected to be the encoded
	// full proof file, containing the complete provenance of the asset.
	//
	// If a proof cannot be found, then ErrProofNotFound should be returned.
	FetchProof(ctx context.Context, id Locator) (Blob, error)

	fn.EventPublisher[Blob, []*Locator]
}

NotifyArchiver is an Archiver that also allows callers to subscribe to notifications about new proofs being added to the archiver.

type Proof

type Proof struct {
	// Version is the version of the state transition proof.
	Version TransitionVersion

	// PrevOut is the previous on-chain outpoint of the asset. This outpoint
	// is that of the first on-chain input. Outpoints which correspond to
	// the other inputs can be found in AdditionalInputs.
	PrevOut wire.OutPoint

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

	// BlockHeight is the height of the current block committing to the
	// on-chain transaction attempting an asset state transition.
	BlockHeight uint32

	// 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

	// MetaReveal is the set of bytes that were revealed to prove the
	// derivation of the meta data hash contained in the genesis asset.
	//
	// TODO(roasbeef): use even/odd framing here?
	//
	// NOTE: This field is optional, and can only be specified if the asset
	// above is a genesis asset. If specified, then verifiers _should_ also
	// verify the hashes match up.
	MetaReveal *MetaReveal

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

	// ChallengeWitness is an optional virtual transaction witness that
	// serves as an ownership proof for the asset. If this is non-nil, then
	// it is a valid transfer witness for a 1-input, 1-output virtual
	// transaction that spends the asset in this proof and sends it to the
	// NUMS key, to prove that the creator of the proof is able to produce
	// a valid signature to spend the asset.
	ChallengeWitness wire.TxWitness

	// GenesisReveal is the Genesis information for an asset, that must be
	// provided for minting proofs, and must be empty for non-minting
	// proofs. This allows for derivation of the asset ID. If the asset is
	// part of an asset group, the Genesis information is also used for
	// rederivation of the asset group key.
	GenesisReveal *asset.Genesis

	// GroupKeyReveal is an optional set of bytes that represent the public
	// key and Tapscript root used to derive the final tweaked group key for
	// the asset group. This field must be provided for issuance proofs of
	// grouped assets.
	GroupKeyReveal *asset.GroupKeyReveal
}

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 Decode added in v0.4.0

func Decode(blob []byte) (*Proof, error)

Decode decodes a proof from a byte slice.

func RandProof added in v0.4.0

func RandProof(t testing.TB, genesis asset.Genesis,
	scriptKey *btcec.PublicKey, block wire.MsgBlock, txIndex int,
	outputIndex uint32) Proof

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) IsUnknownVersion added in v0.3.0

func (p *Proof) IsUnknownVersion() bool

IsUnknownVersion returns true if a proof has a version that is not recognized by this implementation of tap.

func (*Proof) OutPoint added in v0.3.0

func (p *Proof) OutPoint() wire.OutPoint

OutPoint returns the outpoint that commits to the asset associated with this proof.

func (*Proof) Record added in v0.4.0

func (p *Proof) Record() tlv.Record

Record returns a TLV record that can be used to encode/decode a Proof to/from a TLV stream.

NOTE: This is part of the tlv.RecordProducer interface.

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,
	headerVerifier HeaderVerifier, merkleVerifier MerkleVerifier,
	groupVerifier GroupVerifier,
	chainLookup asset.ChainLookup) (*AssetSnapshot, error)

Verify verifies the proof by ensuring that:

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

func (*Proof) VerifyProofs added in v0.4.0

func (p *Proof) VerifyProofs() (*commitment.TapCommitment, error)

VerifyProofs verifies the inclusion and exclusion proofs as well as the split root proof.

type ProofCommitmentKeys added in v0.4.0

type ProofCommitmentKeys map[asset.SerializedKey]*commitment.TapCommitment

ProofCommitmentKeys stores the Taproot Asset commitments and taproot output keys derived from a TaprootProof.

func (ProofCommitmentKeys) GetCommitment added in v0.4.0

func (k ProofCommitmentKeys) GetCommitment() (*commitment.TapCommitment,
	error)

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 received.
	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 attempts to tear down the mailbox as specified by the passed
	// sid.
	CleanUp(ctx context.Context, sid streamID) error

	// Close closes the underlying connection to the hashmail server.
	Close() error
}

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

type Recipient

type Recipient struct {
	// ScriptKey is the main identifier of the recipient. It is used to
	// derive the stream IDs for the mailbox.
	ScriptKey *btcec.PublicKey

	// AssetID is the ID of the asset that is being transferred. This is
	// used for logging purposes only.
	AssetID asset.ID

	// Amount is the amount of the asset that is being transferred. This is
	// used for logging purposes only.
	Amount uint64
}

Recipient describes the recipient of a proof. The script key is enough to identify a transferred asset in the context of the proof courier. This is because a proof only needs to be delivered via courier if the recipient used an address to receive (non-interactive). And each address requires the user to derive a fresh and unique script key. The other fields are used for logging purposes only.

type SizableInteger added in v0.4.0

type SizableInteger interface {
	constraints.Unsigned | ~int | ~int16 | ~int32 | ~int64
}

A subset of Integer that excludes int8, since we never use it in practice.

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 Taproot Asset commitment.
	CommitmentProof *CommitmentProof

	// TapscriptProof represents a taproot control block to prove that a
	// taproot output is not committing to a Taproot Asset commitment.
	//
	// NOTE: This field will be set only if the output does NOT contain a
	// valid Taproot Asset 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 Taproot Asset commitment through a CommitmentProof, or that no Taproot Asset 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,
	tapCommitmentKey [32]byte) (ProofCommitmentKeys, error)

DeriveByAssetExclusion derives the possible taproot keys backing a Taproot Asset 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 TapCommitment.

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,
	single *bool) (ProofCommitmentKeys, error)

DeriveByAssetInclusion derives the unique taproot output key backing a Taproot Asset 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 Taproot Asset 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 TapscriptProof

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

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

	// Bip86 indicates this is a normal BIP-0086 wallet output (likely a
	// change output) that does not commit to any script or Taproot Asset
	// root.
	Bip86 bool
}

TapscriptProof represents a proof of a Taproot output not including a Taproot Asset commitment. Taproot Asset commitments must exist at a leaf with depth 0 or 1, so we can guarantee that a Taproot Asset 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 CreateTapscriptProof added in v0.4.0

func CreateTapscriptProof(leaves []txscript.TapLeaf) (*TapscriptProof, error)

CreateTapscriptProof creates a TapscriptProof from a list of tapscript leaves proving that there is no asset commitment contained in the output the proof is for.

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 TapscriptProof backing a taproot output that does not include a Taproot Asset 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 TestBlockHeader added in v0.3.0

type TestBlockHeader struct {
	Version    int32  `json:"version"`
	PrevBlock  string `json:"prev_block"`
	MerkleRoot string `json:"merkle_root"`
	Timestamp  uint32 `json:"timestamp"`
	Bits       uint32 `json:"bits"`
	Nonce      uint32 `json:"nonce"`
}

func NewTestFromBlockHeader added in v0.3.0

func NewTestFromBlockHeader(t testing.TB,
	h *wire.BlockHeader) *TestBlockHeader

func (*TestBlockHeader) ToBlockHeader added in v0.3.0

func (tbh *TestBlockHeader) ToBlockHeader(t testing.TB) *wire.BlockHeader

type TestCommitmentProof added in v0.3.0

type TestCommitmentProof struct {
	Proof            *commitment.TestProof `json:"proof"`
	TapscriptSibling string                `json:"tapscript_sibling"`
}

func NewTestFromCommitmentProof added in v0.3.0

func NewTestFromCommitmentProof(t testing.TB,
	p *CommitmentProof) *TestCommitmentProof

func (*TestCommitmentProof) ToCommitmentProof added in v0.3.0

func (tcp *TestCommitmentProof) ToCommitmentProof(
	t testing.TB) *CommitmentProof

type TestMetaReveal added in v0.3.0

type TestMetaReveal struct {
	Type uint8  `json:"type"`
	Data string `json:"data"`
}

func NewTestFromMetaReveal added in v0.3.0

func NewTestFromMetaReveal(t testing.TB, m *MetaReveal) *TestMetaReveal

func (*TestMetaReveal) ToMetaReveal added in v0.3.0

func (tmr *TestMetaReveal) ToMetaReveal(t testing.TB) *MetaReveal

type TestProof added in v0.3.0

type TestProof struct {
	PrevOut          string                    `json:"prev_out"`
	BlockHeader      *TestBlockHeader          `json:"block_header"`
	BlockHeight      uint32                    `json:"block_height"`
	AnchorTx         string                    `json:"anchor_tx"`
	TxMerkleProof    *TestTxMerkleProof        `json:"tx_merkle_proof"`
	Asset            *asset.TestAsset          `json:"asset"`
	InclusionProof   *TestTaprootProof         `json:"inclusion_proof"`
	ExclusionProofs  []*TestTaprootProof       `json:"exclusion_proofs"`
	SplitRootProof   *TestTaprootProof         `json:"split_root_proof"`
	MetaReveal       *TestMetaReveal           `json:"meta_reveal"`
	AdditionalInputs []string                  `json:"additional_inputs"`
	ChallengeWitness []string                  `json:"challenge_witness"`
	GenesisReveal    *asset.TestGenesisReveal  `json:"genesis_reveal"`
	GroupKeyReveal   *asset.TestGroupKeyReveal `json:"group_key_reveal"`
}

func NewTestFromProof added in v0.3.0

func NewTestFromProof(t testing.TB, p *Proof) *TestProof

func (*TestProof) ToProof added in v0.3.0

func (tp *TestProof) ToProof(t testing.TB) *Proof

type TestTaprootProof added in v0.3.0

type TestTaprootProof struct {
	OutputIndex     uint32               `json:"output_index"`
	InternalKey     string               `json:"internal_key"`
	CommitmentProof *TestCommitmentProof `json:"commitment_proof"`
	TapscriptProof  *TestTapscriptProof  `json:"tapscript_proof"`
}

func NewTestFromTaprootProof added in v0.3.0

func NewTestFromTaprootProof(t testing.TB,
	p *TaprootProof) *TestTaprootProof

func (*TestTaprootProof) ToTaprootProof added in v0.3.0

func (ttp *TestTaprootProof) ToTaprootProof(t testing.TB) *TaprootProof

type TestTapscriptProof added in v0.3.0

type TestTapscriptProof struct {
	TapPreimage1 string `json:"tap_preimage_1"`
	TapPreimage2 string `json:"tap_preimage_2"`
	Bip86        bool   `json:"bip86"`
}

func NewTestFromTapscriptProof added in v0.3.0

func NewTestFromTapscriptProof(t testing.TB,
	p *TapscriptProof) *TestTapscriptProof

func (*TestTapscriptProof) ToTapscriptProof added in v0.3.0

func (ttp *TestTapscriptProof) ToTapscriptProof(t testing.TB) *TapscriptProof

type TestTxMerkleProof added in v0.3.0

type TestTxMerkleProof struct {
	Nodes []string `json:"nodes"`
	Bits  []bool   `json:"bits"`
}

func NewTestFromTxMerkleProof added in v0.3.0

func NewTestFromTxMerkleProof(t testing.TB,
	p *TxMerkleProof) *TestTxMerkleProof

func (*TestTxMerkleProof) ToTxMerkleProof added in v0.3.0

func (tmp *TestTxMerkleProof) ToTxMerkleProof(t testing.TB) *TxMerkleProof

type TestVectors added in v0.3.0

type TestVectors struct {
	ValidTestCases []*ValidTestCase `json:"valid_test_cases"`
	ErrorTestCases []*ErrorTestCase `json:"error_test_cases"`
}

type TransferLog added in v0.3.1

type TransferLog interface {
	// LogProofTransferAttempt logs a new proof transfer attempt.
	LogProofTransferAttempt(context.Context, Locator, TransferType) error

	// QueryProofTransferLog returns timestamps which correspond to logged
	// proof delivery attempts.
	QueryProofTransferLog(context.Context, Locator,
		TransferType) ([]time.Time, error)
}

TransferLog is an interface that allows the courier to log the attempted delivery/receive of a proof.

type TransferType added in v0.3.1

type TransferType string

TransferType is the type of proof transfer attempt. The transfer is either a proof delivery to the transfer counterparty or receiving a proof from the transfer counterparty. Note that the transfer counterparty is usually the proof courier service.

const (
	// SendTransferType signifies that a proof was sent to the transfer
	// counterparty.
	SendTransferType TransferType = "send"

	// ReceiveTransferType signifies that a proof was received from the
	// proof transfer counterparty.
	ReceiveTransferType TransferType = "receive"
)

type TransitionParams

type TransitionParams struct {
	// BaseProofParams houses the basic chain level parameters needed to
	// construct a proof.
	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

	// RootTaprootAssetTree is the commitment root that commitments to the
	// inclusion of the root split asset at the RootOutputIndex.
	RootTaprootAssetTree *commitment.TapCommitment

	// RootTapscriptSibling is the tapscript sibling of the output at
	// commits to the asset split root.
	RootTapscriptSibling *commitment.TapscriptPreimage
}

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

type TransitionVersion added in v0.3.0

type TransitionVersion uint32

TransitionVersion denotes the versioning scheme for an individual state transition proof.

const (
	// TransitionV0 is the first version of the state transition proof.
	TransitionV0 TransitionVersion = 0
)

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-0037 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 URLDispatch added in v0.3.3

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

URLDispatch is a proof courier dispatch that uses the courier address URL scheme to determine which courier service to use.

func NewCourierDispatch added in v0.3.3

func NewCourierDispatch(cfg *CourierCfg) *URLDispatch

NewCourierDispatch creates a new proof courier dispatch.

func (*URLDispatch) NewCourier added in v0.3.3

func (u *URLDispatch) NewCourier(addr *url.URL,
	recipient Recipient) (Courier, error)

NewCourier instantiates a new courier service handle given a service URL address.

type UniverseRpcCourier added in v0.3.0

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

UniverseRpcCourier is a universe RPC proof courier service handle. It implements the Courier interface.

func (*UniverseRpcCourier) Close added in v0.3.3

func (c *UniverseRpcCourier) Close() error

Close closes the courier's connection to the remote gRPC service.

func (*UniverseRpcCourier) DeliverProof added in v0.3.0

func (c *UniverseRpcCourier) DeliverProof(ctx context.Context,
	annotatedProof *AnnotatedProof) error

DeliverProof attempts to delivery a proof file to the receiver.

func (*UniverseRpcCourier) ReceiveProof added in v0.3.0

func (c *UniverseRpcCourier) ReceiveProof(ctx context.Context,
	originLocator Locator) (*AnnotatedProof, error)

ReceiveProof attempts to obtain a proof file from the courier service. The final proof in the target proof file is identified by the given locator.

func (*UniverseRpcCourier) SetSubscribers added in v0.3.0

func (c *UniverseRpcCourier) SetSubscribers(
	subscribers map[uint64]*fn.EventReceiver[fn.Event])

SetSubscribers sets the subscribers for the courier. This method is thread-safe.

type UniverseRpcCourierCfg added in v0.3.3

type UniverseRpcCourierCfg struct {
	// BackoffCfg configures the behaviour of the proof delivery
	// functionality.
	BackoffCfg *BackoffCfg
}

UniverseRpcCourierCfg is the config for the universe RPC proof courier.

type UpdateCallback added in v0.3.0

type UpdateCallback func([]*Proof) error

UpdateCallback is a callback that is called when proofs are updated because of a re-org.

type ValidTestCase added in v0.3.0

type ValidTestCase struct {
	Proof    *TestProof `json:"proof"`
	Expected string     `json:"expected"`
	Comment  string     `json:"comment"`
}

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,
		headerVerifier HeaderVerifier, merkleVerifier MerkleVerifier,
		groupVerifier GroupVerifier,
		chainLookupGen ChainLookupGenerator) (*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.

type Watcher added in v0.3.0

type Watcher interface {
	// WatchProofs adds new proofs to the re-org watcher for their anchor
	// transaction to be watched until it reaches a safe confirmation depth.
	WatchProofs(newProofs []*Proof, onProofUpdate 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.
	MaybeWatch(file *File, onProofUpdate UpdateCallback) error

	// ShouldWatch returns true if the proof is for a block that is not yet
	// sufficiently deep to be considered safe.
	ShouldWatch(proof *Proof) bool

	// DefaultUpdateCallback returns 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.
	DefaultUpdateCallback() UpdateCallback
}

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

Jump to

Keyboard shortcuts

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