Skip to content

Commit

Permalink
Update for node release v21 (#14)
Browse files Browse the repository at this point in the history
* Update for node release v21

- Removed `beta` flag no one uses. Maintaining this is too difficult with the difficulty changes. Program will error if that flag is given. This is not necessary for distributed work requests as those include the absolute difficulty
- Update threshold to 8x current
- Add lower receive threshold
- Follow changes to work_validate

* Fix incorrectly including "valid" in response if only multiplier was given

If **difficulty** is not given then "valid" is not ever included, regardless of multiplier

* No redundancy
  • Loading branch information
guilhermelawless committed Jun 16, 2020
1 parent 5192ece commit a75d984
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 33 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

![Build](https://github.com/nanocurrency/nano-work-server/workflows/Build/badge.svg)

This project is a dedicated work server for [the Nano cryptocurrency](https://nano.org/).
This project is a dedicated work server for [the Nano cryptocurrency](https://nano.org/). See the [documentation](https://docs.nano.org/integration-guides/work-generation/) for details on work generation and the current network difficulty.

It supports the `work_generate`, `work_cancel`, and `work_validate` commands from the Nano RPC.
**nano-work-server** supports the `work_generate`, `work_cancel`, and `work_validate` commands from the Nano RPC.
For details on these commands, see [the Nano RPC documentation](https://docs.nano.org/commands/rpc-protocol/).

To see available command line options, run `nano-work-server --help`.
Expand Down Expand Up @@ -47,6 +47,8 @@ cd target/release

## Using

_Note_ difficulty values may be outdated in these examples.

- `work_generate` example:

```json
Expand Down Expand Up @@ -87,7 +89,6 @@ cd target/release
"difficulty": "ffffffd21c3933f4",
"multiplier": "1.3946469"
}

```

- `work_cancel` example:
Expand Down
58 changes: 28 additions & 30 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ use time::PreciseTime;

use gpu::Gpu;

const LIVE_DIFFICULTY: u64 = 0xffffffc000000000;
const BETA_DIFFICULTY: u64 = 0xfffff00000000000;
const LIVE_DIFFICULTY: u64 = 0xfffffff800000000;
const LIVE_RECEIVE_DIFFICULTY: u64 = 0xfffffe0000000000;

fn work_value(root: [u8; 32], work: [u8; 8]) -> u64 {
let mut buf = [0u8; 8];
Expand Down Expand Up @@ -99,13 +99,12 @@ impl WorkState {
#[derive(Clone)]
struct RpcService {
work_state: Arc<(Mutex<WorkState>, Condvar)>,
base_difficulty: u64,
}

enum RpcCommand {
WorkGenerate([u8; 32], u64, Option<f64>),
WorkGenerate([u8; 32], Option<u64>, Option<f64>),
WorkCancel([u8; 32]),
WorkValidate([u8; 32], [u8; 8], u64, Option<f64>),
WorkValidate([u8; 32], [u8; 8], Option<u64>, Option<f64>),
}

enum HexJsonError {
Expand Down Expand Up @@ -148,11 +147,11 @@ impl RpcService {
}

fn to_multiplier(&self, difficulty: u64) -> f64 {
(self.base_difficulty.wrapping_neg() as f64) / (difficulty.wrapping_neg() as f64)
(LIVE_DIFFICULTY.wrapping_neg() as f64) / (difficulty.wrapping_neg() as f64)
}

fn from_multiplier(&self, multiplier: f64) -> u64 {
(((self.base_difficulty.wrapping_neg() as f64) / multiplier) as u64).wrapping_neg()
(((LIVE_DIFFICULTY.wrapping_neg() as f64) / multiplier) as u64).wrapping_neg()
}

fn parse_hex_json(value: &Value, out: &mut [u8], allow_short: bool) -> Result<(), HexJsonError> {
Expand Down Expand Up @@ -277,7 +276,7 @@ impl RpcService {
}
Some(action) if action == "work_generate" => Ok(RpcCommand::WorkGenerate(
Self::parse_hash_json(&json)?,
Self::parse_difficulty_json(&json)?.unwrap_or(self.base_difficulty),
Self::parse_difficulty_json(&json)?,
Self::parse_multiplier_json(&json)?,
)),
Some(action) if action == "work_cancel" => {
Expand All @@ -286,7 +285,7 @@ impl RpcService {
Some(action) if action == "work_validate" => Ok(RpcCommand::WorkValidate(
Self::parse_hash_json(&json)?,
Self::parse_work_json(&json)?,
Self::parse_difficulty_json(&json)?.unwrap_or(self.base_difficulty),
Self::parse_difficulty_json(&json)?,
Self::parse_multiplier_json(&json)?,
)),
Some(_) => {
Expand Down Expand Up @@ -321,7 +320,7 @@ impl RpcService {
match command {
RpcCommand::WorkGenerate(root, difficulty, multiplier) => {
let difficulty = match multiplier {
None => difficulty,
None => difficulty.unwrap_or(LIVE_DIFFICULTY),
Some(multiplier) => self.from_multiplier(multiplier)
};
Box::new(self.generate_work(root, difficulty).then(move |res| match res {
Expand Down Expand Up @@ -366,18 +365,27 @@ impl RpcService {
}
RpcCommand::WorkValidate(root, work, difficulty, multiplier) => {
let _ = println!("Validate {}", hex::encode_upper(&root));
let difficulty = match multiplier {
None => difficulty,
let difficulty_l = match multiplier {
None => difficulty.unwrap_or(LIVE_DIFFICULTY),
Some(multiplier) => self.from_multiplier(multiplier)
};
let (valid, result_difficulty) = work_valid(root, work, difficulty);
let (valid, result_difficulty) = work_valid(root, work, difficulty_l);
let (valid_all, _) = work_valid(root, work, LIVE_DIFFICULTY);
let (valid_receive, _) = work_valid(root, work, LIVE_RECEIVE_DIFFICULTY);
Box::new(future::ok((
StatusCode::Ok,
json!({
"valid": if valid { "1" } else { "0" },
"difficulty": format!("{:x}", result_difficulty),
"multiplier": format!("{}", self.to_multiplier(result_difficulty)),
}),
{
let mut result = json!({
"valid_all": if valid_all { "1" } else { "0" },
"valid_receive": if valid_receive { "1" } else { "0" },
"difficulty": format!("{:x}", result_difficulty),
"multiplier": format!("{}", self.to_multiplier(result_difficulty)),
});
if difficulty.is_some() {
result.as_object_mut().unwrap().insert(String::from("valid"), json!(if valid {"1"} else {"0"}));
}
result
},
)))
}
}
Expand Down Expand Up @@ -453,19 +461,12 @@ fn main() {
.value_name("N")
.help("The GPU local work size. Increasing it may increase performance. For advanced users only."),
)
.arg(
clap::Arg::with_name("beta")
.long("beta")
.help("Generate work for the beta network. Modifies the base threshold for given multipliers or requests without a custom difficulty"),
)
.arg(
clap::Arg::with_name("shuffle")
.long("shuffle")
.help("Pick a random request from the queue instead of the oldest. Increases efficiency when using multiple work servers")
)
.get_matches();
let beta = args.is_present("beta");
let base_difficulty = if beta {BETA_DIFFICULTY} else {LIVE_DIFFICULTY};
let random_mode = args.is_present("shuffle");
let listen_addr = args.value_of("listen_address")
.unwrap()
Expand Down Expand Up @@ -664,14 +665,11 @@ fn main() {
let server = Http::new()
.bind(&listen_addr, move || {
Ok(RpcService {
work_state: work_state.clone(),
base_difficulty
work_state: work_state.clone()
})
})
.expect("Failed to bind server");
println!("Configured for the {} network with threshold {:x}",
if beta {"beta"} else {"live"},
base_difficulty);
println!("Configured for the live network with threshold {:x}", LIVE_DIFFICULTY);
println!("Ready to receive requests on {}", listen_addr);
server.run().expect("Error running server");
}

0 comments on commit a75d984

Please sign in to comment.