provider_local

package
v0.56.1 Latest Latest
Warning

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

Go to latest
Published: Jul 18, 2026 License: Apache-2.0 Imports: 84 Imported by: 0

Documentation

Index

Constants

View Source
const ConfirmProtocolID = protocol.ID("alpha/pairing-confirm")

ConfirmProtocolID is the protocol ID for pairing confirmation exchange.

View Source
const ControllerID = "provider/local"

ControllerID is the controller id.

View Source
const ProviderID = "local"

ProviderID is the default ID for the local provider.

Variables

View Source
var ConfigID = ControllerID

ConfigID is the id attached to the config objects.

View Source
var ErrDirectInviteOwnerMustBeOnline = errors.New("space owner must be online to accept this invite directly")

ErrDirectInviteOwnerMustBeOnline indicates the direct invite path requires the owner to be reachable on the live transport.

View Source
var ErrNoSessionTransport = errors.New("no session transport running")

ErrNoSessionTransport is returned when a pairing operation requires a session transport but none is running.

View Source
var Version = controller.MustParseVersion("0.0.1")

Version is the controller version

Functions

func BlockStoreBucketID

func BlockStoreBucketID(providerID, accountID, blockStoreID string) string

BlockStoreBucketID returns the bucket id for a block store.

func BlockStoreLocalID

func BlockStoreLocalID(providerID, accountID, blockStoreID string) string

BlockStoreLocalID returns the local block store id for a block store.

func DeriveSASEmoji

func DeriveSASEmoji(
	localPriv bifrost_crypto.PrivKey,
	remotePub bifrost_crypto.PubKey,
	localPeerID peer.ID,
	remotePeerID peer.ID,
) ([]string, error)

DeriveSASEmoji derives a 6-emoji SAS verification sequence from the local session's private key and the remote peer's public key. Both sides compute the same sequence if keys are authentic.

func HasSessionEnvelope added in v0.54.0

func HasSessionEnvelope(ctx context.Context, objStore object.ObjectStore, sessionID string) (bool, error)

HasSessionEnvelope reports whether a local session recovery envelope exists.

func LinkedCloudKey

func LinkedCloudKey(sessionID string) []byte

LinkedCloudKey returns the ObjectStore key for the linked-cloud account ID.

func NewBlockStoreRef

func NewBlockStoreRef(providerID, providerAccountID, bstoreID string) *bstore.BlockStoreRef

NewBlockStoreRef builds a new BlockStoreRef.

func NewObjectStoreSOStateFuncs

func NewObjectStoreSOStateFuncs(rctx context.Context, objStore object.ObjectStore) (
	watchFn sobject.SOStateWatchFunc,
	lockFn sobject.SOStateLockFunc,
)

NewObjectStoreSOStateFuncs constructs a SOHostState backed by an object store and in-memory locks.

Assumes no other writers will access the object store. rctx is the context to use for looking up states from the object store.

func NewProviderAccountInfo

func NewProviderAccountInfo(providerID, accountID string) *provider.ProviderAccountInfo

NewProviderAccountInfo constructs a new provider account info object for the local provider.

func NewProviderInfo

func NewProviderInfo(providerID string) *provider.ProviderInfo

NewProviderInfo constructs the provider info.

func ProviderIRI

func ProviderIRI(providerID string) string

ProviderIRI returns the GC IRI for a provider: "provider:{id}".

func ReadEnvelope

func ReadEnvelope(ctx context.Context, objStore object.ObjectStore, sessionID string) ([]byte, error)

ReadEnvelope reads the Shamir envelope bytes from the ObjectStore.

func SessionObjectStoreID

func SessionObjectStoreID(providerID, accountID string) string

SessionObjectStoreID returns the object store id for sessions.

func SessionObjectStorePrivKey

func SessionObjectStorePrivKey(sessionID string) []byte

SessionObjectStorePrivKey returns the object store key for the priv key for a session with the given id.

func SessionObjectStoreStateKey

func SessionObjectStoreStateKey(sessionID string) []byte

SessionObjectStoreStateKey returns the object store key for the state for a session with the given id.

func SobjectBindingKey

func SobjectBindingKey(purpose string) []byte

SobjectBindingKey returns the object store key for a shared object binding purpose.

func SobjectBlockStoreID

func SobjectBlockStoreID(sobjectID string) string

SobjectBlockStoreID returns the block store id for a shared object. Block stores backing a shared object share the shared object's ULID verbatim; no prefix is added.

func SobjectObjectStoreHostStateKey

func SobjectObjectStoreHostStateKey(sharedObjectID string) []byte

SobjectObjectStoreHostStateKey returns the object store key for a shared object with the given id.

func SobjectObjectStoreID

func SobjectObjectStoreID(providerID, accountID string) string

SobjectObjectStoreID returns the object store id for shared objects.

func SobjectObjectStoreListKey

func SobjectObjectStoreListKey() []byte

SobjectObjectStoreListKey returns the object store key for the shared object list.

func SobjectObjectStoreLocalOpResultKey

func SobjectObjectStoreLocalOpResultKey(sharedObjectID, opLocalID string) []byte

SobjectObjectStoreLocalOpResultKey returns the object store key for a shared object op result.

func SobjectObjectStoreLocalStateKey

func SobjectObjectStoreLocalStateKey(sharedObjectID string) []byte

SobjectObjectStoreLocalStateKey returns the object store key for a shared object with the given id.

func StorageVolumeID

func StorageVolumeID(providerID, accountID string) string

StorageVolumeID returns the storage volume id for a provider account.

func UnlockSessionFromEnvelope

func UnlockSessionFromEnvelope(ctx context.Context, objStore object.ObjectStore, sessionID string, entityPrivKey bifrost_crypto.PrivKey) (bifrost_crypto.PrivKey, error)

UnlockSessionFromEnvelope recovers the session private key from the envelope using the provided entity private key.

Types

type BlockStore

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

BlockStore implements the bstore interface.

func (*BlockStore) BeginDeferFlush

func (b *BlockStore) BeginDeferFlush()

BeginDeferFlush forwards the GC ref-batch scope to the inner store.

func (*BlockStore) BeginReadOperation added in v0.51.7

func (b *BlockStore) BeginReadOperation(ctx context.Context) (block.StoreOps, func(), error)

BeginReadOperation opens a read scope on the inner store.

func (*BlockStore) EndDeferFlush

func (b *BlockStore) EndDeferFlush(ctx context.Context) error

EndDeferFlush forwards the GC ref-batch scope to the inner store.

func (*BlockStore) GetBlock

func (b *BlockStore) GetBlock(ctx context.Context, ref *block.BlockRef) ([]byte, bool, error)

GetBlock forwards to the active Session read owner when configured.

func (*BlockStore) GetBlockExists

func (b *BlockStore) GetBlockExists(ctx context.Context, ref *block.BlockRef) (bool, error)

GetBlockExists forwards to the active Session read owner when configured.

func (*BlockStore) GetBlockExistsBatch

func (b *BlockStore) GetBlockExistsBatch(ctx context.Context, refs []*block.BlockRef) ([]bool, error)

GetBlockExistsBatch forwards batched existence probes to the active read owner.

func (*BlockStore) GetDecodedBlockCache added in v0.51.7

func (b *BlockStore) GetDecodedBlockCache() *block.DecodedBlockCache

GetDecodedBlockCache returns the lifecycle-owned decoded-block cache.

func (*BlockStore) GetHashType

func (b *BlockStore) GetHashType() hash.HashType

GetHashType returns the inner store hash type.

func (*BlockStore) GetID

func (b *BlockStore) GetID() string

GetID returns the inner store id.

func (*BlockStore) GetSupportedFeatures

func (b *BlockStore) GetSupportedFeatures() block.StoreFeature

GetSupportedFeatures returns the native feature bitset for the inner store.

func (*BlockStore) InvalidateDecodedBlockRef added in v0.51.7

func (b *BlockStore) InvalidateDecodedBlockRef(ctx context.Context, ref *block.BlockRef)

InvalidateDecodedBlockRef removes decoded-cache entries for ref.

func (*BlockStore) PutBlock

func (b *BlockStore) PutBlock(ctx context.Context, data []byte, opts *block.PutOpts) (*block.BlockRef, bool, error)

PutBlock forwards to the inner store.

func (*BlockStore) PutBlockBatch

func (b *BlockStore) PutBlockBatch(ctx context.Context, entries []*block.PutBatchEntry) error

PutBlockBatch forwards batched writes to the inner store.

func (*BlockStore) RmBlock

func (b *BlockStore) RmBlock(ctx context.Context, ref *block.BlockRef) error

RmBlock forwards to the inner store.

func (*BlockStore) StatBlock

func (b *BlockStore) StatBlock(ctx context.Context, ref *block.BlockRef) (*block.BlockStat, error)

StatBlock forwards to the active Session read owner when configured.

func (*BlockStore) Sync added in v0.52.0

func (b *BlockStore) Sync(ctx context.Context) (bool, error)

Sync forwards the durability barrier to the inner store.

type Config

type Config struct {

	// ProviderId is the provider identifier.
	// Defaults to "local" if unset.
	// NOTE: Many places in the codebase expect this to be "local" so change carefully!
	ProviderId string `protobuf:"bytes,1,opt,name=provider_id,json=providerId,proto3" json:"providerId,omitempty"`
	// PeerId is the peer id to use.
	// If empty, uses the first value returned from GetPeer
	PeerId string `protobuf:"bytes,2,opt,name=peer_id,json=peerId,proto3" json:"peerId,omitempty"`
	// StorageId is the storage id to use.
	// If empty, uses the default storage controller id.
	StorageId string `protobuf:"bytes,3,opt,name=storage_id,json=storageId,proto3" json:"storageId,omitempty"`
	// contains filtered or unexported fields
}

Config configures the local space provider controller.

func (*Config) CloneMessageVT

func (m *Config) CloneMessageVT() protobuf_go_lite.CloneMessage

func (*Config) CloneVT

func (m *Config) CloneVT() *Config

func (*Config) EqualMessageVT

func (this *Config) EqualMessageVT(thatMsg any) bool

func (*Config) EqualVT

func (this *Config) EqualVT(that *Config) bool

func (*Config) EqualsConfig

func (c *Config) EqualsConfig(other config.Config) bool

EqualsConfig checks if the config is equal to another.

func (*Config) GetConfigID

func (c *Config) GetConfigID() string

GetConfigID returns the unique string for this configuration type. This string is stored with the encoded config.

func (*Config) GetPeerId

func (x *Config) GetPeerId() string

func (*Config) GetProviderId

func (x *Config) GetProviderId() string

func (*Config) GetStorageId

func (x *Config) GetStorageId() string

func (*Config) MarshalJSON

func (x *Config) MarshalJSON() ([]byte, error)

MarshalJSON marshals the Config to JSON.

func (*Config) MarshalProtoJSON

func (x *Config) MarshalProtoJSON(s *json.MarshalState)

MarshalProtoJSON marshals the Config message to JSON.

func (*Config) MarshalProtoText

func (x *Config) MarshalProtoText() string

func (*Config) MarshalToSizedBufferVT

func (m *Config) MarshalToSizedBufferVT(dAtA []byte) (int, error)

func (*Config) MarshalToVT

func (m *Config) MarshalToVT(dAtA []byte) (int, error)

func (*Config) MarshalVT

func (m *Config) MarshalVT() (dAtA []byte, err error)

func (*Config) ParsePeerID

func (c *Config) ParsePeerID() (peer.ID, error)

ParsePeerID parses the peer id field.

func (*Config) ProtoMessage

func (*Config) ProtoMessage()

func (*Config) Reset

func (x *Config) Reset()

func (*Config) SizeVT

func (m *Config) SizeVT() (n int)

func (*Config) String

func (x *Config) String() string

func (*Config) UnmarshalJSON

func (x *Config) UnmarshalJSON(b []byte) error

UnmarshalJSON unmarshals the Config from JSON.

func (*Config) UnmarshalProtoJSON

func (x *Config) UnmarshalProtoJSON(s *json.UnmarshalState)

UnmarshalProtoJSON unmarshals the Config message from JSON.

func (*Config) UnmarshalVT

func (m *Config) UnmarshalVT(dAtA []byte) error

func (*Config) Validate

func (c *Config) Validate() error

Validate validates the configuration.

type Controller

Controller is the provider controller type.

type Factory

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

Factory constructs the local provider.

func NewFactory

func NewFactory(bus bus.Bus) *Factory

NewFactory builds the factory.

func (*Factory) Construct

func (t *Factory) Construct(
	ctx context.Context,
	conf config.Config,
	opts controller.ConstructOpts,
) (controller.Controller, error)

Construct constructs the associated controller given configuration.

func (*Factory) ConstructConfig

func (t *Factory) ConstructConfig() config.Config

ConstructConfig constructs an instance of the controller configuration.

func (*Factory) GetConfigID

func (t *Factory) GetConfigID() string

GetConfigID returns the configuration ID for the controller.

func (*Factory) GetControllerID

func (t *Factory) GetControllerID() string

GetControllerID returns the unique ID for the controller.

func (*Factory) GetVersion

func (t *Factory) GetVersion() controller.Version

GetVersion returns the version of this controller.

type LocalSOHost

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

LocalSOHost is the implementation of the local shared object host logic.

func NewLocalSOHost

func NewLocalSOHost(
	le *logrus.Entry,
	privKey crypto.PrivKey,
	soHost *sobject.SOHost,
	objStore object.ObjectStore,
	sharedObjectID string,
	sfs *block_transform.StepFactorySet,
) (*LocalSOHost, error)

NewLocalSOHost constructs a new LocalSOHost.

func (*LocalSOHost) AccessSharedObjectState

func (l *LocalSOHost) AccessSharedObjectState(ctx context.Context, released func()) (ccontainer.Watchable[sobject.SharedObjectStateSnapshot], func(), error)

AccessSharedObjectState adds a reference to the state and returns the state container.

func (*LocalSOHost) Execute

func (l *LocalSOHost) Execute(ctx context.Context) error

Execute executes the LocalSOHost logic.

func (*LocalSOHost) QueueOperation

func (l *LocalSOHost) QueueOperation(ctx context.Context, op []byte) (string, error)

QueueOperation applies an operation to the shared object op queue. Returns after the operation is applied to the local queue. Returns the local op id.

func (*LocalSOHost) WaitOperation

func (l *LocalSOHost) WaitOperation(ctx context.Context, localID string) (uint64, bool, error)

WaitOperation waits for the operation to be confirmed or rejected by the provider. Returns the current state nonce (greater than or equal to the nonce when the op was applied). After ClearOperation has been called, this will return success even for failed ops! If the operation was rejected, returns 0, true, error. Any other error returns 0, false, error

type LocalSOOperationResult

type LocalSOOperationResult struct {

	// LocalId is the local operation id, must be a valid ulid.
	LocalId string `protobuf:"bytes,1,opt,name=local_id,json=localId,proto3" json:"localId,omitempty"`
	// Result is the operation result.
	Result *sobject.SOOperationResult `protobuf:"bytes,2,opt,name=result,proto3" json:"result,omitempty"`
	// RootSeqno is the root seqno that accepted or rejected the operation.
	RootSeqno uint64 `protobuf:"varint,3,opt,name=root_seqno,json=rootSeqno,proto3" json:"rootSeqno,omitempty"`
	// contains filtered or unexported fields
}

LocalSOOperationResult contains the result of a SOOperation.

func (*LocalSOOperationResult) CloneMessageVT

func (*LocalSOOperationResult) CloneVT

func (*LocalSOOperationResult) EqualMessageVT

func (this *LocalSOOperationResult) EqualMessageVT(thatMsg any) bool

func (*LocalSOOperationResult) EqualVT

func (this *LocalSOOperationResult) EqualVT(that *LocalSOOperationResult) bool

func (*LocalSOOperationResult) GetLocalId

func (x *LocalSOOperationResult) GetLocalId() string

func (*LocalSOOperationResult) GetResult

func (*LocalSOOperationResult) GetRootSeqno added in v0.51.7

func (x *LocalSOOperationResult) GetRootSeqno() uint64

func (*LocalSOOperationResult) MarshalJSON

func (x *LocalSOOperationResult) MarshalJSON() ([]byte, error)

MarshalJSON marshals the LocalSOOperationResult to JSON.

func (*LocalSOOperationResult) MarshalProtoJSON

func (x *LocalSOOperationResult) MarshalProtoJSON(s *json.MarshalState)

MarshalProtoJSON marshals the LocalSOOperationResult message to JSON.

func (*LocalSOOperationResult) MarshalProtoText

func (x *LocalSOOperationResult) MarshalProtoText() string

func (*LocalSOOperationResult) MarshalToSizedBufferVT

func (m *LocalSOOperationResult) MarshalToSizedBufferVT(dAtA []byte) (int, error)

func (*LocalSOOperationResult) MarshalToVT

func (m *LocalSOOperationResult) MarshalToVT(dAtA []byte) (int, error)

func (*LocalSOOperationResult) MarshalVT

func (m *LocalSOOperationResult) MarshalVT() (dAtA []byte, err error)

func (*LocalSOOperationResult) ProtoMessage

func (*LocalSOOperationResult) ProtoMessage()

func (*LocalSOOperationResult) Reset

func (x *LocalSOOperationResult) Reset()

func (*LocalSOOperationResult) SizeVT

func (m *LocalSOOperationResult) SizeVT() (n int)

func (*LocalSOOperationResult) String

func (x *LocalSOOperationResult) String() string

func (*LocalSOOperationResult) UnmarshalJSON

func (x *LocalSOOperationResult) UnmarshalJSON(b []byte) error

UnmarshalJSON unmarshals the LocalSOOperationResult from JSON.

func (*LocalSOOperationResult) UnmarshalProtoJSON

func (x *LocalSOOperationResult) UnmarshalProtoJSON(s *json.UnmarshalState)

UnmarshalProtoJSON unmarshals the LocalSOOperationResult message from JSON.

func (*LocalSOOperationResult) UnmarshalVT

func (m *LocalSOOperationResult) UnmarshalVT(dAtA []byte) error

type LocalSOState

type LocalSOState struct {

	// OpQueue contains locally queued ops not applied to the SOHost yet.
	OpQueue []*sobject.QueuedSOOperation `protobuf:"bytes,1,rep,name=op_queue,json=opQueue,proto3" json:"opQueue,omitempty"`
	// contains filtered or unexported fields
}

LocalSOState contains the local state for a shared object.

func (*LocalSOState) CloneMessageVT

func (m *LocalSOState) CloneMessageVT() protobuf_go_lite.CloneMessage

func (*LocalSOState) CloneVT

func (m *LocalSOState) CloneVT() *LocalSOState

func (*LocalSOState) EqualMessageVT

func (this *LocalSOState) EqualMessageVT(thatMsg any) bool

func (*LocalSOState) EqualVT

func (this *LocalSOState) EqualVT(that *LocalSOState) bool

func (*LocalSOState) GetOpQueue

func (x *LocalSOState) GetOpQueue() []*sobject.QueuedSOOperation

func (*LocalSOState) MarshalJSON

func (x *LocalSOState) MarshalJSON() ([]byte, error)

MarshalJSON marshals the LocalSOState to JSON.

func (*LocalSOState) MarshalProtoJSON

func (x *LocalSOState) MarshalProtoJSON(s *json.MarshalState)

MarshalProtoJSON marshals the LocalSOState message to JSON.

func (*LocalSOState) MarshalProtoText

func (x *LocalSOState) MarshalProtoText() string

func (*LocalSOState) MarshalToSizedBufferVT

func (m *LocalSOState) MarshalToSizedBufferVT(dAtA []byte) (int, error)

func (*LocalSOState) MarshalToVT

func (m *LocalSOState) MarshalToVT(dAtA []byte) (int, error)

func (*LocalSOState) MarshalVT

func (m *LocalSOState) MarshalVT() (dAtA []byte, err error)

func (*LocalSOState) ProtoMessage

func (*LocalSOState) ProtoMessage()

func (*LocalSOState) Reset

func (x *LocalSOState) Reset()

func (*LocalSOState) SizeVT

func (m *LocalSOState) SizeVT() (n int)

func (*LocalSOState) String

func (x *LocalSOState) String() string

func (*LocalSOState) UnmarshalJSON

func (x *LocalSOState) UnmarshalJSON(b []byte) error

UnmarshalJSON unmarshals the LocalSOState from JSON.

func (*LocalSOState) UnmarshalProtoJSON

func (x *LocalSOState) UnmarshalProtoJSON(s *json.UnmarshalState)

UnmarshalProtoJSON unmarshals the LocalSOState message from JSON.

func (*LocalSOState) UnmarshalVT

func (m *LocalSOState) UnmarshalVT(dAtA []byte) error

type PairingConfirmMessage

type PairingConfirmMessage struct {

	// Confirmed indicates the user verified the SAS emoji match.
	Confirmed bool `protobuf:"varint,1,opt,name=confirmed,proto3" json:"confirmed,omitempty"`
	// Rejected indicates the user rejected the SAS emoji match.
	Rejected bool `protobuf:"varint,2,opt,name=rejected,proto3" json:"rejected,omitempty"`
	// contains filtered or unexported fields
}

PairingConfirmMessage is exchanged over a bifrost link during the mutual SAS verification step. Both peers send their confirmation status and wait for the remote's response.

func (*PairingConfirmMessage) CloneMessageVT

func (*PairingConfirmMessage) CloneVT

func (*PairingConfirmMessage) EqualMessageVT

func (this *PairingConfirmMessage) EqualMessageVT(thatMsg any) bool

func (*PairingConfirmMessage) EqualVT

func (this *PairingConfirmMessage) EqualVT(that *PairingConfirmMessage) bool

func (*PairingConfirmMessage) GetConfirmed

func (x *PairingConfirmMessage) GetConfirmed() bool

func (*PairingConfirmMessage) GetRejected

func (x *PairingConfirmMessage) GetRejected() bool

func (*PairingConfirmMessage) MarshalJSON

func (x *PairingConfirmMessage) MarshalJSON() ([]byte, error)

MarshalJSON marshals the PairingConfirmMessage to JSON.

func (*PairingConfirmMessage) MarshalProtoJSON

func (x *PairingConfirmMessage) MarshalProtoJSON(s *json.MarshalState)

MarshalProtoJSON marshals the PairingConfirmMessage message to JSON.

func (*PairingConfirmMessage) MarshalProtoText

func (x *PairingConfirmMessage) MarshalProtoText() string

func (*PairingConfirmMessage) MarshalToSizedBufferVT

func (m *PairingConfirmMessage) MarshalToSizedBufferVT(dAtA []byte) (int, error)

func (*PairingConfirmMessage) MarshalToVT

func (m *PairingConfirmMessage) MarshalToVT(dAtA []byte) (int, error)

func (*PairingConfirmMessage) MarshalVT

func (m *PairingConfirmMessage) MarshalVT() (dAtA []byte, err error)

func (*PairingConfirmMessage) ProtoMessage

func (*PairingConfirmMessage) ProtoMessage()

func (*PairingConfirmMessage) Reset

func (x *PairingConfirmMessage) Reset()

func (*PairingConfirmMessage) SizeVT

func (m *PairingConfirmMessage) SizeVT() (n int)

func (*PairingConfirmMessage) String

func (x *PairingConfirmMessage) String() string

func (*PairingConfirmMessage) UnmarshalJSON

func (x *PairingConfirmMessage) UnmarshalJSON(b []byte) error

UnmarshalJSON unmarshals the PairingConfirmMessage from JSON.

func (*PairingConfirmMessage) UnmarshalProtoJSON

func (x *PairingConfirmMessage) UnmarshalProtoJSON(s *json.UnmarshalState)

UnmarshalProtoJSON unmarshals the PairingConfirmMessage message from JSON.

func (*PairingConfirmMessage) UnmarshalVT

func (m *PairingConfirmMessage) UnmarshalVT(dAtA []byte) error

type PairingSnapshot

type PairingSnapshot struct {
	Status       PairingStatus
	Code         string
	RemotePeerID peer.ID
	Emoji        []string
	ErrMsg       string
}

PairingSnapshot is a point-in-time snapshot of pairing state.

type PairingStatus

type PairingStatus int32

PairingStatus describes the current phase of a device pairing flow. Values match the PairingStatus proto enum in sdk/session/session.proto.

const (
	PairingStatusIdle                PairingStatus = 0
	PairingStatusCodeGenerated       PairingStatus = 1
	PairingStatusWaitingForPeer      PairingStatus = 2
	PairingStatusPeerConnected       PairingStatus = 3
	PairingStatusVerifyingEmoji      PairingStatus = 4
	PairingStatusVerified            PairingStatus = 5
	PairingStatusFailed              PairingStatus = 6
	PairingStatusSignalingFailed     PairingStatus = 7
	PairingStatusConnectionTimeout   PairingStatus = 8
	PairingStatusWaitingForRemote    PairingStatus = 9
	PairingStatusBothConfirmed       PairingStatus = 10
	PairingStatusPairingRejected     PairingStatus = 11
	PairingStatusConfirmationTimeout PairingStatus = 12
)

type Provider

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

Provider implements the local provider.

func NewProvider

func NewProvider(
	le *logrus.Entry,
	b bus.Bus,
	storageID string,
	info *provider.ProviderInfo,
	peer peer.Peer,
	handler provider.ProviderHandler,
) *Provider

NewProvider constructs a new Provider.

func (*Provider) AccessProviderAccount

func (p *Provider) AccessProviderAccount(ctx context.Context, accountID string, released func()) (provider.ProviderAccount, func(), error)

AccessProviderAccount accesses a provider account. If accountID is empty, it will use the default or prompt the user. released may be nil

func (*Provider) CreateLocalAccountAndSession

func (p *Provider) CreateLocalAccountAndSession(ctx context.Context, cloudAccountID string) (*session.SessionRef, error)

CreateLocalAccountAndSession initializes a local provider account and session. cloudAccountID links this local session to a cloud account (empty for standalone).

NOTE: this is a WIP / possibly temporary function.

func (*Provider) Execute

func (p *Provider) Execute(ctx context.Context) error

Execute executes the provider. Return nil for no-op (will not be restarted).

func (*Provider) GetProviderInfo

func (p *Provider) GetProviderInfo() *provider.ProviderInfo

GetProviderInfo returns the basic provider information.

type ProviderAccount

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

ProviderAccount implements the local provider account.

func (*ProviderAccount) AccessSharedObjectHealth

func (a *ProviderAccount) AccessSharedObjectHealth(
	ctx context.Context,
	ref *sobject.SharedObjectRef,
	released func(),
) (ccontainer.Watchable[*sobject.SharedObjectHealth], func(), error)

AccessSharedObjectHealth adds a reference to shared object health by ref.

func (*ProviderAccount) AccessSharedObjectList

func (a *ProviderAccount) AccessSharedObjectList(ctx context.Context, released func()) (ccontainer.Watchable[*sobject.SharedObjectList], func(), error)

AccessSharedObjectList adds a reference to the list of shared objects and returns the container. Returns a release function. Accepts a function that is called if the Watchable becomes invalid.

func (*ProviderAccount) AutoStartP2PSyncIfPaired

func (a *ProviderAccount) AutoStartP2PSyncIfPaired(
	ctx context.Context,
	st *transport.SessionTransport,
) error

AutoStartP2PSyncIfPaired starts P2P sync when the account already has paired devices recorded in AccountSettings. Called from the session mount path so a session that was paired in a prior mount restores its DEX + SOSync controllers without requiring the user to re-pair.

When no paired devices are present this is a no-op. Errors mounting the account settings SO are logged and swallowed so a missing or unreadable SO does not abort the session mount.

func (*ProviderAccount) ClearPairingState

func (a *ProviderAccount) ClearPairingState()

ClearPairingState releases any active pairing directive and clears state.

func (*ProviderAccount) CompletePairing

func (a *ProviderAccount) CompletePairing(
	ctx context.Context,
	relayURL string,
	signingEnvPrefix string,
	code string,
	sessionPriv crypto.PrivKey,
	sessionPeerID peer.ID,
) (peer.ID, error)

CompletePairing looks up a pairing code to get the remote peer ID. Ensures the session transport is running and adds an EstablishLinkWithPeer directive for the remote peer on the transport's child bus.

func (*ProviderAccount) ConfirmPairing

func (a *ProviderAccount) ConfirmPairing(
	ctx context.Context,
	remotePeerID peer.ID,
	displayName string,
) error

ConfirmPairing confirms a verified pairing by adding the remote peer as OWNER on all SharedObjects in the account, persisting the paired device to the account settings SO, and optionally starting P2P sync.

func (*ProviderAccount) ConfirmSASMatch

func (a *ProviderAccount) ConfirmSASMatch(confirmed bool)

ConfirmSASMatch sends the local user's SAS confirmation decision. Called from the UI when the user clicks "Yes, they match" or "No, abort".

func (*ProviderAccount) CreateBlockStore

func (a *ProviderAccount) CreateBlockStore(ctx context.Context, id string) (*bstore.BlockStoreRef, error)

CreateBlockStore creates a new bstore with the given details.

func (*ProviderAccount) CreateOrgSharedObject

func (a *ProviderAccount) CreateOrgSharedObject(ctx context.Context, orgID, displayName string) error

CreateOrgSharedObject creates an organization SharedObject and queues InitOrganizationOp. Used by the local provider to create orgs without any cloud API call.

func (*ProviderAccount) CreateSessionTransport

func (a *ProviderAccount) CreateSessionTransport(ctx context.Context, sessionKey crypto.PrivKey, signalingURL string) error

CreateSessionTransport creates and starts a session transport using the given session private key and signaling URL. If a transport is already running, it is stopped first.

The transport runs via a RoutineContainer. On post-Ready failures, the exit callback clears sessionTransport and broadcasts.

func (*ProviderAccount) CreateSharedObject

func (a *ProviderAccount) CreateSharedObject(ctx context.Context, id string, meta *sobject.SharedObjectMeta, _, _ string) (*sobject.SharedObjectRef, error)

CreateSharedObject creates a new sobject with the given details.

func (*ProviderAccount) DeleteSharedObject

func (a *ProviderAccount) DeleteSharedObject(ctx context.Context, id string) error

DeleteSharedObject deletes the shared object with the given id.

func (*ProviderAccount) EnsureAccountSettingsSO

func (a *ProviderAccount) EnsureAccountSettingsSO(ctx context.Context) (*sobject.SharedObjectRef, error)

EnsureAccountSettingsSO returns the bound account settings SharedObjectRef, creating and binding a unique-id local settings SO when absent.

func (*ProviderAccount) EnsureSessionTransport

func (a *ProviderAccount) EnsureSessionTransport(
	ctx context.Context,
	sessionPriv crypto.PrivKey,
	relayURL string,
) error

EnsureSessionTransport creates the session transport if not already running.

func (*ProviderAccount) GeneratePairingCode

func (a *ProviderAccount) GeneratePairingCode(
	ctx context.Context,
	relayURL string,
	signingEnvPrefix string,
	sessionPriv crypto.PrivKey,
	sessionPeerID peer.ID,
) (string, error)

GeneratePairingCode generates an 8-char alphanumeric pairing code, registers it with the pairing relay via signed HTTP POST, and returns the code. Ensures the session transport is running before posting the code.

func (*ProviderAccount) GetAccountID

func (a *ProviderAccount) GetAccountID() string

GetAccountID returns the provider account identifier.

func (*ProviderAccount) GetAccountSettingsRef

func (a *ProviderAccount) GetAccountSettingsRef(ctx context.Context) (*sobject.SharedObjectRef, error)

GetAccountSettingsRef returns the bound account settings SharedObjectRef.

func (*ProviderAccount) GetMountedSessionPeerID

func (a *ProviderAccount) GetMountedSessionPeerID(ctx context.Context) peer.ID

GetMountedSessionPeerID returns the peer ID of a mounted local session.

func (*ProviderAccount) GetOnlinePeerIDsWithWait added in v0.51.7

func (a *ProviderAccount) GetOnlinePeerIDsWithWait(peerIDs []string) ([]string, []<-chan struct{})

GetOnlinePeerIDsWithWait returns the base58 peer IDs of paired devices that currently have an active bifrost link and change channels for transport and link state.

func (*ProviderAccount) GetPINSessionRecoveryState added in v0.54.0

func (a *ProviderAccount) GetPINSessionRecoveryState(ctx context.Context, ref *session.SessionRef) (session.SessionRecoveryState, error)

GetPINSessionRecoveryState reports whether the local PIN reset path has a recovery envelope to unlock with a password or backup key.

func (*ProviderAccount) GetPairingBroadcast

func (a *ProviderAccount) GetPairingBroadcast() *broadcast.Broadcast

GetPairingBroadcast returns the pairing state broadcast.

func (*ProviderAccount) GetPairingContext

func (a *ProviderAccount) GetPairingContext() context.Context

GetPairingContext returns the lifecycle context used for pairing routines.

func (*ProviderAccount) GetPairingLinkCh

func (a *ProviderAccount) GetPairingLinkCh() <-chan link.MountedLink

GetPairingLinkCh returns the channel that receives a link when the remote peer connects, or nil if no pairing is active.

func (*ProviderAccount) GetPairingRemotePeerID

func (a *ProviderAccount) GetPairingRemotePeerID() peer.ID

GetPairingRemotePeerID returns the remote peer ID being paired, or empty. Must be called inside pairingBcast.HoldLock or from a single goroutine.

func (*ProviderAccount) GetPairingSnapshot

func (a *ProviderAccount) GetPairingSnapshot() PairingSnapshot

GetPairingSnapshot returns a snapshot of the current pairing status. Must be called inside pairingBcast.HoldLock or from a single goroutine.

func (*ProviderAccount) GetProviderAccountFeature

func (a *ProviderAccount) GetProviderAccountFeature(ctx context.Context, feature provider.ProviderFeature) (provider.ProviderAccountFeature, error)

GetProviderAccountFeature returns the implementation of a specific provider feature.

Implements one of SpaceProvider, BlockStoreProvider, ... Check GetProviderInfo()=>features in advance before calling this. Returns ErrUnimplementedProviderFeature if the feature is not implemented.

func (*ProviderAccount) GetProviderID

func (a *ProviderAccount) GetProviderID() string

GetProviderID returns the provider identifier.

func (*ProviderAccount) GetSOListCtr

GetSOListCtr returns the shared object list container.

func (*ProviderAccount) GetSessionTransport

func (a *ProviderAccount) GetSessionTransport() *transport.SessionTransport

GetSessionTransport returns the running session transport, or nil.

func (*ProviderAccount) GetStepFactorySet

func (a *ProviderAccount) GetStepFactorySet() *block_transform.StepFactorySet

GetStepFactorySet returns the block transform step factory set.

func (*ProviderAccount) GetStorageStats

func (a *ProviderAccount) GetStorageStats(ctx context.Context) (*volume.StorageStats, error)

GetStorageStats returns storage usage statistics for the account volume.

func (*ProviderAccount) GetStorageStatsSnapshotWithWait added in v0.51.7

func (a *ProviderAccount) GetStorageStatsSnapshotWithWait(
	ctx context.Context,
) (*volume.StorageStats, <-chan struct{}, error)

GetStorageStatsSnapshotWithWait returns current storage statistics and a change channel for storage stats updates.

func (*ProviderAccount) GetTransportBroadcast

func (a *ProviderAccount) GetTransportBroadcast() *broadcast.Broadcast

GetTransportBroadcast returns the transport state broadcast.

func (*ProviderAccount) GetTransportSnapshotWithWait

func (a *ProviderAccount) GetTransportSnapshotWithWait() (bool, <-chan struct{})

GetTransportSnapshotWithWait returns whether transport is running and its wait channel.

func (*ProviderAccount) GetVolume

func (a *ProviderAccount) GetVolume() volume.Volume

GetVolume returns the parent volume for the account.

func (*ProviderAccount) IsP2PSyncRunning

func (a *ProviderAccount) IsP2PSyncRunning() bool

IsP2PSyncRunning returns whether P2P sync is currently active. Safe to call from any goroutine.

func (*ProviderAccount) JoinViaInvite

func (a *ProviderAccount) JoinViaInvite(
	ctx context.Context,
	sessionKey crypto.PrivKey,
	inviteMsg *sobject.SOInviteMessage,
	signalingURL string,
) (*sobject_invite.JoinResult, error)

JoinViaInvite executes the full invite join flow: 1. Ensures a session transport is running (starts one if needed) 2. Opens an SRPC stream to the owner and sends AcceptInviteRequest 3. Receives the SOGrant from the owner 4. Mounts the shared object with the grant 5. Starts P2P sync so SolicitSync delivers state

The inviteMsg is the out-of-band SOInviteMessage from the owner. sessionKey is the invitee's session private key. signalingURL is the cloud API base URL for signaling (can be empty for local).

func (*ProviderAccount) MountBlockStore

func (a *ProviderAccount) MountBlockStore(ctx context.Context, ref *bstore.BlockStoreRef, released func()) (bstore.BlockStore, func(), error)

MountBlockStore attempts to mount a BlockStore returning the bstore and a release function.

usually called by the provider controller

func (*ProviderAccount) MountSession

func (a *ProviderAccount) MountSession(ctx context.Context, ref *session.SessionRef, released func()) (session.Session, func(), error)

MountSession attempts to mount a Session returning the session and a release function.

usually called by the provider controller

func (*ProviderAccount) MountSharedObject

func (a *ProviderAccount) MountSharedObject(ctx context.Context, ref *sobject.SharedObjectRef, released func()) (sobject.SharedObject, func(), error)

MountSharedObject attempts to mount a SharedObject returning the sobject and a release function.

usually called by the provider controller

func (*ProviderAccount) OnDirectPairingConnected

func (a *ProviderAccount) OnDirectPairingConnected(
	remotePeerID peer.ID,
	sessionKey crypto.PrivKey,
	localPeerID peer.ID,
	lnk link.Link,
	isOfferer bool,
)

OnDirectPairingConnected is called when a no-cloud WebRTC link establishes via ManualSignalTransport. Sets PEER_CONNECTED and starts the confirmation exchange directly on the link (bypassing SolicitProtocol).

func (*ProviderAccount) QueueOrgUpdateOp

func (a *ProviderAccount) QueueOrgUpdateOp(ctx context.Context, orgID string, op *s4wave_org.UpdateOrgOp) error

QueueOrgUpdateOp queues an UpdateOrgOp on the org SO.

func (*ProviderAccount) RefreshSharedObjectList added in v0.52.0

func (a *ProviderAccount) RefreshSharedObjectList(context.Context) error

RefreshSharedObjectList keeps the SharedObjectProvider contract uniform. Local provider lists are updated synchronously by local mutations.

func (*ProviderAccount) ResetPINSession

func (a *ProviderAccount) ResetPINSession(ctx context.Context, ref *session.SessionRef, cred *session.EntityCredential) error

ResetPINSession resets a PIN-locked session via envelope recovery. Derives the entity key from the credential, recovers the session private key from the envelope, re-encrypts it in auto-unlock mode, and restarts the session tracker.

func (*ProviderAccount) RewrapSessionEnvelope

func (a *ProviderAccount) RewrapSessionEnvelope(ctx context.Context, keypairs []*session.EntityKeypair) error

RewrapSessionEnvelope re-wraps the session private key in a Shamir envelope using the current set of entity keypair public keys from the AccountSettings SharedObject.

The envelope is written to {sessionID}/env in the session's ObjectStore. Threshold is 0 (any single entity keypair can recover the session key).

Skipped silently when the session is locked (privkey not in memory) or when no entity keypairs are available.

func (*ProviderAccount) SetPairingCode

func (a *ProviderAccount) SetPairingCode(code string, sessionKey crypto.PrivKey)

SetPairingCode stores the pairing code and sets status to CODE_GENERATED. Starts the confirmation exchange goroutine which waits for a remote peer to connect via the solicit protocol (generator side).

func (*ProviderAccount) SetPairingFailed

func (a *ProviderAccount) SetPairingFailed(msg string)

SetPairingFailed marks the pairing as failed with an error message.

func (*ProviderAccount) SetPairingRemotePeer

func (a *ProviderAccount) SetPairingRemotePeer(ctx context.Context, remotePeerID peer.ID, sessionKey crypto.PrivKey) error

SetPairingRemotePeer stores the remote peer ID, adds an EstablishLinkWithPeer directive on the session transport's child bus, and sets status to WAITING_FOR_PEER. sessionKey is stored for SAS emoji computation when the link establishes.

func (*ProviderAccount) SetPairingSignalingFailed

func (a *ProviderAccount) SetPairingSignalingFailed(msg string)

SetPairingSignalingFailed marks the pairing as failed due to signaling.

func (*ProviderAccount) StartP2PSync

func (a *ProviderAccount) StartP2PSync(ctx context.Context, sessionTransport *transport.SessionTransport) error

StartP2PSync starts SO sync and DEX block exchange for all mounted shared objects. Called when a P2P-linked device connects.

childBus is the session transport's child bus where solicit controllers run. The session transport must be running before calling this method.

func (*ProviderAccount) StopP2PSync

func (a *ProviderAccount) StopP2PSync()

StopP2PSync stops all P2P sync controllers, waits for goroutines to finish, and releases references.

func (*ProviderAccount) StopSessionTransport

func (a *ProviderAccount) StopSessionTransport()

StopSessionTransport stops the running session transport if any.

func (*ProviderAccount) UnlinkDevice

func (a *ProviderAccount) UnlinkDevice(ctx context.Context, remotePeerID peer.ID) error

UnlinkDevice removes a paired device from the account settings SO and revokes its SO participant access on all shared objects.

func (*ProviderAccount) UnlockPINSession

func (a *ProviderAccount) UnlockPINSession(ctx context.Context, ref *session.SessionRef, pin []byte) error

UnlockPINSession unlocks a PIN-locked session before it is mounted. Stores the decrypted key on the ProviderAccount for the tracker to consume.

func (*ProviderAccount) UpdateSharedObjectMeta

func (a *ProviderAccount) UpdateSharedObjectMeta(ctx context.Context, id string, meta *sobject.SharedObjectMeta) error

UpdateSharedObjectMeta updates the metadata for an existing shared object.

func (*ProviderAccount) WaitGCCleanup added in v0.51.2

func (a *ProviderAccount) WaitGCCleanup(ctx context.Context) error

WaitGCCleanup waits for pending account GC cleanup to finish.

func (*ProviderAccount) WatchOrgList

func (a *ProviderAccount) WatchOrgList(ctx context.Context, cb func([]*api.OrgResponse)) error

WatchOrgList watches the organization list by scanning the SO list for org-typed SOs. Emits updates whenever the SO list changes. Returns when the context is canceled.

type Session

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

Session implements the session interface attached to sessionTracker.

func (*Session) AccessStateAtomStore

func (s *Session) AccessStateAtomStore(ctx context.Context, storeID string) (resource_state.StateAtomStore, error)

AccessStateAtomStore gets or creates a shared session state atom store.

func (*Session) GetBus

func (s *Session) GetBus() bus.Bus

GetBus returns the bus used for the session.

func (*Session) GetLockState

func (s *Session) GetLockState(ctx context.Context) (session.SessionLockMode, bool, error)

GetLockState returns the current lock mode and whether the session is locked.

func (*Session) GetPeerId

func (s *Session) GetPeerId() peer.ID

GetPeerId returns the peer id used by the session.

func (*Session) GetPrivKey

func (s *Session) GetPrivKey() crypto.PrivKey

GetPrivKey returns the session private key. Returns nil if the session is locked.

func (*Session) GetProviderAccount

func (s *Session) GetProviderAccount() provider.ProviderAccount

GetProviderAccount returns the handle to the session provider account.

func (*Session) GetSessionRef

func (s *Session) GetSessionRef() *session.SessionRef

GetSessionRef returns the ref to the session.

func (*Session) LockSession

func (s *Session) LockSession(ctx context.Context) error

LockSession locks a running session, scrubbing the privkey from memory. The session tracker will restart and enter PIN-wait state when re-mounted.

func (*Session) SetLockMode

func (s *Session) SetLockMode(ctx context.Context, mode session.SessionLockMode, pin []byte) error

SetLockMode changes the session lock mode. Hot switch: session stays running.

func (*Session) SnapshotStateAtomStoreIDs

func (s *Session) SnapshotStateAtomStoreIDs(ctx context.Context) ([]string, error)

SnapshotStateAtomStoreIDs returns the known session state atom store ids.

func (*Session) UnlockSession

func (s *Session) UnlockSession(ctx context.Context, pin []byte) error

UnlockSession unlocks a PIN-locked session. No-op if already unlocked.

func (*Session) WatchLockState

func (s *Session) WatchLockState(ctx context.Context, cb func(mode session.SessionLockMode, locked bool)) error

WatchLockState calls the callback with the current lock state and on changes.

func (*Session) WatchStateAtomStoreIDs

func (s *Session) WatchStateAtomStoreIDs(
	ctx context.Context,
	cb func(storeIDs []string) error,
) error

WatchStateAtomStoreIDs watches the known session state atom store ids.

type SharedObject

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

SharedObject implements the sobject interface attached to sobjectTracker.

func (*SharedObject) AccessLocalStateStore

func (s *SharedObject) AccessLocalStateStore(ctx context.Context, storeID string, released func()) (kvtx.Store, func(), error)

AccessLocalStateStore accesses a kvtx ops for a local state store with the given ID. This state store is stored along with the local SharedObject state.

func (*SharedObject) AccessSharedObjectState

func (s *SharedObject) AccessSharedObjectState(ctx context.Context, released func()) (ccontainer.Watchable[sobject.SharedObjectStateSnapshot], func(), error)

AccessSharedObjectState adds a reference to the state and returns the state container. Returns a release function. Accepts a function that is called if the Watchable becomes invalid.

func (*SharedObject) ClearOperationResult

func (s *SharedObject) ClearOperationResult(ctx context.Context, localID string) error

ClearOperationResult clears the operation state (rejection). No-op if the operation was successfully applied. Be sure to call this after WaitOperation returns an error. Call with the local operation id.

func (*SharedObject) CreateSOInviteOp

func (s *SharedObject) CreateSOInviteOp(
	ctx context.Context,
	ownerPrivKey crypto.PrivKey,
	role sobject.SOParticipantRole,
	providerID string,
	targetPeerID string,
	maxUses uint32,
	expiresAt *timestamppb.Timestamp,
) (*sobject.SOInviteMessage, error)

CreateSOInviteOp creates a signed invite and stores it locally.

func (*SharedObject) GetBlockStore

func (s *SharedObject) GetBlockStore() bstore.BlockStore

GetBlockStore returns the block store mounted along with the SharedObject.

func (*SharedObject) GetBus

func (s *SharedObject) GetBus() bus.Bus

GetBus returns the bus used for the shared object.

func (*SharedObject) GetPeerID

func (s *SharedObject) GetPeerID() peer.ID

GetPeerID returns the local peer id for the shared object.

func (*SharedObject) GetPrivKey

func (s *SharedObject) GetPrivKey() crypto.PrivKey

GetPrivKey returns the private key for signing invite messages.

func (*SharedObject) GetProviderID

func (s *SharedObject) GetProviderID() string

GetProviderID returns the provider identifier for the invite message.

func (*SharedObject) GetSOHost

func (s *SharedObject) GetSOHost() *sobject.SOHost

GetSOHost returns the SOHost for invite operations.

func (*SharedObject) GetSOHostState

func (s *SharedObject) GetSOHostState(ctx context.Context) (*sobject.SOState, error)

GetSOHostState returns a snapshot of the current SOState via the SOHost.

func (*SharedObject) GetSharedObjectID

func (s *SharedObject) GetSharedObjectID() string

GetSharedObjectID returns the shared object id.

func (*SharedObject) GetSharedObjectState

func (s *SharedObject) GetSharedObjectState(ctx context.Context) (sobject.SharedObjectStateSnapshot, error)

GetSharedObjectState returns an snapshot of the shared object state.

func (*SharedObject) IncrementInviteUses

func (s *SharedObject) IncrementInviteUses(ctx context.Context, signerPrivKey crypto.PrivKey, inviteID string) error

IncrementInviteUses increments invite uses locally.

func (*SharedObject) ProcessOperations

func (s *SharedObject) ProcessOperations(ctx context.Context, watch bool, cb sobject.ProcessOpsFunc) error

ProcessOperations processes operations as a validator. The ops should be processed in the order they are provided. The results must be a subset of ops (but does not need to have all ops). If watch is set, waits for ops to be queued, then calls cb. Does not return. If watch is unset, if there are no available ops, returns immediately. cb is called with the state snapshot and the decoded inner state.

func (*SharedObject) QueueOperation

func (s *SharedObject) QueueOperation(ctx context.Context, op []byte) (string, error)

QueueOperation applies an operation to the shared object op queue. Returns after the operation is applied to the local queue. Returns the local operation ID.

func (*SharedObject) RevokeInvite

func (s *SharedObject) RevokeInvite(ctx context.Context, signerPrivKey crypto.PrivKey, inviteID string) error

RevokeInvite revokes an invite locally.

func (*SharedObject) WaitOperation

func (s *SharedObject) WaitOperation(ctx context.Context, localID string) (uint64, bool, error)

WaitOperation waits for the operation to be confirmed or rejected by the provider. Returns the current state nonce (greater than or equal to the nonce when the op was applied). After ClearOperation has been called, this will return success even for failed ops! If the operation was rejected, returns 0, true, error. Any other error returns 0, false, error

Jump to

Keyboard shortcuts

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