grin/core/src/pow.rs

152 lines
4.5 KiB
Rust
Raw Normal View History

// Copyright 2019 The Grin Developers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
2016-10-21 03:06:12 +03:00
//! The proof of work needs to strike a balance between fast header
//! verification to avoid DoS attacks and difficulty for block verifiers to
//! build new blocks. In addition, mining new blocks should also be as
//! difficult on high end custom-made hardware (ASICs) as on commodity hardware
//! or smartphones. For this reason we use Cuckoo Cycle (see the cuckoo
2016-10-21 03:06:12 +03:00
//! module for more information).
//!
//! Note that this miner implementation is here mostly for tests and
//! reference. It's not optimized for speed.
#![deny(non_upper_case_globals)]
#![deny(non_camel_case_types)]
#![deny(non_snake_case)]
#![deny(unused_mut)]
#![warn(missing_docs)]
pub use self::common::EdgeType;
pub use self::types::*;
use crate::core::{Block, BlockHeader};
use crate::genesis;
use crate::global;
use chrono;
use num;
#[macro_use]
mod common;
pub mod cuckaroo;
pub mod cuckarood;
pub mod cuckaroom;
pub mod cuckatoo;
mod error;
#[allow(dead_code)]
pub mod lean;
mod siphash;
mod types;
pub use crate::pow::cuckaroo::{new_cuckaroo_ctx, CuckarooContext};
pub use crate::pow::cuckarood::{new_cuckarood_ctx, CuckaroodContext};
pub use crate::pow::cuckaroom::{new_cuckaroom_ctx, CuckaroomContext};
pub use crate::pow::cuckatoo::{new_cuckatoo_ctx, CuckatooContext};
pub use crate::pow::error::Error;
use chrono::prelude::{DateTime, NaiveDateTime, Utc};
const MAX_SOLS: u32 = 10;
/// Validates the proof of work of a given header, and that the proof of work
/// satisfies the requirements of the header.
pub fn verify_size(bh: &BlockHeader) -> Result<(), Error> {
let mut ctx = global::create_pow_context::<u64>(
bh.height,
bh.pow.edge_bits(),
bh.pow.proof.nonces.len(),
MAX_SOLS,
)?;
ctx.set_header_nonce(bh.pre_pow(), None, false)?;
ctx.verify(&bh.pow.proof)
2016-10-21 03:06:12 +03:00
}
/// Mines a genesis block using the internal miner
pub fn mine_genesis_block() -> Result<Block, Error> {
let mut gen = genesis::genesis_dev();
// total_difficulty on the genesis header *is* the difficulty of that block
let genesis_difficulty = gen.header.pow.total_difficulty;
2017-09-29 21:44:25 +03:00
let sz = global::min_edge_bits();
let proof_size = global::proofsize();
pow_size(&mut gen.header, genesis_difficulty, proof_size, sz)?;
Ok(gen)
}
2017-09-29 21:44:25 +03:00
/// Runs a proof of work computation over the provided block using the provided
/// Mining Worker, until the required difficulty target is reached. May take a
/// while for a low target...
pub fn pow_size(
bh: &mut BlockHeader,
diff: Difficulty,
proof_size: usize,
sz: u8,
) -> Result<(), Error> {
let start_nonce = bh.pow.nonce;
2016-10-21 03:06:12 +03:00
2018-03-04 03:19:54 +03:00
// try to find a cuckoo cycle on that header hash
loop {
// if we found a cycle (not guaranteed) and the proof hash is higher that the
// diff, we're all good
let mut ctx = global::create_pow_context::<u32>(bh.height, sz, proof_size, MAX_SOLS)?;
ctx.set_header_nonce(bh.pre_pow(), None, true)?;
if let Ok(proofs) = ctx.find_cycles() {
bh.pow.proof = proofs[0].clone();
if bh.pow.to_difficulty(bh.height) >= diff {
2018-03-04 03:19:54 +03:00
return Ok(());
}
}
// otherwise increment the nonce
let (res, _) = bh.pow.nonce.overflowing_add(1);
bh.pow.nonce = res;
2018-03-04 03:19:54 +03:00
// and if we're back where we started, update the time (changes the hash as
// well)
if bh.pow.nonce == start_nonce {
bh.timestamp = DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc);
2018-03-04 03:19:54 +03:00
}
}
2016-10-21 03:06:12 +03:00
}
#[cfg(test)]
mod test {
use super::*;
use crate::genesis;
use crate::global;
use crate::global::ChainTypes;
2016-10-21 03:06:12 +03:00
/// We'll be generating genesis blocks differently
2016-10-21 03:06:12 +03:00
#[test]
fn genesis_pow() {
Re-launch floonet (#2249) * Fix secondary scaling bugs; rename is_testnet -> is_floonet (#2215) * add global::is_mainnet() * use it to change pre-genesis pow type * rename is_testnet -> is_floonet * Support multiple chain configurations (#2217) * Support multiple chain configurations Supports generating the proper configuration for each chain type (mainnet, floonet, usernet). Will run them by default under their respective root directory (~/.grin/main, ~/.grin/floo, etc). Assigned default ports for mainnet, overriding them to keep Floonet ports unchanged. For now, starting on mainnet will abort. * Fixed usernet command line help message. Fixes #2217 * Differing magic numbers for each chain type (#2208) * stick to e=H(R|P|m) when use schnorr signature (#2200) * stick to e=H(R|P|m) when use schnorr signature * (1)add verify_slate_messages for wallet receive (2)log the message content * remove debug log on verify_slate_messages * verify the sender's message signature when receive_tx in wallet listen * Revert "remove debug log on verify_slate_messages" This reverts commit 65ea32a407bfd57d02bf169803f1483ba611962e. * Revert "rustfmt" This reverts commit c380ab91856344b73595bb04eef1fc087dedd84d. * Revert "(1)add verify_slate_messages for wallet receive (2)log the message content" This reverts commit 9584ca7a893b22a768dea061039140033c07e8eb. * [re-floonet] Keychain Floonet BIP32 version/network option (#2235) * add 'is_floonet' property to keychain * fix hex encoding and tests * Fix couple floonet loose ends (#2230) * Fix couple floonet loose ends. Fixes #2216 * Doc fix for sig message * Refuse unkown kernel features (#2244) * Minor: magic number change for re-floonet * Set pre genesis is_secondary to true (#2247) * Minor: tx validation error display underlying * New floonet genesis * genesis rustfmt * Use chain-specific config for wallet toml gen * Fix default wallet_listener_url * New more reasonable genesis block, bumped version * genesis rustfmt * Couple minor fixes to genesis generation script
2018-12-29 01:46:21 +03:00
global::set_mining_mode(ChainTypes::UserTesting);
let mut b = genesis::genesis_dev();
Re-launch floonet (#2249) * Fix secondary scaling bugs; rename is_testnet -> is_floonet (#2215) * add global::is_mainnet() * use it to change pre-genesis pow type * rename is_testnet -> is_floonet * Support multiple chain configurations (#2217) * Support multiple chain configurations Supports generating the proper configuration for each chain type (mainnet, floonet, usernet). Will run them by default under their respective root directory (~/.grin/main, ~/.grin/floo, etc). Assigned default ports for mainnet, overriding them to keep Floonet ports unchanged. For now, starting on mainnet will abort. * Fixed usernet command line help message. Fixes #2217 * Differing magic numbers for each chain type (#2208) * stick to e=H(R|P|m) when use schnorr signature (#2200) * stick to e=H(R|P|m) when use schnorr signature * (1)add verify_slate_messages for wallet receive (2)log the message content * remove debug log on verify_slate_messages * verify the sender's message signature when receive_tx in wallet listen * Revert "remove debug log on verify_slate_messages" This reverts commit 65ea32a407bfd57d02bf169803f1483ba611962e. * Revert "rustfmt" This reverts commit c380ab91856344b73595bb04eef1fc087dedd84d. * Revert "(1)add verify_slate_messages for wallet receive (2)log the message content" This reverts commit 9584ca7a893b22a768dea061039140033c07e8eb. * [re-floonet] Keychain Floonet BIP32 version/network option (#2235) * add 'is_floonet' property to keychain * fix hex encoding and tests * Fix couple floonet loose ends (#2230) * Fix couple floonet loose ends. Fixes #2216 * Doc fix for sig message * Refuse unkown kernel features (#2244) * Minor: magic number change for re-floonet * Set pre genesis is_secondary to true (#2247) * Minor: tx validation error display underlying * New floonet genesis * genesis rustfmt * Use chain-specific config for wallet toml gen * Fix default wallet_listener_url * New more reasonable genesis block, bumped version * genesis rustfmt * Couple minor fixes to genesis generation script
2018-12-29 01:46:21 +03:00
b.header.pow.nonce = 28106;
b.header.pow.proof.edge_bits = global::min_edge_bits();
Re-launch floonet (#2249) * Fix secondary scaling bugs; rename is_testnet -> is_floonet (#2215) * add global::is_mainnet() * use it to change pre-genesis pow type * rename is_testnet -> is_floonet * Support multiple chain configurations (#2217) * Support multiple chain configurations Supports generating the proper configuration for each chain type (mainnet, floonet, usernet). Will run them by default under their respective root directory (~/.grin/main, ~/.grin/floo, etc). Assigned default ports for mainnet, overriding them to keep Floonet ports unchanged. For now, starting on mainnet will abort. * Fixed usernet command line help message. Fixes #2217 * Differing magic numbers for each chain type (#2208) * stick to e=H(R|P|m) when use schnorr signature (#2200) * stick to e=H(R|P|m) when use schnorr signature * (1)add verify_slate_messages for wallet receive (2)log the message content * remove debug log on verify_slate_messages * verify the sender's message signature when receive_tx in wallet listen * Revert "remove debug log on verify_slate_messages" This reverts commit 65ea32a407bfd57d02bf169803f1483ba611962e. * Revert "rustfmt" This reverts commit c380ab91856344b73595bb04eef1fc087dedd84d. * Revert "(1)add verify_slate_messages for wallet receive (2)log the message content" This reverts commit 9584ca7a893b22a768dea061039140033c07e8eb. * [re-floonet] Keychain Floonet BIP32 version/network option (#2235) * add 'is_floonet' property to keychain * fix hex encoding and tests * Fix couple floonet loose ends (#2230) * Fix couple floonet loose ends. Fixes #2216 * Doc fix for sig message * Refuse unkown kernel features (#2244) * Minor: magic number change for re-floonet * Set pre genesis is_secondary to true (#2247) * Minor: tx validation error display underlying * New floonet genesis * genesis rustfmt * Use chain-specific config for wallet toml gen * Fix default wallet_listener_url * New more reasonable genesis block, bumped version * genesis rustfmt * Couple minor fixes to genesis generation script
2018-12-29 01:46:21 +03:00
println!("proof {}", global::proofsize());
2017-09-29 21:44:25 +03:00
pow_size(
&mut b.header,
Difficulty::min(),
global::proofsize(),
global::min_edge_bits(),
)
.unwrap();
Re-launch floonet (#2249) * Fix secondary scaling bugs; rename is_testnet -> is_floonet (#2215) * add global::is_mainnet() * use it to change pre-genesis pow type * rename is_testnet -> is_floonet * Support multiple chain configurations (#2217) * Support multiple chain configurations Supports generating the proper configuration for each chain type (mainnet, floonet, usernet). Will run them by default under their respective root directory (~/.grin/main, ~/.grin/floo, etc). Assigned default ports for mainnet, overriding them to keep Floonet ports unchanged. For now, starting on mainnet will abort. * Fixed usernet command line help message. Fixes #2217 * Differing magic numbers for each chain type (#2208) * stick to e=H(R|P|m) when use schnorr signature (#2200) * stick to e=H(R|P|m) when use schnorr signature * (1)add verify_slate_messages for wallet receive (2)log the message content * remove debug log on verify_slate_messages * verify the sender's message signature when receive_tx in wallet listen * Revert "remove debug log on verify_slate_messages" This reverts commit 65ea32a407bfd57d02bf169803f1483ba611962e. * Revert "rustfmt" This reverts commit c380ab91856344b73595bb04eef1fc087dedd84d. * Revert "(1)add verify_slate_messages for wallet receive (2)log the message content" This reverts commit 9584ca7a893b22a768dea061039140033c07e8eb. * [re-floonet] Keychain Floonet BIP32 version/network option (#2235) * add 'is_floonet' property to keychain * fix hex encoding and tests * Fix couple floonet loose ends (#2230) * Fix couple floonet loose ends. Fixes #2216 * Doc fix for sig message * Refuse unkown kernel features (#2244) * Minor: magic number change for re-floonet * Set pre genesis is_secondary to true (#2247) * Minor: tx validation error display underlying * New floonet genesis * genesis rustfmt * Use chain-specific config for wallet toml gen * Fix default wallet_listener_url * New more reasonable genesis block, bumped version * genesis rustfmt * Couple minor fixes to genesis generation script
2018-12-29 01:46:21 +03:00
println!("nonce {}", b.header.pow.nonce);
assert_ne!(b.header.pow.nonce, 310);
assert!(b.header.pow.to_difficulty(0) >= Difficulty::min());
2018-12-29 05:00:44 +03:00
assert!(verify_size(&b.header).is_ok());
2016-10-21 03:06:12 +03:00
}
}