feat: feature gate incremental function
ci/woodpecker/push/woodpecker Pipeline was successful Details
ci/woodpecker/pr/woodpecker Pipeline was successful Details

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
with:
command: check
args: --all --bins --examples --tests
args: --all --bins --examples --tests --all-features
- name: tests
uses: actions-rs/cargo@v1
@ -56,7 +56,7 @@ jobs:
uses: actions-rs/tarpaulin@v0.1
with:
version: '0.15.0'
args: '-t 1200'
args: '-t 1200 --all-features'
- name: Upload to Codecov
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"
derive_builder = "0.12"
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
define test_core
cargo test --no-fail-fast
cargo test --no-fail-fast --all-features
endef
default: ## Build library in debug mode

View File

@ -50,19 +50,32 @@ pub struct Config {
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),
/// Final result
Work(PoW<T>),
}
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>(
&self,
t: &T,
difficulty: u32,
step: usize,
inter: Option<SteppedSolve<T>>,
) -> bincode::Result<SteppedSolve<T>>
inter: Option<IncrementalSolve<T>>,
) -> bincode::Result<IncrementalSolve<T>>
where
T: Serialize,
{
@ -70,23 +83,34 @@ impl Config {
.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.
///
/// Make sure difficulty is not too high. A 64 bit difficulty,
/// 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,
prefix: &[u8],
difficulty: u32,
step: usize,
inter: Option<SteppedSolve<T>>,
) -> SteppedSolve<T>
inter: Option<IncrementalSolve<T>>,
) -> IncrementalSolve<T>
where
T: Serialize,
{
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)
}
_ => {
@ -98,20 +122,16 @@ impl Config {
}
};
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 {
if count > step {
return SteppedSolve::Intermediate(result, n, prefix_sha, difficulty);
return IncrementalSolve::Intermediate(result, n, prefix_sha, difficulty);
} else {
count += 1;
}
n += 1;
result = dev::score(prefix_sha.clone(), n);
}
SteppedSolve::Work(PoW {
IncrementalSolve::Work(PoW {
nonce: n,
result: result.to_string(),
_spook: PhantomData,
@ -331,6 +351,7 @@ mod test {
}
#[test]
#[cfg(feature = "incremental")]
fn stepped_solve() {
let phrase = "Ex nihilo nihil fit.".to_owned();
let config = get_config();
@ -338,15 +359,15 @@ mod test {
let mut inter = None;
loop {
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}");
inter = Some(SteppedSolve::Intermediate(
inter = Some(IncrementalSolve::Intermediate(
result, nonce, prefix, difficulty,
));
continue;
}
Ok(SteppedSolve::Work(w)) => {
Ok(IncrementalSolve::Work(w)) => {
assert!(config.is_valid_proof(&w, &phrase));
assert!(config.is_sufficient_difficulty(&w, DIFFICULTY));
break;