Complete genesis replacement

This commit is contained in:
Ignotus Peverell 2018-12-14 00:46:41 +00:00
parent 18416e8528
commit 2386ce3b8a
No known key found for this signature in database
GPG key ID: 99CD25F39F8F8211
4 changed files with 95 additions and 24 deletions

View file

@ -19,6 +19,8 @@ use chrono::prelude::{TimeZone, Utc};
use crate::core; use crate::core;
use crate::global; use crate::global;
use crate::pow::{Difficulty, Proof, ProofOfWork}; 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::core::hash::Hash;
use crate::keychain::BlindingFactor; use crate::keychain::BlindingFactor;
@ -136,14 +138,14 @@ pub fn genesis_testnet4() -> core::Block {
/// Placeholder for mainnet genesis block, will definitely change before /// Placeholder for mainnet genesis block, will definitely change before
/// release so no use trying to pre-mine it. /// release so no use trying to pre-mine it.
pub fn genesis_main() -> core::Block { pub fn genesis_main() -> core::Block {
core::Block::with_header(core::BlockHeader { let gen = core::Block::with_header(core::BlockHeader {
height: 0, height: 0,
timestamp: Utc.ymd(2019, 1, 15).and_hms(12, 0, 0), // REPLACE timestamp: Utc.ymd(2019, 1, 15).and_hms(12, 0, 0), // REPLACE
prev_root: Hash::default(), // REPLACE prev_root: Hash::default(), // REPLACE
output_root: Hash::default(), // REPLACE output_root: Hash::default(), // REPLACE
range_proof_root: Hash::default(), // REPLACE range_proof_root: Hash::default(), // REPLACE
kernel_root: Hash::default(), // REPLACE kernel_root: Hash::default(), // REPLACE
total_kernel_offset: BlindingFactor::zero(), // REPLACE total_kernel_offset: BlindingFactor::zero(), // REPLACE
output_mmr_size: 1, output_mmr_size: 1,
kernel_mmr_size: 1, kernel_mmr_size: 1,
pow: ProofOfWork { pow: ProofOfWork {
@ -156,10 +158,22 @@ pub fn genesis_main() -> core::Block {
}, },
}, },
..Default::default() ..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)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;

View file

@ -311,6 +311,8 @@ pub fn get_genesis_nonce() -> u64 {
ChainTypes::AutomatedTesting => 0, ChainTypes::AutomatedTesting => 0,
// Magic nonce for current genesis block at cuckatoo15 // Magic nonce for current genesis block at cuckatoo15
ChainTypes::UserTesting => 27944, ChainTypes::UserTesting => 27944,
// Placeholder, obviously not the right value
ChainTypes::Mainnet => 0,
// Magic nonce for genesis block for testnet2 (cuckatoo29) // Magic nonce for genesis block for testnet2 (cuckatoo29)
_ => panic!("Pre-set"), _ => panic!("Pre-set"),
} }

View file

@ -24,3 +24,7 @@ grin_miner_plugin = "0.4.2"
grin_store = "0.4.2" grin_store = "0.4.2"
grin_util = "0.4.2" grin_util = "0.4.2"
serde_json = "1" serde_json = "1"
[patch.crates-io]
grin_core = { path = "../../core" }
grin_keychain = { path = "../../keychain" }

View file

@ -14,12 +14,12 @@
//! Main for building the genesis generation utility. //! Main for building the genesis generation utility.
use std::{fs, io, path, process};
use std::io::{BufRead, Write}; use std::io::{BufRead, Write};
use std::sync::Arc; use std::sync::Arc;
use std::{fs, io, path, process};
use chrono::prelude::Utc; use chrono::prelude::Utc;
use chrono::{Duration, Timelike, Datelike}; use chrono::{Datelike, Duration, Timelike};
use curl; use curl;
use serde_json; use serde_json;
@ -43,10 +43,16 @@ static PLUGIN_PATH: &str = "cuckaroo_mean_cuda_29.cuckooplugin";
fn main() { fn main() {
core::global::set_mining_mode(core::global::ChainTypes::Mainnet); core::global::set_mining_mode(core::global::ChainTypes::Mainnet);
if !path::Path::new(GENESIS_RS_PATH).exists() { 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() { 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 // get the latest bitcoin hash
@ -61,12 +67,10 @@ fn main() {
} }
println!("Using bitcoin block hash {}", h1); println!("Using bitcoin block hash {}", h1);
// build the basic parts of the genesis block header, perhaps some of this // build the basic parts of the genesis block header
// can be moved to core
let mut gen = core::genesis::genesis_main(); let mut gen = core::genesis::genesis_main();
gen.header.timestamp = Utc::now() + Duration::minutes(30); gen.header.timestamp = Utc::now() + Duration::minutes(30);
gen.header.prev_root = core::core::hash::Hash::from_hex(&h1).unwrap(); 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 // TODO get the proper keychain and/or raw coinbase
let keychain = ExtKeychain::from_random_seed().unwrap(); let keychain = ExtKeychain::from_random_seed().unwrap();
@ -100,7 +104,7 @@ fn main() {
nonce += 1; 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.nonce = solver_sols.sols[0].nonce as u64;
gen.header.pow.proof.nonces = solver_sols.sols[0].to_u64s(); gen.header.pow.proof.nonces = solver_sols.sols[0].to_u64s();
assert!(gen.header.pow.is_secondary(), "Not a secondary header"); assert!(gen.header.pow.is_secondary(), "Not a secondary header");
@ -111,16 +115,17 @@ fn main() {
) )
.unwrap(); .unwrap();
println!("Built genesis:\n{:?}", gen);
println!("Final genesis hash: {}", gen.hash().to_hex()); 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); 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(); let mut input = String::new();
io::stdin().read_line(&mut input).unwrap(); io::stdin().read_line(&mut input).unwrap();
if input != "c" { if input != "c" {
return return;
} }
// Commit genesis block info in git and tag // Commit genesis block info in git and tag
@ -140,8 +145,6 @@ fn main() {
} }
fn update_genesis_rs(gen: &core::core::Block) { fn update_genesis_rs(gen: &core::core::Block) {
// TODO coinbase output and kernel
// set the replacement patterns // set the replacement patterns
let mut replacements = vec![]; let mut replacements = vec![];
replacements.push(( replacements.push((
@ -156,20 +159,68 @@ fn update_genesis_rs(gen: &core::core::Block) {
gen.header.timestamp.time().second(), gen.header.timestamp.time().second(),
), ),
)); ));
replacements.push((
"prev_root".to_string(),
format!("Hash::from_hex(\"{}\")", gen.header.prev_root.to_hex()),
));
replacements.push(( replacements.push((
"output_root".to_string(), "output_root".to_string(),
format!("Hash::from_hex(\"{}\")", gen.header.output_root.to_hex()), format!("Hash::from_hex(\"{}\")", gen.header.output_root.to_hex()),
)); ));
replacements.push(( replacements.push((
"range_proof_root".to_string(), "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(( replacements.push((
"kernel_root".to_string(), "kernel_root".to_string(),
format!("Hash::from_hex(\"{}\")", gen.header.kernel_root.to_hex()), 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 mut replaced = String::new();
{ {
let genesis_rs = fs::File::open(GENESIS_RS_PATH).unwrap(); let genesis_rs = fs::File::open(GENESIS_RS_PATH).unwrap();