Skip to content
This repository has been archived by the owner on Feb 15, 2024. It is now read-only.

Commit

Permalink
Merge pull request #2 from subspace/initial-api
Browse files Browse the repository at this point in the history
Add initial api for SDK
  • Loading branch information
i1i1 authored Oct 10, 2022
2 parents 95bb4af + 44ea07a commit 8b406b2
Show file tree
Hide file tree
Showing 6 changed files with 346 additions and 10 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Install Protoc
uses: arduino/setup-protoc@v1
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
Expand Down
9 changes: 9 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,12 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
libp2p-core = "0.36"
either = "1.8"
tempdir = "0.3"
bytesize = "1.1"

subspace-core-primitives = { git = "https://github.com/subspace/subspace", rev = "8007a0acd57064264aa03a8c71eb1c9cc9466994" }

[dev-dependencies]
tokio = { version = "1.21", features = ["rt-multi-thread", "macros"] }
77 changes: 77 additions & 0 deletions examples/simple.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use bytesize::ByteSize;
use subspace_sdk::{Farmer, Network, Node, NodeMode, PlotDescription, PublicKey};

#[tokio::main]
async fn main() {
let mut node: Node = Node::builder()
.mode(NodeMode::Full)
.network(Network::Gemini2a)
.name("i1i1")
.port(1337)
.build("node")
.await
.expect("Failed to init a node");

node.sync().await;

let reward_address = PublicKey::from([0; 32]);
let mut farmer: Farmer = Farmer::builder()
.ws_rpc("127.0.0.1:9955".parse().unwrap())
.listen_on("/ip4/0.0.0.0/tcp/40333".parse().unwrap())
.build(
reward_address,
node.clone(),
PlotDescription::new("plot", ByteSize::gb(10)),
)
.await
.expect("Failed to init a farmer");

farmer.sync().await;

farmer
.on_solution(|solution| async move {
eprintln!("Found solution: {solution:?}");
})
.await;
node.on_block(|block| async move {
eprintln!("New block: {block:?}");
})
.await;

farmer.start_farming().await;

dbg!(node.get_info().await);
dbg!(farmer.get_info().await);

farmer.stop_farming().await;
farmer.close().await;
node.close().await;

// Restarting
let mut node = Node::builder()
.mode(NodeMode::Full)
.network(Network::Gemini2a)
.build("node")
.await
.expect("Failed to init a node");
node.sync().await;

let mut farmer = Farmer::builder()
.build(
reward_address,
node.clone(),
PlotDescription::new("plot", ByteSize::gb(10)),
)
.await
.expect("Failed to init a farmer");

farmer.sync().await;
farmer.start_farming().await;

// Delete everything
for plot in farmer.plots().await {
plot.delete().await;
}
farmer.wipe().await;
node.wipe().await;
}
128 changes: 128 additions & 0 deletions src/farmer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
use std::{io, net::SocketAddr, path::PathBuf};

use bytesize::ByteSize;
use either::Either;
use libp2p_core::multiaddr::Multiaddr;
use tempdir::TempDir;

use crate::{Node, PublicKey};

// TODO: Should it be non-exhaustive?
pub struct PlotDescription {
pub directory: Either<PathBuf, TempDir>,
pub space_pledged: ByteSize,
}

impl PlotDescription {
// TODO: should we check that plot is valid at this stage?
// Or it can be literally a description of a plot
pub fn new(directory: impl Into<PathBuf>, space_pledged: ByteSize) -> Self {
Self {
directory: Either::Left(directory.into()),
space_pledged,
}
}

pub fn with_tempdir(space_pledged: ByteSize) -> io::Result<Self> {
TempDir::new("plot")
.map(Either::Right)
.map(|directory| Self {
directory,
space_pledged,
})
}
}

#[derive(Default)]
pub struct Builder {
listen_on: Option<Multiaddr>,
ws_rpc: Option<SocketAddr>,
}

impl Builder {
pub fn new() -> Self {
Self::default()
}

pub fn listen_on(mut self, multiaddr: Multiaddr) -> Self {
self.listen_on = Some(multiaddr);
self
}

pub fn ws_rpc(mut self, ws_rpc: SocketAddr) -> Self {
self.ws_rpc = Some(ws_rpc);
self
}

/// It supposed to open node at the supplied location
// TODO: Should we just require multiple plots?
pub async fn build(
self,
reward_address: PublicKey,
node: Node,
plot: PlotDescription,
) -> Result<Farmer, ()> {
let _ = (reward_address, node, plot);
todo!()
}
}

pub struct Farmer {
_ensure_cant_construct: (),
}

#[derive(Debug)]
#[non_exhaustive]
pub struct Info {
pub version: String,
pub reward_address: PublicKey,
pub dsn_peers: u64,
pub space_pledged: ByteSize,
}

#[derive(Debug)]
pub struct Solution {
_ensure_cant_construct: (),
}

pub struct Plot {
_ensure_cant_construct: (),
}

impl Plot {
pub async fn delete(&mut self) {}
}

impl Farmer {
pub fn builder() -> Builder {
Builder::new()
}

pub async fn sync(&mut self) {}

pub async fn start_farming(&mut self) {}

pub async fn stop_farming(&mut self) {}

pub async fn get_info(&mut self) -> Info {
todo!()
}

pub async fn on_solution<H, F>(&mut self, on_solution: H)
where
H: Clone + Send + Sync + 'static + FnMut(Solution) -> F,
F: Send + 'static + std::future::Future<Output = ()>,
{
let _ = on_solution;
}

pub async fn plots(&mut self) -> &mut [Plot] {
todo!()
}

// Stops farming, closes plots, and sends signal to the node
pub async fn close(self) {}

// Runs `.close()` and also wipes farmer's state
pub async fn wipe(self) {}
}
31 changes: 21 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
pub fn add(left: usize, right: usize) -> usize {
left + right
}
pub mod farmer;
pub mod node;

use std::path::PathBuf;

#[cfg(test)]
mod tests {
use super::*;
pub use farmer::{
Builder as FarmerBuilder, Farmer, Info as NodeInfo, Plot, PlotDescription, Solution,
};
pub use node::{Builder as NodeBuilder, Info as FarmerInfo, Mode as NodeMode, Network, Node};
pub use subspace_core_primitives::PublicKey;

#[derive(Default)]
#[non_exhaustive]
pub enum Directory {
#[default]
Default,
Tmp,
Custom(PathBuf),
}

#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
impl<P: Into<PathBuf>> From<P> for Directory {
fn from(path: P) -> Self {
Self::Custom(path.into())
}
}
109 changes: 109 additions & 0 deletions src/node.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
use crate::Directory;

#[non_exhaustive]
#[derive(Debug, Default)]
pub enum Mode {
#[default]
Full,
}

#[non_exhaustive]
#[derive(Debug, Default)]
pub enum Network {
#[default]
Gemini2a,
// TODO: put proper type here
Custom(std::convert::Infallible),
}

#[derive(Default)]
pub struct Builder {
mode: Mode,
network: Network,
name: Option<String>,
port: u16,
}

impl Builder {
pub fn new() -> Self {
Self::default()
}

pub fn mode(mut self, ty: Mode) -> Self {
self.mode = ty;
self
}

pub fn network(mut self, network: Network) -> Self {
self.network = network;
self
}

pub fn name(mut self, name: impl AsRef<str>) -> Self {
if !name.as_ref().is_empty() {
self.name = Some(name.as_ref().to_owned());
}
self
}

pub fn port(mut self, port: u16) -> Self {
self.port = port;
self
}

/// It supposed to open node at the supplied location
pub async fn build(self, directory: impl Into<Directory>) -> Result<Node, ()> {
let _ = directory;
todo!()
}
}

#[derive(Clone)]
pub struct Node {
_ensure_cant_construct: (),
}

#[derive(Debug)]
#[non_exhaustive]
pub struct Info {
pub version: String,
pub network: Network,
pub mode: Mode,
pub name: Option<String>,
pub connected_peers: u64,
pub best_block: u64,
pub total_space_pledged: u64,
pub total_history_size: u64,
pub space_pledged: u64,
}

#[derive(Debug)]
pub struct Block {
_ensure_cant_construct: (),
}

impl Node {
pub fn builder() -> Builder {
Builder::new()
}

pub async fn sync(&mut self) {}

// Leaves the network and gracefully shuts down
pub async fn close(self) {}

// Runs `.close()` and also wipes node's state
pub async fn wipe(self) {}

pub async fn get_info(&mut self) -> Info {
todo!()
}

pub async fn on_block<H, F>(&mut self, callback: H)
where
H: Clone + Send + Sync + 'static + FnMut(Block) -> F,
F: Send + 'static + std::future::Future<Output = ()>,
{
let _ = callback;
}
}

0 comments on commit 8b406b2

Please sign in to comment.