Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sendpayment Part 2: Channel open, Get invoice #58

Merged
merged 15 commits into from
Oct 8, 2022
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ rustls-pemfile = "1"
secrecy = "0.8"
# Serialization / deserialization framework
serde = { version = "1", features = ["derive"] }
serde_with = { version = "2", default-features = false, features = ["macros"] }
serde_qs = "0"
serde_json = "1"
# Core SGX types
Expand Down
6 changes: 3 additions & 3 deletions common/src/api/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,12 +177,12 @@ impl OpaqueUserAuthToken {
mod test {
use super::*;
use crate::test_utils::roundtrip::{
bcs_roundtrip_proptest, signed_roundtrip_proptest,
serde_roundtrip_proptest, signed_roundtrip_proptest,
};

#[test]
fn test_user_signup_request_canonical() {
bcs_roundtrip_proptest::<UserSignupRequest>();
serde_roundtrip_proptest::<UserSignupRequest>();
}

#[test]
Expand All @@ -192,7 +192,7 @@ mod test {

#[test]
fn test_user_auth_request_canonical() {
bcs_roundtrip_proptest::<UserAuthRequest>();
serde_roundtrip_proptest::<UserAuthRequest>();
}

#[test]
Expand Down
6 changes: 6 additions & 0 deletions common/src/api/node.rs → common/src/api/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,9 @@ pub struct NodeInfo {
pub struct ListChannels {
pub channel_details: Vec<LxChannelDetails>,
}

#[derive(Serialize, Deserialize)]
pub struct GetInvoiceRequest {
pub amt_msat: Option<u64>,
pub expiry_secs: u32,
}
9 changes: 8 additions & 1 deletion common/src/api/def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@

use async_trait::async_trait;

use crate::api::command::{GetInvoiceRequest, ListChannels, NodeInfo};
use crate::api::error::{BackendApiError, NodeApiError, RunnerApiError};
use crate::api::node::{ListChannels, NodeInfo};
use crate::api::ports::UserPorts;
use crate::api::provision::{
Instance, Node, NodeInstanceSeed, NodeProvisionRequest, SealedSeed,
Expand All @@ -30,6 +30,7 @@ use crate::api::provision::{
use crate::api::vfs::{NodeDirectory, NodeFile, NodeFileId};
use crate::api::UserPk;
use crate::enclave::Measurement;
use crate::ln::invoice::LxInvoice;

/// Defines the api that the backend exposes to the node.
#[async_trait]
Expand Down Expand Up @@ -142,4 +143,10 @@ pub trait OwnerNodeRunApi {
///
/// [`EmptyData`]: super::qs::EmptyData
async fn list_channels(&self) -> Result<ListChannels, NodeApiError>;

/// POST /owner/get_invoice [`GetInvoiceRequest`] -> [`ListChannels`]
async fn get_invoice(
&self,
req: GetInvoiceRequest,
) -> Result<LxInvoice, NodeApiError>;
}
29 changes: 17 additions & 12 deletions common/src/api/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,15 +222,17 @@ pub enum NodeErrorKind {
#[error("Other reqwest error")]
Reqwest,

#[error("Could not proxy request to node")]
Proxy,

#[error("Wrong user pk")]
WrongUserPk,
#[error("Given node pk doesn't match node pk derived from seed")]
WrongNodePk,
#[error("Error occurred during provisioning")]
Provision,

#[error("Could not proxy request to node")]
Proxy,
#[error("Error while executing command")]
Command,
}

/// All variants of errors that the LSP can return.
Expand Down Expand Up @@ -499,10 +501,11 @@ impl ErrorCodeConvertible for NodeErrorKind {
Self::Timeout => 3,
Self::Decode => 4,
Self::Reqwest => 5,
Self::WrongUserPk => 6,
Self::WrongNodePk => 7,
Self::Provision => 8,
Self::Proxy => 9,
Self::Proxy => 6,
Self::WrongUserPk => 7,
Self::WrongNodePk => 8,
Self::Provision => 9,
Self::Command => 10,
}
}
fn from_code(code: ErrorCode) -> Self {
Expand All @@ -513,10 +516,11 @@ impl ErrorCodeConvertible for NodeErrorKind {
3 => Self::Timeout,
4 => Self::Decode,
5 => Self::Reqwest,
6 => Self::WrongUserPk,
7 => Self::WrongNodePk,
8 => Self::Provision,
9 => Self::Proxy,
6 => Self::Proxy,
7 => Self::WrongUserPk,
8 => Self::WrongNodePk,
9 => Self::Provision,
10 => Self::Command,
_ => Self::Unknown,
}
}
Expand Down Expand Up @@ -611,11 +615,12 @@ impl HasStatusCode for NodeApiError {
Connect => SERVER_503_SERVICE_UNAVAILABLE,
Timeout => SERVER_504_GATEWAY_TIMEOUT,
Decode => SERVER_502_BAD_GATEWAY,
Proxy => SERVER_502_BAD_GATEWAY,
Reqwest => CLIENT_400_BAD_REQUEST,
WrongUserPk => CLIENT_400_BAD_REQUEST,
WrongNodePk => CLIENT_400_BAD_REQUEST,
Provision => SERVER_500_INTERNAL_SERVER_ERROR,
Proxy => SERVER_502_BAD_GATEWAY,
Command => SERVER_500_INTERNAL_SERVER_ERROR,
}
}
}
Expand Down
9 changes: 4 additions & 5 deletions common/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@ use crate::{const_ref_cast, ed25519, hexstr_or_bytes};

/// Authentication and User Signup.
pub mod auth;
/// Data types used in APIs for top level commands.
pub mod command;
/// Traits defining the various REST API interfaces.
pub mod def;
/// Enums for the API errors returned by the various services.
pub mod error;
/// Minor data types defining what is returned by APIs exposed by the node.
/// Bigger / more fundamental LN types should go under [`crate::ln`].
pub mod node;
/// `Port`, `Ports`, `UserPorts`, `RunPorts`, etc.
pub mod ports;
/// Data types specific to provisioning.
Expand Down Expand Up @@ -192,7 +191,7 @@ mod test {

#[test]
fn user_pk_bcs() {
roundtrip::bcs_roundtrip_proptest::<UserPk>();
roundtrip::serde_roundtrip_proptest::<UserPk>();
}

#[test]
Expand All @@ -202,6 +201,6 @@ mod test {

#[test]
fn node_pk_bcs() {
roundtrip::bcs_roundtrip_proptest::<NodePk>();
roundtrip::serde_roundtrip_proptest::<NodePk>();
}
}
33 changes: 28 additions & 5 deletions common/src/api/rest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,20 @@ pub const POST: Method = Method::POST;
pub const DELETE: Method = Method::DELETE;

/// A warp helper that converts `Result<T, E>` into [`Response<Body>`].
/// This function should be used in all warp routes because:
/// This function should be used after all *fallible* warp handlers because:
///
/// 1) `RestClient::send_and_deserialize` relies on the HTTP status code to
/// determine whether a response should be deserialized as the requested
/// object or as the error type.
/// 2) Using this function voids the need to call reply::json(&resp) in every
/// warp handler or to manually set the error code in every response.
/// object or as the error type. This function handles this automatically and
/// consistently across all Lexe APIs.
/// 2) It saves time; there is no need to call reply::json(&resp) in every warp
/// handler or to manually set the error code in every response.
/// 3) Removing the [`warp::Reply`] serialization step from the warp handlers
/// allows each handler to be independently unit and integration tested.
///
/// This function can be used at the end of a warp filter chain like so:
/// For infallible handlers, use [`into_succ_response`] instead.
///
/// ## Usage
///
/// ```ignore
/// let status = warp::path("status")
Expand All @@ -54,6 +59,24 @@ pub fn into_response<T: Serialize, E: HasStatusCode + Into<ErrorResponse>>(
}
}

/// Like [`into_response`], but converts `T` into [`Response<Body>`]. This fn
/// should be used for the same reasons that [`into_response`] is used, but
/// applies only to *infallible* handlers.
///
/// ## Usage
///
/// ```ignore
/// let node_info = warp::path("node_info")
/// .and(warp::get())
/// .and(inject::channel_manager(channel_manager.clone()))
/// .and(inject::peer_manager(peer_manager))
/// .map(command::node_info)
/// .map(into_succ_response);
/// ```
pub fn into_succ_response<T: Serialize>(data: T) -> Response<Body> {
build_json_response(StatusCode::OK, &data)
}

/// A warp helper for recovering one of our [`api::error`](crate::api::error)
/// types if it was emitted from an intermediate filter's rejection and then
/// converting into the standard json error response.
Expand Down
13 changes: 12 additions & 1 deletion common/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ pub mod tls;
use anyhow::Context;
use async_trait::async_trait;

use crate::api::command::{GetInvoiceRequest, ListChannels, NodeInfo};
use crate::api::def::{OwnerNodeProvisionApi, OwnerNodeRunApi};
use crate::api::error::NodeApiError;
use crate::api::node::{ListChannels, NodeInfo};
use crate::api::provision::NodeProvisionRequest;
use crate::api::qs::EmptyData;
use crate::api::rest::{RestClient, GET, POST};
use crate::api::UserPk;
use crate::attest;
use crate::ln::invoice::LxInvoice;
use crate::rng::Crng;
use crate::root_seed::RootSeed;

Expand Down Expand Up @@ -93,4 +94,14 @@ impl OwnerNodeRunApi for NodeClient {

self.rest.request(GET, url, &data).await
}

async fn get_invoice(
&self,
req: GetInvoiceRequest,
) -> Result<LxInvoice, NodeApiError> {
let run_url = &self.run_url;
let url = format!("{run_url}/owner/get_invoice");

self.rest.request(POST, url, &req).await
}
}
2 changes: 2 additions & 0 deletions common/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use crate::ln::peer::ChannelPeer;
use crate::rng::SysRng;
use crate::root_seed::RootSeed;

pub const DEFAULT_CHANNEL_SIZE: usize = 256;

pub const DEFAULT_BACKEND_URL: &str = "http://127.0.0.1:3030";
pub const DEFAULT_GATEWAY_URL: &str = "http://127.0.0.1:4040";
pub const DEFAULT_RUNNER_URL: &str = "http://127.0.0.1:5050";
Expand Down
Loading