feat: feature gate incremental function
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful

This commit is contained in:
Aravinth Manivannan 2023-07-04 20:04:52 +05:30
parent 0e96f03166
commit 12d7533339
Signed by: realaravinth
GPG key ID: F8F50389936984FF
4 changed files with 45 additions and 20 deletions

View file

@ -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')

View file

@ -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 = []

View file

@ -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

View file

@ -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;