feat: feature gate incremental function
This commit is contained in:
parent
0e96f03166
commit
12d7533339
4 changed files with 45 additions and 20 deletions
4
.github/workflows/linux.yml
vendored
4
.github/workflows/linux.yml
vendored
|
@ -42,7 +42,7 @@ jobs:
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: check
|
command: check
|
||||||
args: --all --bins --examples --tests
|
args: --all --bins --examples --tests --all-features
|
||||||
|
|
||||||
- name: tests
|
- name: tests
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
|
@ -56,7 +56,7 @@ jobs:
|
||||||
uses: actions-rs/tarpaulin@v0.1
|
uses: actions-rs/tarpaulin@v0.1
|
||||||
with:
|
with:
|
||||||
version: '0.15.0'
|
version: '0.15.0'
|
||||||
args: '-t 1200'
|
args: '-t 1200 --all-features'
|
||||||
|
|
||||||
- name: Upload to Codecov
|
- name: Upload to Codecov
|
||||||
if: matrix.version == 'stable' && (github.ref == 'refs/heads/master' || github.event_name == 'pull_request')
|
if: matrix.version == 'stable' && (github.ref == 'refs/heads/master' || github.event_name == 'pull_request')
|
||||||
|
|
|
@ -19,3 +19,7 @@ serde = { version = "1.0", features = ["derive"] }
|
||||||
bincode = "1.3"
|
bincode = "1.3"
|
||||||
derive_builder = "0.12"
|
derive_builder = "0.12"
|
||||||
num = { version = "0.4.0", default-features = false, features = ["serde", "num-bigint"]}
|
num = { version = "0.4.0", default-features = false, features = ["serde", "num-bigint"]}
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
incremental = []
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -2,7 +2,7 @@
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
define test_core
|
define test_core
|
||||||
cargo test --no-fail-fast
|
cargo test --no-fail-fast --all-features
|
||||||
endef
|
endef
|
||||||
|
|
||||||
default: ## Build library in debug mode
|
default: ## Build library in debug mode
|
||||||
|
|
55
src/lib.rs
55
src/lib.rs
|
@ -50,19 +50,32 @@ pub struct Config {
|
||||||
pub salt: String,
|
pub salt: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum SteppedSolve<T> {
|
/// Return value of incremental prooving. When proof is ready, IncrementalSolve::Work is returned
|
||||||
|
/// and when proof is not ready, IncrementalSolve::Intermediate is returned
|
||||||
|
#[cfg(feature = "incremental")]
|
||||||
|
pub enum IncrementalSolve<T> {
|
||||||
|
/// Intermediate result
|
||||||
Intermediate(u128, u64, Sha256, u128),
|
Intermediate(u128, u64, Sha256, u128),
|
||||||
|
/// Final result
|
||||||
Work(PoW<T>),
|
Work(PoW<T>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
|
///
|
||||||
|
/// step is used to control the number of cycles after which the function should exit, even
|
||||||
|
/// when the proof isn't ready
|
||||||
|
/// inter is used to keep track of state and complete proof generation. Set inter to None
|
||||||
|
/// during first cyle and pass the returned value of the previous cycle to continue proof
|
||||||
|
/// generation
|
||||||
|
|
||||||
|
#[cfg(feature = "incremental")]
|
||||||
pub fn stepped_prove_work<T>(
|
pub fn stepped_prove_work<T>(
|
||||||
&self,
|
&self,
|
||||||
t: &T,
|
t: &T,
|
||||||
difficulty: u32,
|
difficulty: u32,
|
||||||
step: usize,
|
step: usize,
|
||||||
inter: Option<SteppedSolve<T>>,
|
inter: Option<IncrementalSolve<T>>,
|
||||||
) -> bincode::Result<SteppedSolve<T>>
|
) -> bincode::Result<IncrementalSolve<T>>
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
|
@ -70,23 +83,34 @@ impl Config {
|
||||||
.map(|v| self.stepped_prove_work_serialized(&v, difficulty, step, inter))
|
.map(|v| self.stepped_prove_work_serialized(&v, difficulty, step, inter))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create Proof of Work on an already serialized item of type T.
|
#[cfg(feature = "incremental")]
|
||||||
|
/// Create Proof of Work over item of type T.
|
||||||
|
///
|
||||||
|
/// Make sure difficulty is not too high. A 64 bit difficulty,
|
||||||
|
/// for example, takes a long time on a general purpose processor.
|
||||||
/// The input is assumed to be serialized using network byte order.
|
/// The input is assumed to be serialized using network byte order.
|
||||||
///
|
///
|
||||||
/// Make sure difficulty is not too high. A 64 bit difficulty,
|
/// Make sure difficulty is not too high. A 64 bit difficulty,
|
||||||
/// for example, takes a long time on a general purpose processor.
|
/// for example, takes a long time on a general purpose processor.
|
||||||
pub fn stepped_prove_work_serialized<T>(
|
/// step is used to control the number of cycles after which the function should exit, even
|
||||||
|
/// when the proof isn't ready
|
||||||
|
/// inter is used to keep track of state and complete proof generation. Set inter to None
|
||||||
|
/// during first cyle and pass the returned value of the previous cycle to continue proof
|
||||||
|
/// generation
|
||||||
|
/// Returns bincode::Error if serialization fails.
|
||||||
|
/// Create Proof of Work on an already serialized item of type T.
|
||||||
|
fn stepped_prove_work_serialized<T>(
|
||||||
&self,
|
&self,
|
||||||
prefix: &[u8],
|
prefix: &[u8],
|
||||||
difficulty: u32,
|
difficulty: u32,
|
||||||
step: usize,
|
step: usize,
|
||||||
inter: Option<SteppedSolve<T>>,
|
inter: Option<IncrementalSolve<T>>,
|
||||||
) -> SteppedSolve<T>
|
) -> IncrementalSolve<T>
|
||||||
where
|
where
|
||||||
T: Serialize,
|
T: Serialize,
|
||||||
{
|
{
|
||||||
let (mut result, mut n, prefix_sha, difficulty) = match inter {
|
let (mut result, mut n, prefix_sha, difficulty) = match inter {
|
||||||
Some(SteppedSolve::Intermediate(result, nonce, prefix, difficulty)) => {
|
Some(IncrementalSolve::Intermediate(result, nonce, prefix, difficulty)) => {
|
||||||
(result, nonce, prefix, difficulty)
|
(result, nonce, prefix, difficulty)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -98,20 +122,16 @@ impl Config {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
// let prefix_sha = Sha256::new().chain(&self.salt).chain(prefix);
|
|
||||||
// let mut n = 0;
|
|
||||||
// let mut result = 0;
|
|
||||||
// let difficulty = get_difficulty(difficulty);
|
|
||||||
while result < difficulty {
|
while result < difficulty {
|
||||||
if count > step {
|
if count > step {
|
||||||
return SteppedSolve::Intermediate(result, n, prefix_sha, difficulty);
|
return IncrementalSolve::Intermediate(result, n, prefix_sha, difficulty);
|
||||||
} else {
|
} else {
|
||||||
count += 1;
|
count += 1;
|
||||||
}
|
}
|
||||||
n += 1;
|
n += 1;
|
||||||
result = dev::score(prefix_sha.clone(), n);
|
result = dev::score(prefix_sha.clone(), n);
|
||||||
}
|
}
|
||||||
SteppedSolve::Work(PoW {
|
IncrementalSolve::Work(PoW {
|
||||||
nonce: n,
|
nonce: n,
|
||||||
result: result.to_string(),
|
result: result.to_string(),
|
||||||
_spook: PhantomData,
|
_spook: PhantomData,
|
||||||
|
@ -331,6 +351,7 @@ mod test {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[cfg(feature = "incremental")]
|
||||||
fn stepped_solve() {
|
fn stepped_solve() {
|
||||||
let phrase = "Ex nihilo nihil fit.".to_owned();
|
let phrase = "Ex nihilo nihil fit.".to_owned();
|
||||||
let config = get_config();
|
let config = get_config();
|
||||||
|
@ -338,15 +359,15 @@ mod test {
|
||||||
let mut inter = None;
|
let mut inter = None;
|
||||||
loop {
|
loop {
|
||||||
match config.stepped_prove_work(&phrase, 50000, 1000, inter) {
|
match config.stepped_prove_work(&phrase, 50000, 1000, inter) {
|
||||||
Ok(SteppedSolve::Intermediate(result, nonce, prefix, difficulty)) => {
|
Ok(IncrementalSolve::Intermediate(result, nonce, prefix, difficulty)) => {
|
||||||
println!("Current nonce {nonce}");
|
println!("Current nonce {nonce}");
|
||||||
inter = Some(SteppedSolve::Intermediate(
|
inter = Some(IncrementalSolve::Intermediate(
|
||||||
result, nonce, prefix, difficulty,
|
result, nonce, prefix, difficulty,
|
||||||
));
|
));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(SteppedSolve::Work(w)) => {
|
Ok(IncrementalSolve::Work(w)) => {
|
||||||
assert!(config.is_valid_proof(&w, &phrase));
|
assert!(config.is_valid_proof(&w, &phrase));
|
||||||
assert!(config.is_sufficient_difficulty(&w, DIFFICULTY));
|
assert!(config.is_sufficient_difficulty(&w, DIFFICULTY));
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue