universe

package
v0.2.2 Latest Latest
Warning

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

Go to latest
Published: Jun 23, 2023 License: MIT Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// DefaultTimeout is the default timeout we use for RPC and database
	// operations.
	DefaultTimeout = 30 * time.Second
)
View Source
const (
	// DefaultUniverseRPCPort is the default port that the universe RPC is
	// hosted on.
	DefaultUniverseRPCPort = 10029
)
View Source
const Subsystem = "UNIV"

Subsystem defines the logging code for this subsystem.

Variables

View Source
var (
	// ErrNoUniverseRoot is returned when no universe root is found.
	ErrNoUniverseRoot = fmt.Errorf("no universe root found")

	// ErrNoUniverseServers is returned when no active Universe servers are
	// found in the DB.
	ErrNoUniverseServers = fmt.Errorf("no active federation servers")

	// ErrDuplicateUniverse is returned when the Universe server being added
	// to the DB already exists.
	ErrDuplicateUniverse = fmt.Errorf("universe server already added")
)
View Source
var (
	// ErrUnsupportedSync is returned when a syncer is asked to async in a
	// way that it does not support.
	ErrUnsupportedSync = fmt.Errorf("unsupported sync type")
)

Functions

func DisableLog

func DisableLog()

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

func UseLogger

func UseLogger(logger btclog.Logger)

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

Types

type AggregateStats

type AggregateStats struct {
	// NumTotalAssets is the total number of assets in the Universe.
	NumTotalAssets uint64

	// NumTotalSyncs is the total number of syncs that have been performed in
	// the Universe.
	NumTotalSyncs uint64

	// NumTotalProofs is the total number of proofs that have been inserted
	// into the Universe.
	NumTotalProofs uint64
}

AggregateStats is a set of aggregate stats for a given Universe.

type AssetSyncDiff

type AssetSyncDiff struct {
	// OldUniverseRoot is the root of the universe before the sync.
	OldUniverseRoot BaseRoot

	// NewUniverseRoot is the new root of the Universe after the sync.
	NewUniverseRoot BaseRoot

	// NewAssetLeaves is the set of new leaf proofs that were added to the
	// Universe.
	NewLeafProofs []*MintingLeaf
}

AssetSyncDiff is the result of a success Universe sync. The diff contains the Universe root, and the set of assets that were added to the Universe.

type AssetSyncSnapshot

type AssetSyncSnapshot struct {
	// AssetID is the ID of the asset.
	AssetID asset.ID

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

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

	// TotalSupply is the total supply of the asset.
	TotalSupply uint64

	// GenesisHeight is the height of the block that the asset was created
	// in.
	GenesisHeight uint32

	// TotalSyncs is the total number of syncs that have been performed for
	// the target asset.
	TotalSyncs uint64

	// TotalProofs is the total number of proofs that have been inserted
	// for the asset.
	TotalProofs uint64
}

AssetSyncSnapshot is a snapshot of the sync activity for a given asset.

type AssetSyncStats

type AssetSyncStats struct {
	// Query is the original query that was used to generate the stats.
	Query SyncStatsQuery

	// SyncStats is the set of sync stats generated by the query.
	SyncStats []AssetSyncSnapshot
}

AssetSyncStats is the response to a SyncStatsQuery request. It contains the original query, and the set of sync stats generated by the query.

type BaseBackend

type BaseBackend interface {
	// RootNode returns the root node for a given base universe.
	RootNode(context.Context) (mssmt.Node, string, error)

	// RegisterIssuance inserts a new minting leaf within the universe
	// tree, stored at the base key. The metaReveal type is purely
	// optional, and should be specified if the genesis proof committed to
	// a non-zero meta hash.
	RegisterIssuance(ctx context.Context,
		key BaseKey, leaf *MintingLeaf,
		metaReveal *proof.MetaReveal) (*IssuanceProof, error)

	// FetchIssuanceProof returns an issuance proof for the target key. If
	// the key doesn't have a script key specified, then all the proofs for
	// the minting outpoint will be returned. If neither are specified,
	// then proofs for all the inserted leaves will be returned.
	//
	// TODO(roasbeef): can eventually do multi-proofs for the SMT
	FetchIssuanceProof(ctx context.Context,
		key BaseKey) ([]*IssuanceProof, error)

	// MintingKeys returns all the keys inserted in the universe.
	MintingKeys(ctx context.Context) ([]BaseKey, error)

	// MintingLeaves returns all the minting leaves inserted into the
	// universe.
	MintingLeaves(ctx context.Context) ([]MintingLeaf, error)

	// DeleteUniverse deletes all leaves, and the root, for a given base
	// universe.
	DeleteUniverse(ctx context.Context) (string, error)
}

BaseBackend is the backend storage interface for a base universe. The backend can be used to store issuance profs, retrieve them, and also fetch the set of keys and leaves stored within the universe.

TODO(roasbeef): gRPC service to match this, think about the REST mapping

type BaseForest

type BaseForest interface {
	// RootNodes returns the complete set of known root nodes for the set
	// of assets tracked in the base Universe.
	RootNodes(ctx context.Context) ([]BaseRoot, error)
}

BaseForest is an interface used to keep track of the set of base universe roots that we know of. The BaseBackend interface is used to interact with a particular base universe, while this is used to obtain aggregate information about the universes.

type BaseKey

type BaseKey struct {
	// MintingOutpoint is the minting outpoint, or the outpoint where the
	// newly created assets reside within.
	MintingOutpoint wire.OutPoint

	// ScriptKey is the script key of the base asset. If this isn't
	// specified, then the caller is attempting to query for all the script
	// keys at that minting outpoint.
	ScriptKey *asset.ScriptKey
}

BaseKey is the top level key for a Base/Root universe. This will be used to key into the MS-SMT. The final key is: sha256(mintingOutpoint || scriptKey). This ensures that all leaves for a given asset will be uniquely keyed in the universe tree.

func (BaseKey) UniverseKey

func (b BaseKey) UniverseKey() [32]byte

UniverseKey is the key for a universe.

type BaseRoot

type BaseRoot struct {
	ID Identifier

	mssmt.Node

	// AssetName is the name of the asset. This might not always be set for
	// performance reasons.
	AssetName string
}

BaseRoot is the ms-smt root for a base universe. This root can be used to compare against other trackers of a base universe to find discrepancies (unknown issuance events, etc).

type Canonical

type Canonical interface {
	BaseBackend

	// Query returns a fully proved response for the target base key.
	Query(context.Context, BaseKey) (*CommittedIssuanceProof, error)

	// LatestCommitment returns the latest chain commitment.
	LatestCommitment() (*Commitment, error)

	// UpdateChainCommitment takes in a series of chain commitments and
	// updates the commitment on chain.
	UpdateChainCommitment(chainCommits ...ChainCommitter) (*Commitment, error)
}

Canonical is an interface that allows a caller to query for the latest canonical Universe information related to an asset.

TODO(roasbeef): sync methods too, divide into read/write?

type ChainCommitter

type ChainCommitter interface {
	// CommitUniverse takes a Universe and returns a new commitment to that
	// Universe in the main chain.
	CommitUniverse(universe BaseBackend) (*Commitment, error)
}

ChainCommitter is used to commit a Universe backend in the chain.

type Commitment

type Commitment struct {
	// BlockHeight is the height of the block that the commitment is
	// contained within.
	BlockHeight uint32

	// BlockHeader is the block header that commits to the transaction.
	BlockHeader wire.BlockHeader

	// MerkleProof is a merkle proof for the above transaction that the
	// anchor output was included.
	MerkleProof *proof.TxMerkleProof

	// UniverseRoot is the full Universe root for this commitment.
	UniverseRoot mssmt.Node
}

Commitment is an on chain universe commitment. This includes the merkle proof for a transaction which anchors the target universe root.

type CommittedIssuanceProof

type CommittedIssuanceProof struct {
	// ChainProof is the on chain proof that shows the Universe root has
	// been stamped in the chain.
	ChainProof *Commitment

	// TaprootAssetProof is a proof of new asset issuance.
	TaprootAssetProof *IssuanceProof
}

CommittedIssuanceProof couples together a Bitcoin level merkle proof commitment with an issuance proof. This allows remote callers to verify that their responses re actually committed to within the chain.

type DiffEngine

type DiffEngine interface {
	BaseForest

	// RootNode returns the root node for a given base universe.
	RootNode(ctx context.Context, id Identifier) (BaseRoot, error)

	// MintingKeys returns all the keys inserted in the universe.
	MintingKeys(ctx context.Context, id Identifier) ([]BaseKey, error)

	// FetchIssuanceProof attempts to fetch an issuance proof for the
	// target base leaf based on the universe identifier (assetID/groupKey).
	//
	// TODO(roasbeef): actually add this somewhere else?  * rn kinda
	// asymmetric, as just need this to complete final portion
	// of diff
	FetchIssuanceProof(ctx context.Context, id Identifier,
		key BaseKey) ([]*IssuanceProof, error)
}

DiffEngine is a Universe diff engine that can be used to compare the state of two universes and find the set of assets that are different between them.

type FederationConfig

type FederationConfig struct {
	// FederationDB is used for CRUD operations related to the current set
	// of servers in the federation.
	FederationDB FederationLog

	// UniverseSyncer is used to synchronize with the federation
	// periodically.
	UniverseSyncer Syncer

	// NewRemoteRegistrar is a function that returns a new register instance
	// to the target remote Universe. This'll be used to optimistically push
	// out new updates to Universe servers.
	NewRemoteRegistrar func(ServerAddr) (Registrar, error)

	// LocalRegistrar is the local register. This'll be used to add new
	// leaves (minting events) to our local server before pushing them out
	// to the federation.
	LocalRegistrar Registrar

	// SyncInterval is the period that we'll use to synchronize with the
	// set of Universe servers.
	SyncInterval time.Duration

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

	// StaticFederationMembers is a set of static federation members
	// that'll be added on start up, and used to sync and push out proofs
	// with.
	StaticFederationMembers []string

	// ServerChecker is a function that can be used to check if a server is
	// operational and not the local daemon.
	ServerChecker func(ServerAddr) error
}

FederationConfig is a config that the FederationEnvoy will used to synchronize new updates between the current set of federated Universe nodes.

type FederationEnvoy

type FederationEnvoy struct {
	*fn.ContextGuard
	// contains filtered or unexported fields
}

FederationEnvoy is used to manage synchronization between the set of federated Universe servers. It handles the periodic sync between universe servers, and can also be used to push out new locally created proofs to the federation.

func NewFederationEnvoy

func NewFederationEnvoy(cfg FederationConfig) *FederationEnvoy

NewFederationEnvoy creates a new federation envoy from the passed config.

func (*FederationEnvoy) AddServer

func (f *FederationEnvoy) AddServer(addrs ...ServerAddr) error

AddServer adds a new set of servers to the federation, then immediately performs a new background sync.

func (*FederationEnvoy) RegisterIssuance

func (f *FederationEnvoy) RegisterIssuance(ctx context.Context, id Identifier,
	key BaseKey, leaf *MintingLeaf) (*IssuanceProof, error)

RegisterIssuance inserts a new minting leaf within the target universe tree (based on the ID), stored at the base key. This can be used to first push out a new update to the local registrar, ultimately queuing it to also be sent to the set of active universe servers.

NOTE: This is part of the universe.Registrar interface.

func (*FederationEnvoy) Start

func (f *FederationEnvoy) Start() error

Start launches all goroutines needed to interact with the envoy.

func (*FederationEnvoy) Stop

func (f *FederationEnvoy) Stop() error

Stop stops all active goroutines.

type FederationLog

type FederationLog interface {
	// UniverseServers returns the set of servers in the federation.
	UniverseServers(ctx context.Context) ([]ServerAddr, error)

	// AddServers adds a slice of servers to the federation.
	AddServers(ctx context.Context, addrs ...ServerAddr) error

	// RemoveServers removes a set of servers from the federation.
	RemoveServers(ctx context.Context, addrs ...ServerAddr) error

	// LogNewSyncs logs a new sync event for each server. This can be used
	// to keep track of the last time we synced with a remote server.
	LogNewSyncs(ctx context.Context, addrs ...ServerAddr) error
}

FederationLog is used to keep track of the set Universe servers that comprise our current federation. This'll be used by the AutoSyncer to periodically push and sync new proof events against the federation.

type FederationPushReq

type FederationPushReq struct {
	// ID identifies the Universe tree to push this new update out to.
	ID Identifier

	// Key is the leaf key in the Universe that the new leaf should be
	// added to.
	Key BaseKey

	// Leaf is the new leaf to add.
	Leaf *MintingLeaf
	// contains filtered or unexported fields
}

FederationPushReq is used to push out new updates to all or some members of the federation.

type GenesisWithGroup

type GenesisWithGroup struct {
	asset.Genesis

	*asset.GroupKey
}

GenesisWithGroup is a two tuple that groups the genesis of an asset with the group key it's associated with (if that exists).

type Identifier

type Identifier struct {
	// AssetID is the asset ID for the universe.
	//
	// TODO(roasbeef): make both pointers?
	AssetID asset.ID

	// GroupKey is the group key for the universe.
	GroupKey *btcec.PublicKey
}

Identifier is the identifier for a root/base universe.

func (*Identifier) String

func (i *Identifier) String() string

String returns a string representation of the ID.

func (*Identifier) StringForLog added in v0.2.1

func (i *Identifier) StringForLog() string

StringForLog returns a string representation of the ID for logging.

type IssuanceProof

type IssuanceProof struct {
	// MintingKey is the minting key for the asset.
	MintingKey BaseKey

	// UniverseRoot is the root of the universe that the asset is located
	// within.
	UniverseRoot mssmt.Node

	// InclusionProof is the inclusion proof for the asset within the
	// universe tree.
	InclusionProof *mssmt.Proof

	// Leaf is the leaf node for the asset within the universe tree.
	Leaf *MintingLeaf
}

IssuanceProof is a complete issuance proof for a given asset specified by the minting key. This proof can be used to verify that a valid asset exists (based on the proof in the leaf), and that the asset is committed to within the universe root.

func (*IssuanceProof) VerifyRoot

func (i *IssuanceProof) VerifyRoot(expectedRoot mssmt.Node) bool

VerifyRoot verifies that the inclusion proof for the root node matches the specified root. This is useful for sanity checking an issuance proof against the purported root, and the included leaf.

type MintingArchive

type MintingArchive struct {
	sync.RWMutex
	// contains filtered or unexported fields
}

MintingArchive is a persistence implementation of the Base universe interface. This is used by minting sub-systems to register new base universe issuance proofs each time an asset is created. It can also be used to synchronize state amongst disparate base universe instances, and also to serve as initial bootstrap for users wishing to send/receive assets.

TODO(roasbeef): erect universe in front of?

func NewMintingArchive

func NewMintingArchive(cfg MintingArchiveConfig) *MintingArchive

NewMintingArchive creates a new minting archive based on the passed config.

func (*MintingArchive) DeleteRoot added in v0.2.1

func (a *MintingArchive) DeleteRoot(ctx context.Context,
	id Identifier) (string, error)

DeleteRoot deletes all universe leaves, and the universe root, for the specified base universe.

func (*MintingArchive) FetchIssuanceProof

func (a *MintingArchive) FetchIssuanceProof(ctx context.Context, id Identifier,
	key BaseKey) ([]*IssuanceProof, error)

FetchIssuanceProof attempts to fetch an issuance proof for the target base leaf based on the universe identifier (assetID/groupKey).

func (*MintingArchive) MintingKeys

func (a *MintingArchive) MintingKeys(ctx context.Context,
	id Identifier) ([]BaseKey, error)

MintingKeys returns the set of minting keys known for the specified base universe identifier.

func (*MintingArchive) MintingLeaves

func (a *MintingArchive) MintingLeaves(ctx context.Context,
	id Identifier) ([]MintingLeaf, error)

MintingLeaves returns the set of minting leaves known for the specified base universe.

func (*MintingArchive) RegisterIssuance

func (a *MintingArchive) RegisterIssuance(ctx context.Context, id Identifier,
	key BaseKey, leaf *MintingLeaf) (*IssuanceProof, error)

RegisterIssuance attempts to register a new issuance proof for a new minting event for the specified base universe identifier. This method will return an error if the passed minting proof is invalid. If the leaf is already known, then no action is taken and the existing issuance commitment proof returned.

func (*MintingArchive) RootNode

func (a *MintingArchive) RootNode(ctx context.Context,
	id Identifier) (BaseRoot, error)

RootNode returns the root node of the base universe corresponding to the passed ID.

func (*MintingArchive) RootNodes

func (a *MintingArchive) RootNodes(ctx context.Context) ([]BaseRoot, error)

RootNodes returns the set of root nodes for all known base universes assets.

type MintingArchiveConfig

type MintingArchiveConfig struct {
	// NewBaseTree returns a new base universe backend for the given
	// identifier. This method always returns a new universe instance, even
	// if the identifier has never been seen before.
	NewBaseTree func(id Identifier) BaseBackend

	// HeaderVerifier is used to verify the validity of the header for a
	// genesis proof.
	HeaderVerifier proof.HeaderVerifier

	// UniverseForest is used to interact with the set of known base
	// universe trees, and also obtain associated metadata and statistics.
	UniverseForest BaseForest

	// UniverseStats is used to export statistics related to the set of
	// external/internal queries to the base universe instance.
	UniverseStats Telemetry
}

MintingArchiveConfig is the main config for the minting archive. This includes all the items required to interact with the set of relevant base universes.

type MintingLeaf

type MintingLeaf struct {
	GenesisWithGroup

	// GenesisProof is the proof of the newly created asset.
	//
	// TODO(roasbeef): have instead be a reader? easier to mmap in the
	// future
	GenesisProof proof.Blob

	// Amt is the amount of units created.
	Amt uint64
}

MintingLeaf is a leaf node in the SMT that represents a minting output. For each new asset created for a given asset/universe, a new minting leaf is created.

func (*MintingLeaf) SmtLeafNode

func (m *MintingLeaf) SmtLeafNode() *mssmt.LeafNode

SmtLeafNode returns the SMT leaf node for the given minting leaf.

type Registrar

type Registrar interface {
	// RegisterIssuance inserts a new minting leaf within the target
	// universe tree (based on the ID), stored at the base key.
	RegisterIssuance(ctx context.Context, id Identifier, key BaseKey,
		leaf *MintingLeaf) (*IssuanceProof, error)
}

Registrar is an interface that allows a caller to register issuance of a new asset in a local/remote base universe instance.

type ServerAddr

type ServerAddr struct {
	// ID is the unique identifier of the remote universe.
	//
	// TODO(roasbeef): break out into generic ID wrapper struct?
	ID uint32
	// contains filtered or unexported fields
}

ServerAddr wraps the reachable network address of a remote universe server.

func NewServerAddr

func NewServerAddr(i uint32, s string) ServerAddr

NewServerAddr creates a new server address from both the universe addr ID and the host name string.

func NewServerAddrFromStr

func NewServerAddrFromStr(s string) ServerAddr

NewServerAddrFromStr creates a new server address from a string that is the host name of the remote universe server.

func (*ServerAddr) Addr

func (s *ServerAddr) Addr() (net.Addr, error)

Addr returns the net.addr the universe is hosted at.

func (*ServerAddr) HostStr

func (s *ServerAddr) HostStr() string

HostStr returns the host string of the remote universe server.

type SimpleSyncCfg

type SimpleSyncCfg struct {
	// LocalDiffEngine is the diff engine tied to a local Universe
	// instance.
	LocalDiffEngine DiffEngine

	// NewRemoteDiffEngine is a function that returns a new diff engine
	// tied to the remote Universe instance we want to sync with.
	NewRemoteDiffEngine func(ServerAddr) (DiffEngine, error)

	// LocalRegistrar is the registrar tied to a local Universe instance.
	// This is used to insert new proof into the local DB as a result of
	// the diff operation.
	LocalRegistrar Registrar
}

SimpleSyncCfg contains all the configuration needed to create a new SimpleSyncer.

type SimpleSyncer

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

SimpleSyncer is a simple implementation of the Syncer interface. It's based on a set difference operation between the local and remote Universe.

func NewSimpleSyncer

func NewSimpleSyncer(cfg SimpleSyncCfg) *SimpleSyncer

NewSimpleSyncer creates a new SimpleSyncer instance.

func (*SimpleSyncer) SyncUniverse

func (s *SimpleSyncer) SyncUniverse(ctx context.Context, host ServerAddr,
	syncType SyncType, idsToSync ...Identifier) ([]AssetSyncDiff, error)

SyncUniverse attempts to synchronize the local universe with the remote universe, governed by the sync type and the set of universe IDs to sync.

type SyncStatsQuery

type SyncStatsQuery struct {
	// AssetNameFilter can be used to filter for stats for a given asset name.
	AssetNameFilter string

	// AssetIDFilter can be used to filter for stats for a given asset ID.
	AssetIDFilter asset.ID

	// AssetTypeFilter can be used to filter for stats for a given asset
	// type.
	AssetTypeFilter *asset.Type

	// SortBy is the sort order to use when returning the stats.
	SortBy SyncStatsSort

	// Offset is the offset to use when returning the stats. This can be
	// used to paginate the response.
	Offset int

	// Limit is the maximum number of stats to return. This can be used to
	// paginate the response.
	Limit int
}

SyncStatsQuery packages a set of query parameters to retrieve stats related to the sync activity of a given Universe. Any of the filters can be specified, however only a single sort by value should be specified. The offset and limit fields can be used to implement pagination.

type SyncStatsSort

type SyncStatsSort uint8

SyncStatsSort is an enum used to specify the sort order of the returned sync stats.

const (
	// SortByNone is a sentinel value that indicates that no sorting should
	// be done.
	SortByNone SyncStatsSort = iota

	// SortByAssetName sorts the returned stats by the asset name.
	SortByAssetName

	// SortByAssetType sorts the returned stats by the asset type.
	SortByAssetType

	// SortByAssetID sorts the returned stats by the asset ID.
	SortByAssetID
)

type SyncType

type SyncType uint8

SyncType is an enum that describes the type of sync that should be performed between a local and remote universe.

const (
	// SyncIssuance is a sync that will only sync new asset issuance events.
	SyncIssuance SyncType = iota

	// SyncFull is a sync that will sync all the assets in the universe.
	SyncFull
)

func (SyncType) String

func (s SyncType) String() string

String returns a human-readable string representation of the sync type.

type Syncer

type Syncer interface {
	// SyncUniverse attempts to synchronize the local universe with the
	// remote universe, governed by the sync type and the set of universe
	// IDs to sync.
	SyncUniverse(ctx context.Context, host ServerAddr,
		syncType SyncType,
		idsToSync ...Identifier) ([]AssetSyncDiff, error)
}

Syncer is used to synchronize the state of two Universe instances: a local instance and a remote instance. As a Universe is a tree based structure, tree based bisection can be used to find the point of divergence with syncing happening once that's found.

type Telemetry

type Telemetry interface {
	// AggreagateSyncStats returns stats aggregated over all assets within
	// the Universe.
	AggregateSyncStats(ctx context.Context) (AggregateStats, error)

	// LogSyncEvent logs a sync event for the target universe.
	//
	// TODO(roasbeef): log based on a given leaf, or entire tree?
	//  * rn main entrypoint is in RPC server, which is leaf based
	//  * alternatively, can log when a set of leaves are queried, as
	//    that's still a sync event, but can be a noop
	LogSyncEvent(ctx context.Context, uniID Identifier,
		key BaseKey) error

	// LogNewProofEvent logs a new proof insertion event for the target
	// universe.
	LogNewProofEvent(ctx context.Context, uniID Identifier,
		key BaseKey) error

	// QuerySyncStats attempts to query the stats for the target universe.
	// For a given asset ID, tag, or type, the set of universe stats is
	// returned which lists information such as the total number of syncs
	// and known proofs for a given Universe server instance.
	QuerySyncStats(ctx context.Context,
		q SyncStatsQuery) (*AssetSyncStats, error)
}

Telemetry it a type used by the Universe syncer and base universe to export telemetry information about the sync process. This logs events of new proofs, and also sync events for entire asset trees.

TODO(roasbeef): prob want to add a wrapper around multiple instances, eg: to the main db and also prometheus or w/e

Jump to

Keyboard shortcuts

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