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

Initial subspace-gateway binary which does nothing #3131

Merged
merged 1 commit into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
16 changes: 16 additions & 0 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ The structure of this repository is the following:
- `crates` contains Subspace-specific Rust crates used to build node and farmer, most are following Substrate naming conventions
- `subspace-node` is an implementation of the node for Subspace protocol
- `subspace-farmer` is a CLI farmer app
- `subspace-gateway` is a Subspace Distributed Storage Network gateway
- `domains` contains client and runtime code for decoupled execution and domains
- `shared` contains low-level primitives used by the node, farmer, and other applications

## How to run

Please refer to [farming.md](/docs/farming.md) on how to run farmer.
Please refer to [farming.md](/docs/farming.md) for how to run the farmer.

If you are looking to farm offline, or build from source for development purposes please refer to [development.md](/docs/development.md).
29 changes: 29 additions & 0 deletions crates/subspace-gateway/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[package]
name = "subspace-gateway"
version = "0.1.0"
authors = ["Teor <[email protected]>"]
description = "A Subspace Network data gateway."
edition = "2021"
license = "MIT OR Apache-2.0"
homepage = "https://subspace.network"
repository = "https://github.com/autonomys/subspace"
include = [
"/src",
"/Cargo.toml",
"/README.md"
]

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
anyhow = "1.0.89"
clap = { version = "4.5.18", features = ["derive"] }
fdlimit = "0.3.0"
futures = "0.3.30"
mimalloc = "0.1.43"
supports-color = "3.0.1"
thiserror = "1.0.64"
tokio = { version = "1.40.0", features = ["macros"] }
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
74 changes: 74 additions & 0 deletions crates/subspace-gateway/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Subspace Gateway

Data Gateway implementation for Subspace Network Blockchain using [Substrate](https://docs.substrate.io/) framework.

## Getting Started

Follow these steps to get started with the Subspace Gateway :hammer_and_wrench:

## Running

It is recommended to follow general farming instructions that explain how to run both farmer and node together.

## Build from source

A Rust toolchain is required to compile this repository, but there are some extra dependencies for the gateway.

`protoc` is required for `libp2p`.

### Ubuntu

LLVM/Clang and `make` are necessary:
```bash
sudo apt-get install llvm clang cmake make protobuf-compiler
```

### macOS

1. Install via Homebrew:

```bash
brew install llvm cmake make protobuf
```

2. Add `llvm` to your `~/.zshrc` or `~/.bashrc`:

```bash
export PATH="/opt/homebrew/opt/llvm/bin:$PATH"
```

3. Activate the changes:

```bash
source ~/.zshrc
```

4. Verify that `llvm` is installed:

```bash
llvm-config --version
```

### Build

Then build the gateway using Cargo:
```
cargo build --profile production --bin subspace-gateway
target/production/subspace-gateway --version
```

#### Start the gateway

Start a gateway connected to a single node development chain:
```bash
target/production/subspace-gateway run \
--dev
```

### Embedded Docs

Once the project has been built, the following command can be used to explore all parameters and subcommands:

```bash
target/production/subspace-gateway --help
```
92 changes: 92 additions & 0 deletions crates/subspace-gateway/src/commands.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
//! Gateway subcommands.

pub(crate) mod run;

use crate::commands::run::RunOptions;
use clap::Parser;
use tokio::signal;
use tracing::level_filters::LevelFilter;
use tracing::{debug, warn};
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
use tracing_subscriber::{fmt, EnvFilter, Layer};

/// Commands for working with a gateway.
#[derive(Debug, Parser)]
#[clap(about, version)]
pub enum Command {
/// Run data gateway
Run(RunOptions),
// TODO: subcommand to run various benchmarks
}

pub(crate) fn init_logger() {
// TODO: Workaround for https://github.com/tokio-rs/tracing/issues/2214, also on
// Windows terminal doesn't support the same colors as bash does
let enable_color = if cfg!(windows) {
false
} else {
supports_color::on(supports_color::Stream::Stderr).is_some()
};
tracing_subscriber::registry()
.with(
fmt::layer().with_ansi(enable_color).with_filter(
EnvFilter::builder()
.with_default_directive(LevelFilter::INFO.into())
.from_env_lossy(),
),
)
.init();
}

pub(crate) fn raise_fd_limit() {
match fdlimit::raise_fd_limit() {
Ok(fdlimit::Outcome::LimitRaised { from, to }) => {
debug!(
"Increased file descriptor limit from previous (most likely soft) limit {} to \
new (most likely hard) limit {}",
from, to
);
}
Ok(fdlimit::Outcome::Unsupported) => {
// Unsupported platform (a platform other than Linux or macOS)
}
Err(error) => {
warn!(
"Failed to increase file descriptor limit for the process due to an error: {}.",
error
);
}
}
}

#[cfg(unix)]
pub(crate) async fn shutdown_signal() {
use futures::FutureExt;
use std::pin::pin;

futures::future::select(
pin!(signal::unix::signal(signal::unix::SignalKind::interrupt())
.expect("Setting signal handlers must never fail")
.recv()
.map(|_| {
tracing::info!("Received SIGINT, shutting down gateway...");
}),),
pin!(signal::unix::signal(signal::unix::SignalKind::terminate())
.expect("Setting signal handlers must never fail")
.recv()
.map(|_| {
tracing::info!("Received SIGTERM, shutting down gateway...");
}),),
)
.await;
}

#[cfg(not(unix))]
pub(crate) async fn shutdown_signal() {
signal::ctrl_c()
.await
.expect("Setting signal handlers must never fail");

tracing::info!("Received Ctrl+C, shutting down gateway...");
}
66 changes: 66 additions & 0 deletions crates/subspace-gateway/src/commands/run.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//! Gateway run command.
//! This is the primary command for the gateway.

use crate::commands::shutdown_signal;
use clap::Parser;
use futures::{select, FutureExt};
use std::pin::pin;
use std::{env, future};
use tracing::info;

/// Options for running a node
#[derive(Debug, Parser)]
pub struct RunOptions {
#[clap(flatten)]
gateway: GatewayOptions,
}

/// Options for running a gateway
#[derive(Debug, Parser)]
pub(super) struct GatewayOptions {
/// Enable development mode.
#[arg(long)]
dev: bool,
}

/// Default run command for gateway
#[expect(clippy::redundant_locals, reason = "code is incomplete")]
pub async fn run(run_options: RunOptions) -> anyhow::Result<()> {
let signal = shutdown_signal();

let RunOptions {
gateway: GatewayOptions { dev: _ },
} = run_options;

info!("Subspace Gateway");
info!("✌️ version {}", env!("CARGO_PKG_VERSION"));
info!("❤️ by {}", env!("CARGO_PKG_AUTHORS"));

let dsn_fut = future::pending::<()>();
let rpc_fut = future::pending::<()>();

// This defines order in which things are dropped
let dsn_fut = dsn_fut;
let rpc_fut = rpc_fut;

let dsn_fut = pin!(dsn_fut);
let rpc_fut = pin!(rpc_fut);

select! {
// Signal future
() = signal.fuse() => {},

// Networking future
() = dsn_fut.fuse() => {
info!("DSN network runner exited.");
},

// RPC service future
() = rpc_fut.fuse() => {
info!("RPC server exited.");
},

}

anyhow::Ok(())
}
45 changes: 45 additions & 0 deletions crates/subspace-gateway/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//! Subspace gateway implementation.

// TODO: Remove
#![allow(
clippy::needless_return,
reason = "https://github.com/rust-lang/rust-clippy/issues/13458"
)]

mod commands;

use crate::commands::{init_logger, raise_fd_limit, Command};
use clap::Parser;

#[global_allocator]
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;

/// Subspace gateway error.
#[derive(thiserror::Error, Debug)]
pub enum Error {
/// Other kind of error.
#[error("Other: {0}")]
Other(String),
}

impl From<String> for Error {
#[inline]
fn from(s: String) -> Self {
Self::Other(s)
}
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
init_logger();
raise_fd_limit();

let command = Command::parse();

match command {
Command::Run(run_options) => {
commands::run::run(run_options).await?;
}
}
Ok(())
}
Loading