Trying to fix slight snafu

This commit is contained in:
Ignotus Peverell 2018-12-11 01:08:02 +00:00
parent 934b11d06f
commit a58235f603
No known key found for this signature in database
GPG key ID: 99CD25F39F8F8211
3 changed files with 167 additions and 0 deletions

24
etc/gen_gen/Cargo.toml Normal file
View file

@ -0,0 +1,24 @@
[package]
name = "grin_gen_gen"
version = "0.0.1"
edition = "2018"
authors = ["Grin Developers <mimblewimble@lists.launchpad.net>"]
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"

18
etc/gen_gen/README.md Normal file
View file

@ -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 <file> --difficulty <u64> --tag <version>`

View file

@ -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()
}