Skip to content
This repository was archived by the owner on Feb 15, 2024. It is now read-only.
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
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;
}
}