SchedulerClient

Struct SchedulerClient 

Source
pub struct SchedulerClient<T> { /* private fields */ }
Expand description

The scheduler service is the endpoint which allows users to register a new node with greenlight, recover access to an existing node if the owner lost its credentials, schedule the node to be run on greenlight’s infrastructure, and retrieve metadata about the node.

§Node

A node is the basic object representing an account on greenlight. Each node corresponds to a c-lightning instance bound to a specific network that can be scheduled on greenlight, and must have a unique node_id.

Nodes are scheduled on-demand onto the infrastructure, but the time to schedule a node is almost instantaneous.

§Authentication

Users are authenticated using mTLS authentication. Applications are provisioned with an anonymous keypair that is not bound to a node, allowing access only to the unauthenticated endpoints Scheduler.GetChallenge, Scheduler.Register and Scheduler.Recover. This allows them to register or recover a node, but doesn’t give access to the node itself. Upon registering or recovering an account the user receives a keypair that is bound to the specific node. Once the user receives their personal mTLS keypair they may use it to connect to greenlight, and thus get access to the node-specific functionality. Please refer to the documentation of your grpc library to learn how to configure grpc to use the node-specific mTLS keypair.

Implementations§

Source§

impl SchedulerClient<Channel>

Source

pub async fn connect<D>(dst: D) -> Result<Self, Error>
where D: TryInto<Endpoint>, D::Error: Into<StdError>,

Attempt to create a new client by connecting to a given endpoint.

Source§

impl<T> SchedulerClient<T>
where T: GrpcService<BoxBody>, T::Error: Into<StdError>, T::ResponseBody: Body<Data = Bytes> + Send + 'static, <T::ResponseBody as Body>::Error: Into<StdError> + Send,

Source

pub fn new(inner: T) -> Self

Source

pub fn with_origin(inner: T, origin: Uri) -> Self

Source

pub fn with_interceptor<F>( inner: T, interceptor: F, ) -> SchedulerClient<InterceptedService<T, F>>
where F: Interceptor, T::ResponseBody: Default, T: Service<Request<BoxBody>, Response = Response<<T as GrpcService<BoxBody>>::ResponseBody>>, <T as Service<Request<BoxBody>>>::Error: Into<StdError> + Send + Sync,

Source

pub fn send_compressed(self, encoding: CompressionEncoding) -> Self

Compress requests with the given encoding.

This requires the server to support it otherwise it might respond with an error.

Source

pub fn accept_compressed(self, encoding: CompressionEncoding) -> Self

Enable decompressing responses.

Source

pub fn max_decoding_message_size(self, limit: usize) -> Self

Limits the maximum size of a decoded message.

Default: 4MB

Source

pub fn max_encoding_message_size(self, limit: usize) -> Self

Limits the maximum size of an encoded message.

Default: usize::MAX

Source

pub async fn register( &mut self, request: impl IntoRequest<RegistrationRequest>, ) -> Result<Response<RegistrationResponse>, Status>

A user may register a new node with greenlight by providing some basic metadata and proving that they have access to the corresponding private key (see challenge-response mechanism below). This means that in order to register a new node the user must have access to the corresponding private keys to prove ownership, and prevent users from just registering arbitrary node_ids without actually knowing the corresponding secrets.

Upon successful registration an mTLS certificate and private key are returned. These can be used to authenticate future connections to the scheduler or the node.

Each node may be registered once, any later attempt will result in an error being returned. If the user lost its credentials it can make use of the Recover RPC method to recover the credentials. Notice that this also means that the same node_id cannot be reused for different networks.

Source

pub async fn recover( &mut self, request: impl IntoRequest<RecoveryRequest>, ) -> Result<Response<RecoveryResponse>, Status>

Should a user have lost its credentials (mTLS keypair) for any reason, they may regain access to their node using the Recover RPC method. Similar to the initial registration the caller needs to authenticate the call by proving access to the node’s secret. This also uses the challenge-response mechanism.

Upon success a newly generated mTLS certificate and private key are returned, allowing the user to authenticate going forward. Existing keypairs are not revoked, in order to avoid locking out other authenticated applications.

Source

pub async fn get_challenge( &mut self, request: impl IntoRequest<ChallengeRequest>, ) -> Result<Response<ChallengeResponse>, Status>

Challenges are one-time values issued by the server, used to authenticate a user/device against the server. A user or device can authenticate to the server by signing the challenge and returning the signed message as part of the request that is to be authenticated.

Challenges may not be reused, and are bound to the scope they have been issued for. Attempting to reuse a challenge or use a challenge with a different scope will result in an error being returned.

Source

pub async fn schedule( &mut self, request: impl IntoRequest<ScheduleRequest>, ) -> Result<Response<NodeInfoResponse>, Status>

Scheduling takes a previously registered node, locates a free slot in greenlight’s infrastructure and allocates it to run the node. The node then goes through the startup sequence, synchronizing with the blockchain, and finally binding its grpc interface (see Node service below) to a public IP address and port. Access is authenticated via the mTLS keypair the user received from registering or recovering the node.

Upon success a NodeInfoResponse containing the grpc connection details and some metadata is returned. The application must use the grpc details and its node-specific mTLS keypair to interact with the node directly.

Source

pub async fn get_node_info( &mut self, request: impl IntoRequest<NodeInfoRequest>, ) -> Result<Response<NodeInfoResponse>, Status>

Much like Schedule this call is used to retrieve the metadata and grpc details of a node. Unlike the other call however it is passive, and will not result in the node being scheduled if it isn’t already running. This can be used to check if a node is already scheduled, or to wait for it to be scheduled (e.g., if the caller is an hsmd that signs off on changes, but doesn’t want to keep the node itself scheduled).

Source

pub async fn maybe_upgrade( &mut self, request: impl IntoRequest<UpgradeRequest>, ) -> Result<Response<UpgradeResponse>, Status>

The signer may want to trigger an upgrade of the node before waiting for the node to be scheduled. This ensures that the signer version is in sync with the node version. The scheduler may decide to defer upgrading if the protocols are compatible. Please do not use this directly, rather use the Signer in the client library to trigger this automatically when required. Posting an incomplete or non-functional UpgradeRequest may result in unschedulable nodes.

Source

pub async fn list_invite_codes( &mut self, request: impl IntoRequest<ListInviteCodesRequest>, ) -> Result<Response<ListInviteCodesResponse>, Status>

This call is used to fetch a list of invite codes associated with the node id of the client. These invite codes can be used for further registration of new nodes.

Source

pub async fn export_node( &mut self, request: impl IntoRequest<ExportNodeRequest>, ) -> Result<Response<ExportNodeResponse>, Status>

Exporting a node allows users to take control of their node

This method initiates the node export on Greenlight, allowing users to offboard from GL into their own infrastructure. After calling this method the node will no longer be schedulable on Greenlight, since it is never safe to assume there haven’t been changes in the node’s state (see CLN Backups documentation for details). ExportNode marks the node as Exporting, then generates an encryption secret which is then used to encrypt a database backup. This encrypted database backup is then made accessible through an HTTP server, and a link to it is returned as a response to ExportNode. After the export completes the node is marked as Exported. The encryption key can then be derived using the signer, using ECDH, allowing only users with the node secret to decrypt it.

ExportNode is idempotent and may be called multiple times, without causing the node to be re-exported multiple times, should the call or the download be interrupted. DO NOT import the backup multiple times into your infrastructure, as that can lead to dataloss (old state being replayed) and loss of funds (see CLN Backups documentation for more information)

Source

pub async fn add_outgoing_webhook( &mut self, request: impl IntoRequest<AddOutgoingWebhookRequest>, ) -> Result<Response<AddOutgoingWebhookResponse>, Status>

Source

pub async fn list_outgoing_webhooks( &mut self, request: impl IntoRequest<ListOutgoingWebhooksRequest>, ) -> Result<Response<ListOutgoingWebhooksResponse>, Status>

Source

pub async fn delete_webhooks( &mut self, request: impl IntoRequest<DeleteOutgoingWebhooksRequest>, ) -> Result<Response<Empty>, Status>

Source

pub async fn rotate_outgoing_webhook_secret( &mut self, request: impl IntoRequest<RotateOutgoingWebhookSecretRequest>, ) -> Result<Response<WebhookSecretResponse>, Status>

Source

pub async fn signer_requests_stream( &mut self, request: impl IntoStreamingRequest<Message = SignerResponse>, ) -> Result<Response<Streaming<SignerRequest>>, Status>

Attaches a Signer via a bidirectional stream to the scheduler. This is a communication channel between greenlight and the signing device that is used for requests that are not part of the node api.

The stream is used to hand out the ApprovePairingRequests that the signer answers with a ApprovePairingResponse.

Trait Implementations§

Source§

impl<T: Clone> Clone for SchedulerClient<T>

Source§

fn clone(&self) -> SchedulerClient<T>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug> Debug for SchedulerClient<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T> !Freeze for SchedulerClient<T>

§

impl<T> RefUnwindSafe for SchedulerClient<T>
where T: RefUnwindSafe,

§

impl<T> Send for SchedulerClient<T>
where T: Send,

§

impl<T> Sync for SchedulerClient<T>
where T: Sync,

§

impl<T> Unpin for SchedulerClient<T>
where T: Unpin,

§

impl<T> UnwindSafe for SchedulerClient<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Any for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Source§

fn type_name(&self) -> &'static str

Source§

impl<T> AnySync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Source§

impl<T> AsAny for T
where T: Any,

Source§

fn as_any(&self) -> &(dyn Any + 'static)

Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Source§

fn type_name(&self) -> &'static str

Gets the type name of self
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast for T
where T: AsAny + ?Sized,

Source§

fn is<T>(&self) -> bool
where T: AsAny,

Returns true if the boxed type is the same as T. Read more
Source§

fn downcast_ref<T>(&self) -> Option<&T>
where T: AsAny,

Forward to the method defined on the type Any.
Source§

fn downcast_mut<T>(&mut self) -> Option<&mut T>
where T: AsAny,

Forward to the method defined on the type Any.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,