From 3e7bc2888c4f23d3a362dd777ed28a4c9ab0b5ae Mon Sep 17 00:00:00 2001 From: Ignotus Peverell Date: Tue, 11 Dec 2018 00:39:39 +0000 Subject: [PATCH 01/14] Get last bitcon block hash, setup genesis header without PoW (for now) --- Cargo.toml | 1 + etc/gen_gen/Cargo.toml | 24 +++++++ etc/gen_gen/README.md | 18 ++++++ etc/gen_gen/src/bin/gen_gen.rs | 114 +++++++++++++++++++++++++++++++++ 4 files changed, 157 insertions(+) create mode 100644 etc/gen_gen/Cargo.toml create mode 100644 etc/gen_gen/README.md create mode 100644 etc/gen_gen/src/bin/gen_gen.rs diff --git a/Cargo.toml b/Cargo.toml index ad5625825..8a9fc7881 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ build = "src/build/build.rs" [workspace] members = ["api", "chain", "config", "core", "keychain", "p2p", "servers", "store", "util", "pool", "wallet"] +exclude = ["etc/gen_gen"] [[bin]] name = "grin" diff --git a/etc/gen_gen/Cargo.toml b/etc/gen_gen/Cargo.toml new file mode 100644 index 000000000..b90811c3f --- /dev/null +++ b/etc/gen_gen/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "grin_gen_gen" +version = "0.0.1" +edition = "2018" +authors = ["Grin Developers "] +description = "Utility to automate the generation of Grin's genesis block" +license = "Apache-2.0" +repository = "https://github.com/mimblewimble/grin" +keywords = [ "crypto", "grin", "mimblewimble" ] +readme = "README.md" + +[[bin]] +name = "gen_gen" +path = "src/bin/gen_gen.rs" + +[dependencies] +chrono = "0.4.4" +curl = "0.4.19" +serde_json = "1" +grin_core = "0.4.2" +grin_chain = "0.4.2" +grin_keychain = "0.4.2" +grin_store = "0.4.2" +grin_util = "0.4.2" diff --git a/etc/gen_gen/README.md b/etc/gen_gen/README.md new file mode 100644 index 000000000..d97b67579 --- /dev/null +++ b/etc/gen_gen/README.md @@ -0,0 +1,18 @@ +# Genesis Genesis + +This crate isn't strictly part of grin but allows the generation and release of a new Grin Genesis in an automated fashion. The process is the following: + +* Prepare a multisig output and kernel to use as coinbase. In the case of Grin mainnet, this is done and owned by the council treasurers. This can be down a few days prior. +* Grab the latest bitcoin block hash from publicly available APIs. +* Build a genesis block with the prepared coinbase and the bitcoin block hash as `prev_root`. The timestamp of the block is set to 30 min ahead to leave enough time to run a build and start a node. +* Mine the block so we have at least a valid Cuckatoo Cycle. We don't require a given difficulty for that solution. +* Finalize the block with the proof-of-work, setting a high-enough difficulty (to be agreed upon separately). +* Commit the block information to github. +* Tag version 1.0.0 (scary). + +N.B. This was written while listening to Genesis. Unfortunately, I'm not rich enough to do it while driving a Genesis. And that'd be dangerous. + +# Usage + +1. Build this crate. +2. From its root run `./target/release/gen-gen --coinbase --difficulty --tag ` diff --git a/etc/gen_gen/src/bin/gen_gen.rs b/etc/gen_gen/src/bin/gen_gen.rs new file mode 100644 index 000000000..a2ee67ab3 --- /dev/null +++ b/etc/gen_gen/src/bin/gen_gen.rs @@ -0,0 +1,114 @@ +// Copyright 2018 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. + +//! Main for building the genesis generation utility. + +use std::fs; +use std::sync::Arc; + +use chrono::Duration; +use chrono::prelude::Utc; +use curl; +use serde_json; + +use grin_chain as chain; +use grin_core as core; +use grin_store as store; +use grin_util as util; + +use grin_keychain::{ExtKeychain, Keychain}; + +static BCHAIN_INFO_URL: &str = "https://blockchain.info/latestblock"; +static BCYPHER_URL: &str = "https://api.blockcypher.com/v1/btc/main"; +static BCHAIR_URL: &str = "https://api.blockchair.com/bitcoin/blocks?limit=2"; + +fn main() { + // get the latest bitcoin hash + let h1 = get_bchain_head(); + let h2 = get_bcypher_head(); + let h3 = get_bchair_head(); + if h1 != h2 || h1 != h3 { + panic!("Bitcoin chain head is inconsistent, please retry."); + } + println!("Using bitcoin block hash {}", h1); + + // build the basic parts of the genesis block header, perhaps some of this + // can be moved to core + let mut gen = core::genesis::genesis_main(); + gen.header.timestamp = Utc::now() + Duration::minutes(30); + gen.header.prev_root = core::core::hash::Hash::from_hex(&h1).unwrap(); + gen.header.pow.proof.edge_bits = 29; + println!("Built genesis:\n{:?}", gen); + + // TODO get the proper keychain and/or raw coinbase + let keychain = ExtKeychain::from_random_seed().unwrap(); + let key_id = ExtKeychain::derive_key_id(0, 1, 0, 0, 0); + let reward = core::libtx::reward::output(&keychain, &key_id, 0, 0).unwrap(); + gen = gen.with_reward(reward.0, reward.1); + + { + // setup a tmp chain to set block header roots + let tmp_chain = setup_chain(".grin.tmp", core::pow::mine_genesis_block().unwrap()); + tmp_chain.set_txhashset_roots(&mut gen).unwrap(); + gen.header.output_mmr_size = 1; + gen.header.kernel_mmr_size = 1; + } + + // TODO mine a valid Cuckatoo29 solution + // TODO check again the bitcoin block to make sure it's not been orphaned + // TODO Commit genesis block info in git and tag +} + +fn setup_chain(dir_name: &str, genesis: core::core::Block) -> chain::Chain { + util::init_test_logger(); + let _ = fs::remove_dir_all(dir_name); + let verifier_cache = Arc::new(util::RwLock::new(core::core::verifier_cache::LruVerifierCache::new())); + let db_env = Arc::new(store::new_env(dir_name.to_string())); + chain::Chain::init( + dir_name.to_string(), + db_env, + Arc::new(chain::types::NoopAdapter {}), + genesis, + core::pow::verify_size, + verifier_cache, + false, + ).unwrap() +} + +fn get_bchain_head() -> String { + get_json(BCHAIN_INFO_URL)["hash"].as_str().unwrap().to_string() +} + +fn get_bcypher_head() -> String { + get_json(BCYPHER_URL)["hash"].as_str().unwrap().to_string() +} + +fn get_bchair_head() -> String { + get_json(BCHAIR_URL)["data"][0]["hash"].as_str().unwrap().to_string() +} + +fn get_json(url: &str) -> serde_json::Value { + let mut body = Vec::new(); + let mut easy = curl::easy::Easy::new(); + easy.url(url).unwrap(); + { + let mut transfer = easy.transfer(); + transfer.write_function(|data| { + body.extend_from_slice(data); + Ok(data.len()) + }).unwrap(); + transfer.perform().unwrap(); + } + serde_json::from_slice(&body).unwrap() +} From 934b11d06f228162765c4eb3c69ad085a1de592e Mon Sep 17 00:00:00 2001 From: Ignotus Peverell Date: Tue, 11 Dec 2018 01:07:17 +0000 Subject: [PATCH 02/14] More a few properties to mainnet genesis. Don't get too excited, several are placeholders. --- Cargo.lock | 2 -- Cargo.toml | 1 + core/src/genesis.rs | 18 ++++++++++-------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5c13bdd0a..c85e4cffc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -751,7 +751,6 @@ dependencies = [ "grin_keychain 0.4.2", "grin_store 0.4.2", "grin_util 0.4.2", - "grin_wallet 0.4.2", "lmdb-zero 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -854,7 +853,6 @@ dependencies = [ "grin_keychain 0.4.2", "grin_store 0.4.2", "grin_util 0.4.2", - "grin_wallet 0.4.2", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index ad5625825..8a9fc7881 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ build = "src/build/build.rs" [workspace] members = ["api", "chain", "config", "core", "keychain", "p2p", "servers", "store", "util", "pool", "wallet"] +exclude = ["etc/gen_gen"] [[bin]] name = "grin" diff --git a/core/src/genesis.rs b/core/src/genesis.rs index 01be438c4..e1f34a115 100644 --- a/core/src/genesis.rs +++ b/core/src/genesis.rs @@ -16,7 +16,6 @@ use chrono::prelude::{TimeZone, Utc}; -use consensus; use core; use global; use pow::{Difficulty, Proof, ProofOfWork}; @@ -110,7 +109,6 @@ pub fn genesis_testnet3() -> core::Block { pub fn genesis_testnet4() -> core::Block { core::Block::with_header(core::BlockHeader { height: 0, - // previous: core::hash::Hash([0xff; 32]), timestamp: Utc.ymd(2018, 10, 17).and_hms(20, 0, 0), pow: ProofOfWork { total_difficulty: Difficulty::from_num(global::initial_block_difficulty()), @@ -137,13 +135,17 @@ pub fn genesis_testnet4() -> core::Block { pub fn genesis_main() -> core::Block { core::Block::with_header(core::BlockHeader { height: 0, - // previous: core::hash::Hash([0xff; 32]), - timestamp: Utc.ymd(2018, 8, 14).and_hms(0, 0, 0), + timestamp: Utc.ymd(2019, 0, 15).and_hms(12, 0, 0), + output_mmr_size: 1, + kernel_mmr_size: 1, pow: ProofOfWork { - total_difficulty: Difficulty::from_num(global::initial_block_difficulty()), - secondary_scaling: 1, - nonce: global::get_genesis_nonce(), - proof: Proof::zero(consensus::PROOFSIZE), + total_difficulty: Difficulty::from_num(10_u64.pow(8)), + secondary_scaling: 1856, + nonce: 1, + proof: Proof { + nonces: vec![0; 42], + edge_bits: 29, + }, }, ..Default::default() }) From a58235f603ce72b9c3af346cefe592ff8d3e2235 Mon Sep 17 00:00:00 2001 From: Ignotus Peverell Date: Tue, 11 Dec 2018 01:08:02 +0000 Subject: [PATCH 03/14] Trying to fix slight snafu --- etc/gen_gen/Cargo.toml | 24 +++++++ etc/gen_gen/README.md | 18 +++++ etc/gen_gen/src/bin/gen_gen.rs | 125 +++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+) create mode 100644 etc/gen_gen/Cargo.toml create mode 100644 etc/gen_gen/README.md create mode 100644 etc/gen_gen/src/bin/gen_gen.rs diff --git a/etc/gen_gen/Cargo.toml b/etc/gen_gen/Cargo.toml new file mode 100644 index 000000000..00a9024f9 --- /dev/null +++ b/etc/gen_gen/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "grin_gen_gen" +version = "0.0.1" +edition = "2018" +authors = ["Grin Developers "] +description = "Utility to automate the generation of Grin's genesis block" +license = "Apache-2.0" +repository = "https://github.com/mimblewimble/grin" +keywords = [ "crypto", "grin", "mimblewimble" ] +readme = "README.md" + +[[bin]] +name = "gen_gen" +path = "src/bin/gen_gen.rs" + +[dependencies] +chrono = "0.4.4" +curl = "0.4.19" +serde_json = "1" +grin_core = { path = "../../core", version = "0.4.2" } +grin_chain = "0.4.2" +grin_keychain = "0.4.2" +grin_store = "0.4.2" +grin_util = "0.4.2" diff --git a/etc/gen_gen/README.md b/etc/gen_gen/README.md new file mode 100644 index 000000000..d97b67579 --- /dev/null +++ b/etc/gen_gen/README.md @@ -0,0 +1,18 @@ +# Genesis Genesis + +This crate isn't strictly part of grin but allows the generation and release of a new Grin Genesis in an automated fashion. The process is the following: + +* Prepare a multisig output and kernel to use as coinbase. In the case of Grin mainnet, this is done and owned by the council treasurers. This can be down a few days prior. +* Grab the latest bitcoin block hash from publicly available APIs. +* Build a genesis block with the prepared coinbase and the bitcoin block hash as `prev_root`. The timestamp of the block is set to 30 min ahead to leave enough time to run a build and start a node. +* Mine the block so we have at least a valid Cuckatoo Cycle. We don't require a given difficulty for that solution. +* Finalize the block with the proof-of-work, setting a high-enough difficulty (to be agreed upon separately). +* Commit the block information to github. +* Tag version 1.0.0 (scary). + +N.B. This was written while listening to Genesis. Unfortunately, I'm not rich enough to do it while driving a Genesis. And that'd be dangerous. + +# Usage + +1. Build this crate. +2. From its root run `./target/release/gen-gen --coinbase --difficulty --tag ` diff --git a/etc/gen_gen/src/bin/gen_gen.rs b/etc/gen_gen/src/bin/gen_gen.rs new file mode 100644 index 000000000..c7311a589 --- /dev/null +++ b/etc/gen_gen/src/bin/gen_gen.rs @@ -0,0 +1,125 @@ +// Copyright 2018 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. + +//! Main for building the genesis generation utility. + +use std::fs; +use std::sync::Arc; + +use chrono::prelude::Utc; +use chrono::Duration; +use curl; +use serde_json; + +use grin_chain as chain; +use grin_core as core; +use grin_store as store; +use grin_util as util; + +use grin_keychain::{ExtKeychain, Keychain}; + +static BCHAIN_INFO_URL: &str = "https://blockchain.info/latestblock"; +static BCYPHER_URL: &str = "https://api.blockcypher.com/v1/btc/main"; +static BCHAIR_URL: &str = "https://api.blockchair.com/bitcoin/blocks?limit=2"; + +fn main() { + // get the latest bitcoin hash + let h1 = get_bchain_head(); + let h2 = get_bcypher_head(); + let h3 = get_bchair_head(); + if h1 != h2 || h1 != h3 { + panic!( + "Bitcoin chain head is inconsistent, please retry ({}, {}, {}).", + h1, h2, h3 + ); + } + println!("Using bitcoin block hash {}", h1); + + // build the basic parts of the genesis block header, perhaps some of this + // can be moved to core + let mut gen = core::genesis::genesis_main(); + gen.header.timestamp = Utc::now() + Duration::minutes(30); + gen.header.prev_root = core::core::hash::Hash::from_hex(&h1).unwrap(); + println!("Built genesis:\n{:?}", gen); + + // TODO get the proper keychain and/or raw coinbase + let keychain = ExtKeychain::from_random_seed().unwrap(); + let key_id = ExtKeychain::derive_key_id(0, 1, 0, 0, 0); + let reward = core::libtx::reward::output(&keychain, &key_id, 0, 0).unwrap(); + gen = gen.with_reward(reward.0, reward.1); + + { + // setup a tmp chain to set block header roots + let tmp_chain = setup_chain(".grin.tmp", core::pow::mine_genesis_block().unwrap()); + tmp_chain.set_txhashset_roots(&mut gen).unwrap(); + } + + // TODO mine a valid Cuckatoo29 solution + // TODO check again the bitcoin block to make sure it's not been orphaned + // TODO Commit genesis block info in git and tag +} + +fn setup_chain(dir_name: &str, genesis: core::core::Block) -> chain::Chain { + util::init_test_logger(); + let _ = fs::remove_dir_all(dir_name); + let verifier_cache = Arc::new(util::RwLock::new( + core::core::verifier_cache::LruVerifierCache::new(), + )); + let db_env = Arc::new(store::new_env(dir_name.to_string())); + chain::Chain::init( + dir_name.to_string(), + db_env, + Arc::new(chain::types::NoopAdapter {}), + genesis, + core::pow::verify_size, + verifier_cache, + false, + ) + .unwrap() +} + +fn get_bchain_head() -> String { + get_json(BCHAIN_INFO_URL)["hash"] + .as_str() + .unwrap() + .to_string() +} + +fn get_bcypher_head() -> String { + get_json(BCYPHER_URL)["hash"].as_str().unwrap().to_string() +} + +fn get_bchair_head() -> String { + get_json(BCHAIR_URL)["data"][0]["hash"] + .as_str() + .unwrap() + .to_string() +} + +fn get_json(url: &str) -> serde_json::Value { + let mut body = Vec::new(); + let mut easy = curl::easy::Easy::new(); + easy.url(url).unwrap(); + { + let mut transfer = easy.transfer(); + transfer + .write_function(|data| { + body.extend_from_slice(data); + Ok(data.len()) + }) + .unwrap(); + transfer.perform().unwrap(); + } + serde_json::from_slice(&body).unwrap() +} From 725499bbf0d21de6655d0c4525a5c4bada0d4f7a Mon Sep 17 00:00:00 2001 From: Ignotus Peverell Date: Tue, 11 Dec 2018 01:09:28 +0000 Subject: [PATCH 04/14] Trying to fix slight snafu --- etc/gen_gen/src/bin/gen_gen.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/etc/gen_gen/src/bin/gen_gen.rs b/etc/gen_gen/src/bin/gen_gen.rs index f7b0c57fa..c7311a589 100644 --- a/etc/gen_gen/src/bin/gen_gen.rs +++ b/etc/gen_gen/src/bin/gen_gen.rs @@ -17,13 +17,8 @@ use std::fs; use std::sync::Arc; -<<<<<<< HEAD use chrono::prelude::Utc; use chrono::Duration; -======= -use chrono::Duration; -use chrono::prelude::Utc; ->>>>>>> 3e7bc2888c4f23d3a362dd777ed28a4c9ab0b5ae use curl; use serde_json; From 31e69e66ac14b8b549da7245eef23008d01ecc85 Mon Sep 17 00:00:00 2001 From: Ignotus Peverell Date: Wed, 12 Dec 2018 23:29:06 +0000 Subject: [PATCH 05/14] Mine a valid Cuckaroo solution for genesis block --- etc/gen_gen/Cargo.toml | 6 ++++-- etc/gen_gen/src/bin/gen_gen.rs | 29 +++++++++++++++++++++++++++-- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/etc/gen_gen/Cargo.toml b/etc/gen_gen/Cargo.toml index 00a9024f9..a985f6488 100644 --- a/etc/gen_gen/Cargo.toml +++ b/etc/gen_gen/Cargo.toml @@ -15,10 +15,12 @@ path = "src/bin/gen_gen.rs" [dependencies] chrono = "0.4.4" +cuckoo_miner = "0.4.2" curl = "0.4.19" -serde_json = "1" -grin_core = { path = "../../core", version = "0.4.2" } +grin_core = "0.4.2" grin_chain = "0.4.2" grin_keychain = "0.4.2" +grin_miner_plugin = "0.4.2" grin_store = "0.4.2" grin_util = "0.4.2" +serde_json = "1" diff --git a/etc/gen_gen/src/bin/gen_gen.rs b/etc/gen_gen/src/bin/gen_gen.rs index c7311a589..efea9185a 100644 --- a/etc/gen_gen/src/bin/gen_gen.rs +++ b/etc/gen_gen/src/bin/gen_gen.rs @@ -22,18 +22,23 @@ use chrono::Duration; use curl; use serde_json; +use cuckoo_miner as cuckoo; use grin_chain as chain; use grin_core as core; +use grin_miner_plugin as plugin; use grin_store as store; use grin_util as util; -use grin_keychain::{ExtKeychain, Keychain}; +use grin_core::core::verifier_cache::LruVerifierCache; +use grin_keychain::{ExtKeychain, Keychain, BlindingFactor}; static BCHAIN_INFO_URL: &str = "https://blockchain.info/latestblock"; static BCYPHER_URL: &str = "https://api.blockcypher.com/v1/btc/main"; static BCHAIR_URL: &str = "https://api.blockchair.com/bitcoin/blocks?limit=2"; fn main() { + core::global::set_mining_mode(core::global::ChainTypes::Mainnet); + // get the latest bitcoin hash let h1 = get_bchain_head(); let h2 = get_bcypher_head(); @@ -65,7 +70,27 @@ fn main() { tmp_chain.set_txhashset_roots(&mut gen).unwrap(); } - // TODO mine a valid Cuckatoo29 solution + // mine a Cuckaroo29 block + let plugin_path = "cuckaroo_mean_cuda_29.cuckooplugin"; + let plugin_lib = cuckoo::PluginLibrary::new(plugin_path).unwrap(); + let solver_ctx = plugin_lib.create_solver_ctx(&mut plugin_lib.get_default_params()); + + let mut solver_sols = plugin::SolverSolutions::default(); + let mut solver_stats = plugin::SolverStats::default(); + let mut nonce = 0; + while solver_sols.num_sols == 0 { + solver_sols = plugin::SolverSolutions::default(); + plugin_lib.run_solver(solver_ctx, gen.header.pre_pow(), nonce, 1, &mut solver_sols, &mut solver_stats); + nonce += 1; + } + + // set the PoW solution and make sure the block is mostly valid + gen.header.pow.nonce = solver_sols.sols[0].nonce as u64; + gen.header.pow.proof.nonces = solver_sols.sols[0].to_u64s(); + assert!(gen.header.pow.is_secondary(), "Not a secondary header"); + core::pow::verify_size(&gen.header).unwrap(); + gen.validate(&BlindingFactor::zero(), Arc::new(util::RwLock::new(LruVerifierCache::new()))).unwrap(); + // TODO check again the bitcoin block to make sure it's not been orphaned // TODO Commit genesis block info in git and tag } From 18416e85287f71beda1abb099a1b469485d5c547 Mon Sep 17 00:00:00 2001 From: Ignotus Peverell Date: Thu, 13 Dec 2018 01:54:25 +0000 Subject: [PATCH 06/14] Use miner as library to get a solution for genesis. Replace final values in genesis.rs before committing it. --- core/src/genesis.rs | 28 +++++++- etc/gen_gen/src/bin/gen_gen.rs | 117 ++++++++++++++++++++++++++++++--- 2 files changed, 134 insertions(+), 11 deletions(-) diff --git a/core/src/genesis.rs b/core/src/genesis.rs index d26b3b9ae..98ed3aa97 100644 --- a/core/src/genesis.rs +++ b/core/src/genesis.rs @@ -20,6 +20,9 @@ use crate::core; use crate::global; use crate::pow::{Difficulty, Proof, ProofOfWork}; +use crate::core::hash::Hash; +use crate::keychain::BlindingFactor; + /// Genesis block definition for development networks. The proof of work size /// is small enough to mine it on the fly, so it does not contain its own /// proof of work solution. Can also be easily mutated for different tests. @@ -135,18 +138,37 @@ pub fn genesis_testnet4() -> core::Block { pub fn genesis_main() -> core::Block { core::Block::with_header(core::BlockHeader { height: 0, - timestamp: Utc.ymd(2019, 0, 15).and_hms(12, 0, 0), + timestamp: Utc.ymd(2019, 1, 15).and_hms(12, 0, 0), // REPLACE + prev_root: Hash::default(), // REPLACE + output_root: Hash::default(), // REPLACE + range_proof_root: Hash::default(), // REPLACE + kernel_root: Hash::default(), // REPLACE + total_kernel_offset: BlindingFactor::zero(), // REPLACE output_mmr_size: 1, kernel_mmr_size: 1, pow: ProofOfWork { total_difficulty: Difficulty::from_num(10_u64.pow(8)), secondary_scaling: 1856, - nonce: 1, + nonce: 1, // REPLACE proof: Proof { - nonces: vec![0; 42], + nonces: vec![0; 42], // REPLACE edge_bits: 29, }, }, ..Default::default() }) } + + +#[cfg(test)] +mod test { + use super::*; + + // TODO update the hash once genesis is set + #[test] + fn mainnet_genesis_hash() { + let gen_hash = genesis_main().hash(); + println!("mainnet genesis hash: {}", gen_hash.to_hex()); + //assert_eq!(gene_hash.to_hex, ""); + } +} diff --git a/etc/gen_gen/src/bin/gen_gen.rs b/etc/gen_gen/src/bin/gen_gen.rs index efea9185a..60f0f0e9e 100644 --- a/etc/gen_gen/src/bin/gen_gen.rs +++ b/etc/gen_gen/src/bin/gen_gen.rs @@ -14,11 +14,12 @@ //! Main for building the genesis generation utility. -use std::fs; +use std::{fs, io, path, process}; +use std::io::{BufRead, Write}; use std::sync::Arc; use chrono::prelude::Utc; -use chrono::Duration; +use chrono::{Duration, Timelike, Datelike}; use curl; use serde_json; @@ -30,14 +31,23 @@ use grin_store as store; use grin_util as util; use grin_core::core::verifier_cache::LruVerifierCache; -use grin_keychain::{ExtKeychain, Keychain, BlindingFactor}; +use grin_keychain::{BlindingFactor, ExtKeychain, Keychain}; static BCHAIN_INFO_URL: &str = "https://blockchain.info/latestblock"; static BCYPHER_URL: &str = "https://api.blockcypher.com/v1/btc/main"; static BCHAIR_URL: &str = "https://api.blockchair.com/bitcoin/blocks?limit=2"; +static GENESIS_RS_PATH: &str = "../../core/src/genesis.rs"; +static PLUGIN_PATH: &str = "cuckaroo_mean_cuda_29.cuckooplugin"; + fn main() { core::global::set_mining_mode(core::global::ChainTypes::Mainnet); + if !path::Path::new(GENESIS_RS_PATH).exists() { + panic!("File {} not found, make sure you're running this from the gen_gen directory", GENESIS_RS_PATH); + } + if !path::Path::new(PLUGIN_PATH).exists() { + panic!("File {} not found, make sure you're running this from the gen_gen directory", PLUGIN_PATH); + } // get the latest bitcoin hash let h1 = get_bchain_head(); @@ -71,8 +81,7 @@ fn main() { } // mine a Cuckaroo29 block - let plugin_path = "cuckaroo_mean_cuda_29.cuckooplugin"; - let plugin_lib = cuckoo::PluginLibrary::new(plugin_path).unwrap(); + let plugin_lib = cuckoo::PluginLibrary::new(PLUGIN_PATH).unwrap(); let solver_ctx = plugin_lib.create_solver_ctx(&mut plugin_lib.get_default_params()); let mut solver_sols = plugin::SolverSolutions::default(); @@ -80,7 +89,14 @@ fn main() { let mut nonce = 0; while solver_sols.num_sols == 0 { solver_sols = plugin::SolverSolutions::default(); - plugin_lib.run_solver(solver_ctx, gen.header.pre_pow(), nonce, 1, &mut solver_sols, &mut solver_stats); + plugin_lib.run_solver( + solver_ctx, + gen.header.pre_pow(), + nonce, + 1, + &mut solver_sols, + &mut solver_stats, + ); nonce += 1; } @@ -89,10 +105,95 @@ fn main() { gen.header.pow.proof.nonces = solver_sols.sols[0].to_u64s(); assert!(gen.header.pow.is_secondary(), "Not a secondary header"); core::pow::verify_size(&gen.header).unwrap(); - gen.validate(&BlindingFactor::zero(), Arc::new(util::RwLock::new(LruVerifierCache::new()))).unwrap(); + gen.validate( + &BlindingFactor::zero(), + Arc::new(util::RwLock::new(LruVerifierCache::new())), + ) + .unwrap(); + + println!("Final genesis hash: {}", gen.hash().to_hex()); // TODO check again the bitcoin block to make sure it's not been orphaned - // TODO Commit genesis block info in git and tag + + update_genesis_rs(&gen); + println!("genesis.rs has been updated, check it and press c+enter to proceed."); + let mut input = String::new(); + io::stdin().read_line(&mut input).unwrap(); + if input != "c" { + return + } + + // Commit genesis block info in git and tag + process::Command::new("git") + .args(&["commit", "-am", "Minor: finalized genesis block"]) + .status() + .expect("git commit failed"); + process::Command::new("git") + .args(&["tag", "-a", "v1.0", "-m", "Mainnet release"]) + .status() + .expect("git tag failed"); + process::Command::new("git") + .args(&["push", "origin", "v1.0"]) + .status() + .expect("git tag push failed"); + println!("All done!"); +} + +fn update_genesis_rs(gen: &core::core::Block) { + // TODO coinbase output and kernel + + // set the replacement patterns + let mut replacements = vec![]; + replacements.push(( + "timestamp".to_string(), + format!( + "Utc.ymd({}, {}, {}).and_hms({}, {}, {})", + gen.header.timestamp.date().year(), + gen.header.timestamp.date().month(), + gen.header.timestamp.date().day(), + gen.header.timestamp.time().hour(), + gen.header.timestamp.time().minute(), + gen.header.timestamp.time().second(), + ), + )); + replacements.push(( + "output_root".to_string(), + format!("Hash::from_hex(\"{}\")", gen.header.output_root.to_hex()), + )); + replacements.push(( + "range_proof_root".to_string(), + format!("Hash::from_hex(\"{}\")", gen.header.range_proof_root.to_hex()), + )); + replacements.push(( + "kernel_root".to_string(), + format!("Hash::from_hex(\"{}\")", gen.header.kernel_root.to_hex()), + )); + + // check each possible replacement in the file + let mut replaced = String::new(); + { + let genesis_rs = fs::File::open(GENESIS_RS_PATH).unwrap(); + let reader = io::BufReader::new(&genesis_rs); + for rline in reader.lines() { + let line = rline.unwrap(); + let mut has_replaced = false; + if line.contains("REPLACE") { + for (pos, replacement) in replacements.iter().enumerate() { + if line.contains(&replacement.0) { + replaced.push_str(&format!("{}: {},\n", replacement.0, replacement.1)); + replacements.remove(pos); + has_replaced = true; + break; + } + } + if !has_replaced { + replaced.push_str(&format!("{}\n", line)); + } + } + } + } + let mut genesis_rs = fs::File::create(GENESIS_RS_PATH).unwrap(); + genesis_rs.write_all(replaced.as_bytes()).unwrap(); } fn setup_chain(dir_name: &str, genesis: core::core::Block) -> chain::Chain { From 2386ce3b8ac2962c2261e5360e2de5ee8e511d38 Mon Sep 17 00:00:00 2001 From: Ignotus Peverell Date: Fri, 14 Dec 2018 00:46:41 +0000 Subject: [PATCH 07/14] Complete genesis replacement --- core/src/genesis.rs | 30 ++++++++---- core/src/global.rs | 2 + etc/gen_gen/Cargo.toml | 4 ++ etc/gen_gen/src/bin/gen_gen.rs | 83 +++++++++++++++++++++++++++------- 4 files changed, 95 insertions(+), 24 deletions(-) diff --git a/core/src/genesis.rs b/core/src/genesis.rs index 98ed3aa97..1e90df646 100644 --- a/core/src/genesis.rs +++ b/core/src/genesis.rs @@ -19,6 +19,8 @@ use chrono::prelude::{TimeZone, Utc}; use crate::core; use crate::global; use crate::pow::{Difficulty, Proof, ProofOfWork}; +use crate::util::secp::Signature; +use crate::util::secp::pedersen::{Commitment, RangeProof}; use crate::core::hash::Hash; use crate::keychain::BlindingFactor; @@ -136,14 +138,14 @@ pub fn genesis_testnet4() -> core::Block { /// Placeholder for mainnet genesis block, will definitely change before /// release so no use trying to pre-mine it. pub fn genesis_main() -> core::Block { - core::Block::with_header(core::BlockHeader { + let gen = core::Block::with_header(core::BlockHeader { height: 0, timestamp: Utc.ymd(2019, 1, 15).and_hms(12, 0, 0), // REPLACE - prev_root: Hash::default(), // REPLACE - output_root: Hash::default(), // REPLACE - range_proof_root: Hash::default(), // REPLACE - kernel_root: Hash::default(), // REPLACE - total_kernel_offset: BlindingFactor::zero(), // REPLACE + prev_root: Hash::default(), // REPLACE + output_root: Hash::default(), // REPLACE + range_proof_root: Hash::default(), // REPLACE + kernel_root: Hash::default(), // REPLACE + total_kernel_offset: BlindingFactor::zero(), // REPLACE output_mmr_size: 1, kernel_mmr_size: 1, pow: ProofOfWork { @@ -156,10 +158,22 @@ pub fn genesis_main() -> core::Block { }, }, ..Default::default() - }) + }); + let kernel = core::TxKernel { + features: core::KernelFeatures::COINBASE_KERNEL, + fee: 0, + lock_height: 0, + excess: Commitment::from_vec(vec![]), // REPLACE + excess_sig: Signature::from_raw_data(&[0; 64]).unwrap(), //REPLACE + }; + let output = core::Output { + features: core::OutputFeatures::COINBASE_OUTPUT, + commit: Commitment::from_vec(vec![]), // REPLACE + proof: RangeProof::zero(), // REPLACE + }; + gen.with_reward(output, kernel) } - #[cfg(test)] mod test { use super::*; diff --git a/core/src/global.rs b/core/src/global.rs index 30a38374d..9384d1d75 100644 --- a/core/src/global.rs +++ b/core/src/global.rs @@ -311,6 +311,8 @@ pub fn get_genesis_nonce() -> u64 { ChainTypes::AutomatedTesting => 0, // Magic nonce for current genesis block at cuckatoo15 ChainTypes::UserTesting => 27944, + // Placeholder, obviously not the right value + ChainTypes::Mainnet => 0, // Magic nonce for genesis block for testnet2 (cuckatoo29) _ => panic!("Pre-set"), } diff --git a/etc/gen_gen/Cargo.toml b/etc/gen_gen/Cargo.toml index a985f6488..f1d394592 100644 --- a/etc/gen_gen/Cargo.toml +++ b/etc/gen_gen/Cargo.toml @@ -24,3 +24,7 @@ grin_miner_plugin = "0.4.2" grin_store = "0.4.2" grin_util = "0.4.2" serde_json = "1" + +[patch.crates-io] +grin_core = { path = "../../core" } +grin_keychain = { path = "../../keychain" } diff --git a/etc/gen_gen/src/bin/gen_gen.rs b/etc/gen_gen/src/bin/gen_gen.rs index 60f0f0e9e..7e4dea486 100644 --- a/etc/gen_gen/src/bin/gen_gen.rs +++ b/etc/gen_gen/src/bin/gen_gen.rs @@ -14,12 +14,12 @@ //! Main for building the genesis generation utility. -use std::{fs, io, path, process}; use std::io::{BufRead, Write}; use std::sync::Arc; +use std::{fs, io, path, process}; use chrono::prelude::Utc; -use chrono::{Duration, Timelike, Datelike}; +use chrono::{Datelike, Duration, Timelike}; use curl; use serde_json; @@ -43,10 +43,16 @@ static PLUGIN_PATH: &str = "cuckaroo_mean_cuda_29.cuckooplugin"; fn main() { core::global::set_mining_mode(core::global::ChainTypes::Mainnet); if !path::Path::new(GENESIS_RS_PATH).exists() { - panic!("File {} not found, make sure you're running this from the gen_gen directory", GENESIS_RS_PATH); + panic!( + "File {} not found, make sure you're running this from the gen_gen directory", + GENESIS_RS_PATH + ); } if !path::Path::new(PLUGIN_PATH).exists() { - panic!("File {} not found, make sure you're running this from the gen_gen directory", PLUGIN_PATH); + panic!( + "File {} not found, make sure you're running this from the gen_gen directory", + PLUGIN_PATH + ); } // get the latest bitcoin hash @@ -61,12 +67,10 @@ fn main() { } println!("Using bitcoin block hash {}", h1); - // build the basic parts of the genesis block header, perhaps some of this - // can be moved to core + // build the basic parts of the genesis block header let mut gen = core::genesis::genesis_main(); gen.header.timestamp = Utc::now() + Duration::minutes(30); gen.header.prev_root = core::core::hash::Hash::from_hex(&h1).unwrap(); - println!("Built genesis:\n{:?}", gen); // TODO get the proper keychain and/or raw coinbase let keychain = ExtKeychain::from_random_seed().unwrap(); @@ -100,7 +104,7 @@ fn main() { nonce += 1; } - // set the PoW solution and make sure the block is mostly valid + // // set the PoW solution and make sure the block is mostly valid gen.header.pow.nonce = solver_sols.sols[0].nonce as u64; gen.header.pow.proof.nonces = solver_sols.sols[0].to_u64s(); assert!(gen.header.pow.is_secondary(), "Not a secondary header"); @@ -111,16 +115,17 @@ fn main() { ) .unwrap(); + println!("Built genesis:\n{:?}", gen); println!("Final genesis hash: {}", gen.hash().to_hex()); - // TODO check again the bitcoin block to make sure it's not been orphaned - update_genesis_rs(&gen); - println!("genesis.rs has been updated, check it and press c+enter to proceed."); + println!("genesis.rs has been updated, check it and run mainnet_genesis_hash test"); + println!("also check bitcoin block {} hasn't been orphaned.", h1); + println!("press c+enter to proceed."); let mut input = String::new(); io::stdin().read_line(&mut input).unwrap(); if input != "c" { - return + return; } // Commit genesis block info in git and tag @@ -140,8 +145,6 @@ fn main() { } fn update_genesis_rs(gen: &core::core::Block) { - // TODO coinbase output and kernel - // set the replacement patterns let mut replacements = vec![]; replacements.push(( @@ -156,20 +159,68 @@ fn update_genesis_rs(gen: &core::core::Block) { gen.header.timestamp.time().second(), ), )); + replacements.push(( + "prev_root".to_string(), + format!("Hash::from_hex(\"{}\")", gen.header.prev_root.to_hex()), + )); replacements.push(( "output_root".to_string(), format!("Hash::from_hex(\"{}\")", gen.header.output_root.to_hex()), )); replacements.push(( "range_proof_root".to_string(), - format!("Hash::from_hex(\"{}\")", gen.header.range_proof_root.to_hex()), + format!( + "Hash::from_hex(\"{}\")", + gen.header.range_proof_root.to_hex() + ), )); replacements.push(( "kernel_root".to_string(), format!("Hash::from_hex(\"{}\")", gen.header.kernel_root.to_hex()), )); + replacements.push(( + "total_kernel_offset".to_string(), + format!("BlindingFactor::from_hex(\"{}\")", gen.header.total_kernel_offset.to_hex()), + )); + replacements.push(( + "nonce".to_string(), + format!("{}", gen.header.pow.nonce), + )); + replacements.push(( + "nonces".to_string(), + format!("{:x?}", gen.header.pow.proof.nonces), + )); + replacements.push(( + "excess".to_string(), + format!( + "Commitment::from_vec(util::from_hex(\"{:x?}\"))", + util::to_hex(gen.kernels()[0].excess.0.to_vec()) + ), + )); + replacements.push(( + "excess_sig".to_string(), + format!( + "Signature::from_raw_data(&util::from_hex(\"{:x?}\"))", + util::to_hex(gen.kernels()[0].excess_sig.to_raw_data().to_vec()) + ), + )); + replacements.push(( + "commit".to_string(), + format!( + "Commitment::from_vec(util::from_hex(\"{:x?}\"))", + util::to_hex(gen.outputs()[0].commitment().0.to_vec()) + ), + )); + replacements.push(( + "proof".to_string(), + format!( + "RangeProof::from_vec(util::from_hex(\"{:x?}\"))", + util::to_hex(gen.outputs()[0].proof.bytes().to_vec()) + ), + )); - // check each possible replacement in the file + // check each possible replacement in the file, remove the replacement from + // the list when found to avoid double replacements let mut replaced = String::new(); { let genesis_rs = fs::File::open(GENESIS_RS_PATH).unwrap(); From 80726c7f8fb5774df7e85c47f019ab71a72fae2b Mon Sep 17 00:00:00 2001 From: Ignotus Peverell Date: Fri, 14 Dec 2018 02:56:45 +0000 Subject: [PATCH 08/14] Fixed various replacements to obtain a compilable, well-formed genesis --- core/src/core/block.rs | 4 +-- core/src/genesis.rs | 11 +++++++- etc/gen_gen/src/bin/gen_gen.rs | 50 ++++++++++++++++------------------ 3 files changed, 36 insertions(+), 29 deletions(-) diff --git a/core/src/core/block.rs b/core/src/core/block.rs index 220d88bc2..cf1e82adc 100644 --- a/core/src/core/block.rs +++ b/core/src/core/block.rs @@ -470,8 +470,8 @@ impl Block { /// Consumes this block and returns a new block with the coinbase output /// and kernels added pub fn with_reward(mut self, reward_out: Output, reward_kern: TxKernel) -> Block { - self.body.outputs.push(reward_out); - self.body.kernels.push(reward_kern); + self.body.outputs = vec![reward_out]; + self.body.kernels = vec![reward_kern]; self } diff --git a/core/src/genesis.rs b/core/src/genesis.rs index 1e90df646..27f167949 100644 --- a/core/src/genesis.rs +++ b/core/src/genesis.rs @@ -14,12 +14,17 @@ //! Definition of the genesis block. Placeholder for now. +// required for genesis replacement +//! #![allow(unused_imports)] + use chrono::prelude::{TimeZone, Utc}; use crate::core; use crate::global; use crate::pow::{Difficulty, Proof, ProofOfWork}; +use crate::util; use crate::util::secp::Signature; +use crate::util::secp::constants::SINGLE_BULLET_PROOF_SIZE; use crate::util::secp::pedersen::{Commitment, RangeProof}; use crate::core::hash::Hash; @@ -135,6 +140,7 @@ pub fn genesis_testnet4() -> core::Block { ..Default::default() }) } + /// Placeholder for mainnet genesis block, will definitely change before /// release so no use trying to pre-mine it. pub fn genesis_main() -> core::Block { @@ -169,7 +175,10 @@ pub fn genesis_main() -> core::Block { let output = core::Output { features: core::OutputFeatures::COINBASE_OUTPUT, commit: Commitment::from_vec(vec![]), // REPLACE - proof: RangeProof::zero(), // REPLACE + proof: RangeProof { + plen: SINGLE_BULLET_PROOF_SIZE, + proof: [0; SINGLE_BULLET_PROOF_SIZE], // REPLACE + } }; gen.with_reward(output, kernel) } diff --git a/etc/gen_gen/src/bin/gen_gen.rs b/etc/gen_gen/src/bin/gen_gen.rs index 7e4dea486..3cea1a397 100644 --- a/etc/gen_gen/src/bin/gen_gen.rs +++ b/etc/gen_gen/src/bin/gen_gen.rs @@ -41,7 +41,6 @@ static GENESIS_RS_PATH: &str = "../../core/src/genesis.rs"; static PLUGIN_PATH: &str = "cuckaroo_mean_cuda_29.cuckooplugin"; fn main() { - core::global::set_mining_mode(core::global::ChainTypes::Mainnet); if !path::Path::new(GENESIS_RS_PATH).exists() { panic!( "File {} not found, make sure you're running this from the gen_gen directory", @@ -80,11 +79,13 @@ fn main() { { // setup a tmp chain to set block header roots + core::global::set_mining_mode(core::global::ChainTypes::AutomatedTesting); let tmp_chain = setup_chain(".grin.tmp", core::pow::mine_genesis_block().unwrap()); tmp_chain.set_txhashset_roots(&mut gen).unwrap(); } // mine a Cuckaroo29 block + core::global::set_mining_mode(core::global::ChainTypes::Mainnet); let plugin_lib = cuckoo::PluginLibrary::new(PLUGIN_PATH).unwrap(); let solver_ctx = plugin_lib.create_solver_ctx(&mut plugin_lib.get_default_params()); @@ -104,18 +105,18 @@ fn main() { nonce += 1; } - // // set the PoW solution and make sure the block is mostly valid + // set the PoW solution and make sure the block is mostly valid gen.header.pow.nonce = solver_sols.sols[0].nonce as u64; gen.header.pow.proof.nonces = solver_sols.sols[0].to_u64s(); assert!(gen.header.pow.is_secondary(), "Not a secondary header"); - core::pow::verify_size(&gen.header).unwrap(); + println!("Built genesis:\n{:?}", gen); + // core::pow::verify_size(&gen.header).unwrap(); gen.validate( &BlindingFactor::zero(), Arc::new(util::RwLock::new(LruVerifierCache::new())), ) .unwrap(); - println!("Built genesis:\n{:?}", gen); println!("Final genesis hash: {}", gen.hash().to_hex()); update_genesis_rs(&gen); @@ -124,7 +125,7 @@ fn main() { println!("press c+enter to proceed."); let mut input = String::new(); io::stdin().read_line(&mut input).unwrap(); - if input != "c" { + if input != "c\n" { return; } @@ -161,62 +162,59 @@ fn update_genesis_rs(gen: &core::core::Block) { )); replacements.push(( "prev_root".to_string(), - format!("Hash::from_hex(\"{}\")", gen.header.prev_root.to_hex()), + format!("Hash::from_hex(\"{}\").unwrap()", gen.header.prev_root.to_hex()), )); replacements.push(( "output_root".to_string(), - format!("Hash::from_hex(\"{}\")", gen.header.output_root.to_hex()), + format!("Hash::from_hex(\"{}\").unwrap()", gen.header.output_root.to_hex()), )); replacements.push(( "range_proof_root".to_string(), format!( - "Hash::from_hex(\"{}\")", + "Hash::from_hex(\"{}\").unwrap()", gen.header.range_proof_root.to_hex() ), )); replacements.push(( "kernel_root".to_string(), - format!("Hash::from_hex(\"{}\")", gen.header.kernel_root.to_hex()), + format!("Hash::from_hex(\"{}\").unwrap()", gen.header.kernel_root.to_hex()), )); replacements.push(( "total_kernel_offset".to_string(), - format!("BlindingFactor::from_hex(\"{}\")", gen.header.total_kernel_offset.to_hex()), - )); - replacements.push(( - "nonce".to_string(), - format!("{}", gen.header.pow.nonce), + format!( + "BlindingFactor::from_hex(\"{}\").unwrap()", + gen.header.total_kernel_offset.to_hex() + ), )); + replacements.push(("nonce".to_string(), format!("{}", gen.header.pow.nonce))); replacements.push(( "nonces".to_string(), - format!("{:x?}", gen.header.pow.proof.nonces), + format!("vec!{:x?}", gen.header.pow.proof.nonces), )); replacements.push(( "excess".to_string(), format!( - "Commitment::from_vec(util::from_hex(\"{:x?}\"))", + "Commitment::from_vec(util::from_hex({:x?}.to_string()).unwrap())", util::to_hex(gen.kernels()[0].excess.0.to_vec()) ), )); replacements.push(( "excess_sig".to_string(), format!( - "Signature::from_raw_data(&util::from_hex(\"{:x?}\"))", - util::to_hex(gen.kernels()[0].excess_sig.to_raw_data().to_vec()) + "Signature::from_raw_data(&{:?}).unwrap()", + gen.kernels()[0].excess_sig.to_raw_data().to_vec(), ), )); replacements.push(( "commit".to_string(), format!( - "Commitment::from_vec(util::from_hex(\"{:x?}\"))", + "Commitment::from_vec(util::from_hex({:x?}.to_string()).unwrap())", util::to_hex(gen.outputs()[0].commitment().0.to_vec()) ), )); replacements.push(( "proof".to_string(), - format!( - "RangeProof::from_vec(util::from_hex(\"{:x?}\"))", - util::to_hex(gen.outputs()[0].proof.bytes().to_vec()) - ), + format!("{:?}", gen.outputs()[0].proof.bytes().to_vec()), )); // check each possible replacement in the file, remove the replacement from @@ -237,9 +235,9 @@ fn update_genesis_rs(gen: &core::core::Block) { break; } } - if !has_replaced { - replaced.push_str(&format!("{}\n", line)); - } + } + if !has_replaced { + replaced.push_str(&format!("{}\n", line)); } } } From 23cf377d3df5926e1e3b3475864d8c0dc20a11e4 Mon Sep 17 00:00:00 2001 From: Ignotus Peverell Date: Fri, 14 Dec 2018 04:51:35 +0000 Subject: [PATCH 09/14] Check plugin errors, uncomment PoW validation --- etc/gen_gen/src/bin/gen_gen.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/etc/gen_gen/src/bin/gen_gen.rs b/etc/gen_gen/src/bin/gen_gen.rs index 3cea1a397..a6a09eb9e 100644 --- a/etc/gen_gen/src/bin/gen_gen.rs +++ b/etc/gen_gen/src/bin/gen_gen.rs @@ -102,6 +102,16 @@ fn main() { &mut solver_sols, &mut solver_stats, ); + if solver_stats.has_errored { + println!( + "Plugin {} has errored, device: {}. Reason: {}", + solver_stats.get_plugin_name(), + solver_stats.get_device_name(), + solver_stats.get_error_reason(), + ); + return; + } + nonce += 1; } @@ -110,7 +120,7 @@ fn main() { gen.header.pow.proof.nonces = solver_sols.sols[0].to_u64s(); assert!(gen.header.pow.is_secondary(), "Not a secondary header"); println!("Built genesis:\n{:?}", gen); - // core::pow::verify_size(&gen.header).unwrap(); + core::pow::verify_size(&gen.header).unwrap(); gen.validate( &BlindingFactor::zero(), Arc::new(util::RwLock::new(LruVerifierCache::new())), @@ -189,7 +199,7 @@ fn update_genesis_rs(gen: &core::core::Block) { replacements.push(("nonce".to_string(), format!("{}", gen.header.pow.nonce))); replacements.push(( "nonces".to_string(), - format!("vec!{:x?}", gen.header.pow.proof.nonces), + format!("vec!{:?}", gen.header.pow.proof.nonces), )); replacements.push(( "excess".to_string(), From 40e94f53b651030c9843dbbec46ae964fbccdb27 Mon Sep 17 00:00:00 2001 From: Ignotus Peverell Date: Fri, 14 Dec 2018 04:51:52 +0000 Subject: [PATCH 10/14] rustfmt --- etc/gen_gen/src/bin/gen_gen.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/etc/gen_gen/src/bin/gen_gen.rs b/etc/gen_gen/src/bin/gen_gen.rs index a6a09eb9e..9f7fb982e 100644 --- a/etc/gen_gen/src/bin/gen_gen.rs +++ b/etc/gen_gen/src/bin/gen_gen.rs @@ -108,7 +108,7 @@ fn main() { solver_stats.get_plugin_name(), solver_stats.get_device_name(), solver_stats.get_error_reason(), - ); + ); return; } @@ -172,11 +172,17 @@ fn update_genesis_rs(gen: &core::core::Block) { )); replacements.push(( "prev_root".to_string(), - format!("Hash::from_hex(\"{}\").unwrap()", gen.header.prev_root.to_hex()), + format!( + "Hash::from_hex(\"{}\").unwrap()", + gen.header.prev_root.to_hex() + ), )); replacements.push(( "output_root".to_string(), - format!("Hash::from_hex(\"{}\").unwrap()", gen.header.output_root.to_hex()), + format!( + "Hash::from_hex(\"{}\").unwrap()", + gen.header.output_root.to_hex() + ), )); replacements.push(( "range_proof_root".to_string(), @@ -187,7 +193,10 @@ fn update_genesis_rs(gen: &core::core::Block) { )); replacements.push(( "kernel_root".to_string(), - format!("Hash::from_hex(\"{}\").unwrap()", gen.header.kernel_root.to_hex()), + format!( + "Hash::from_hex(\"{}\").unwrap()", + gen.header.kernel_root.to_hex() + ), )); replacements.push(( "total_kernel_offset".to_string(), From 194235a5a78ddf4777544ec5f3e53d2c9f6cee27 Mon Sep 17 00:00:00 2001 From: Ignotus Peverell Date: Fri, 14 Dec 2018 21:48:08 +0000 Subject: [PATCH 11/14] Fixes to nonce handling in genesis mining --- etc/gen_gen/src/bin/gen_gen.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/etc/gen_gen/src/bin/gen_gen.rs b/etc/gen_gen/src/bin/gen_gen.rs index 9f7fb982e..c7fe4f3c9 100644 --- a/etc/gen_gen/src/bin/gen_gen.rs +++ b/etc/gen_gen/src/bin/gen_gen.rs @@ -38,7 +38,7 @@ static BCYPHER_URL: &str = "https://api.blockcypher.com/v1/btc/main"; static BCHAIR_URL: &str = "https://api.blockchair.com/bitcoin/blocks?limit=2"; static GENESIS_RS_PATH: &str = "../../core/src/genesis.rs"; -static PLUGIN_PATH: &str = "cuckaroo_mean_cuda_29.cuckooplugin"; +static PLUGIN_PATH: &str = "./cuckaroo_mean_cuda_29.cuckooplugin"; fn main() { if !path::Path::new(GENESIS_RS_PATH).exists() { @@ -87,14 +87,17 @@ fn main() { // mine a Cuckaroo29 block core::global::set_mining_mode(core::global::ChainTypes::Mainnet); let plugin_lib = cuckoo::PluginLibrary::new(PLUGIN_PATH).unwrap(); - let solver_ctx = plugin_lib.create_solver_ctx(&mut plugin_lib.get_default_params()); + let mut params = plugin_lib.get_default_params(); + params.mutate_nonce = false; + let solver_ctx = plugin_lib.create_solver_ctx(&mut params); let mut solver_sols = plugin::SolverSolutions::default(); let mut solver_stats = plugin::SolverStats::default(); let mut nonce = 0; while solver_sols.num_sols == 0 { solver_sols = plugin::SolverSolutions::default(); - plugin_lib.run_solver( + gen.header.pow.nonce = nonce; + let _ = plugin_lib.run_solver( solver_ctx, gen.header.pre_pow(), nonce, @@ -115,8 +118,7 @@ fn main() { nonce += 1; } - // set the PoW solution and make sure the block is mostly valid - gen.header.pow.nonce = solver_sols.sols[0].nonce as u64; + // Set the PoW solution and make sure the block is mostly valid gen.header.pow.proof.nonces = solver_sols.sols[0].to_u64s(); assert!(gen.header.pow.is_secondary(), "Not a secondary header"); println!("Built genesis:\n{:?}", gen); From a71af7adae2af755689e34aea3353b42c9cd0584 Mon Sep 17 00:00:00 2001 From: Ignotus Peverell Date: Fri, 14 Dec 2018 22:12:54 +0000 Subject: [PATCH 12/14] Also produce full block hashes --- core/src/genesis.rs | 4 +++- etc/gen_gen/src/bin/gen_gen.rs | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/core/src/genesis.rs b/core/src/genesis.rs index 27f167949..73d2661cb 100644 --- a/core/src/genesis.rs +++ b/core/src/genesis.rs @@ -187,11 +187,13 @@ pub fn genesis_main() -> core::Block { mod test { use super::*; - // TODO update the hash once genesis is set + // TODO hardcode the hashes once genesis is set #[test] fn mainnet_genesis_hash() { let gen_hash = genesis_main().hash(); println!("mainnet genesis hash: {}", gen_hash.to_hex()); + let gen_bin = core::ser::ser_vec(&genesis_main()).unwrap(); + println!("mainnet genesis full hash: {}\n", gen_bin.hash().to_hex()); //assert_eq!(gene_hash.to_hex, ""); } } diff --git a/etc/gen_gen/src/bin/gen_gen.rs b/etc/gen_gen/src/bin/gen_gen.rs index c7fe4f3c9..037e0b3e7 100644 --- a/etc/gen_gen/src/bin/gen_gen.rs +++ b/etc/gen_gen/src/bin/gen_gen.rs @@ -30,6 +30,7 @@ use grin_miner_plugin as plugin; use grin_store as store; use grin_util as util; +use grin_core::core::hash::Hashed; use grin_core::core::verifier_cache::LruVerifierCache; use grin_keychain::{BlindingFactor, ExtKeychain, Keychain}; @@ -129,7 +130,9 @@ fn main() { ) .unwrap(); - println!("Final genesis hash: {}", gen.hash().to_hex()); + println!("\nFinal genesis cyclehash: {}", gen.hash().to_hex()); + let gen_bin = core::ser::ser_vec(&gen).unwrap(); + println!("Final genesis full hash: {}\n", gen_bin.hash().to_hex()); update_genesis_rs(&gen); println!("genesis.rs has been updated, check it and run mainnet_genesis_hash test"); From 052981d596280698bd363f784246e29e7250527c Mon Sep 17 00:00:00 2001 From: Ignotus Peverell Date: Fri, 14 Dec 2018 22:13:05 +0000 Subject: [PATCH 13/14] rustfmt --- core/src/genesis.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/genesis.rs b/core/src/genesis.rs index 73d2661cb..97048a534 100644 --- a/core/src/genesis.rs +++ b/core/src/genesis.rs @@ -23,9 +23,9 @@ use crate::core; use crate::global; use crate::pow::{Difficulty, Proof, ProofOfWork}; use crate::util; -use crate::util::secp::Signature; use crate::util::secp::constants::SINGLE_BULLET_PROOF_SIZE; use crate::util::secp::pedersen::{Commitment, RangeProof}; +use crate::util::secp::Signature; use crate::core::hash::Hash; use crate::keychain::BlindingFactor; @@ -178,7 +178,7 @@ pub fn genesis_main() -> core::Block { proof: RangeProof { plen: SINGLE_BULLET_PROOF_SIZE, proof: [0; SINGLE_BULLET_PROOF_SIZE], // REPLACE - } + }, }; gen.with_reward(output, kernel) } From cb0d09c4926cd05747d40273e4294a377c78c32a Mon Sep 17 00:00:00 2001 From: Ignotus Peverell Date: Fri, 14 Dec 2018 22:35:59 +0000 Subject: [PATCH 14/14] Fix genesis hash test --- core/src/genesis.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/genesis.rs b/core/src/genesis.rs index 97048a534..87e196e2f 100644 --- a/core/src/genesis.rs +++ b/core/src/genesis.rs @@ -186,13 +186,15 @@ pub fn genesis_main() -> core::Block { #[cfg(test)] mod test { use super::*; + use crate::ser; + use crate::core::hash::Hashed; // TODO hardcode the hashes once genesis is set #[test] fn mainnet_genesis_hash() { let gen_hash = genesis_main().hash(); println!("mainnet genesis hash: {}", gen_hash.to_hex()); - let gen_bin = core::ser::ser_vec(&genesis_main()).unwrap(); + let gen_bin = ser::ser_vec(&genesis_main()).unwrap(); println!("mainnet genesis full hash: {}\n", gen_bin.hash().to_hex()); //assert_eq!(gene_hash.to_hex, ""); }