Skip to content

Commit

Permalink
Initial subspace-gateway binary which does nothing
Browse files Browse the repository at this point in the history
  • Loading branch information
teor2345 committed Oct 17, 2024
1 parent f1428ed commit 5f711a4
Show file tree
Hide file tree
Showing 7 changed files with 324 additions and 1 deletion.
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 <teor@riseup.net>"]
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(())
}

0 comments on commit 5f711a4

Please sign in to comment.