Merge pull request #2196 from mimblewimble/floonet
* Get last bitcon block hash, setup genesis header without PoW (for now) * More a few properties to mainnet genesis. Don't get too excited, several are placeholders. * Mine a valid Cuckaroo solution for genesis block * Use miner as library to get a solution for genesis. Replace final values in genesis.rs before committing it. * Complete genesis replacement * Fixed various replacements to obtain a compilable, well-formed genesis * Check plugin errors, uncomment PoW validation * Fixes to nonce handling in genesis mining * Also produce full block hashes * Fix genesis hash test * Switch commitments (#2157) * [Floonet] Use switch commits for all blinding factors (#2178) * move wallet mods back into dirs * use switched keys for blinding factor in all cases * re-implement flag to turn off switch commit derivation * rename tx log entry field tx_hex -> stored_tx (#2181) * [Floonet] add feature for height locked kernels (#2168) * add feature for height locked kernels * add function to compute kernel features appropriate for lock height, and use it * only sign kernel-features relevant fields; refactor Features * simplify invalid kernel logic * remove unused height arg to reward::output and run some rustfmt * replace nested if/else by match * Floonet chain type and genesis, testnets cleanup (#2182) * [Floonet] Encrypt private slate data upon storage in DB (#2189) * xor encrypt stored nonce and blind sum in transaction data * stop doc tests splatting wallet files throughout * Remove bzip2 dependency * Changed magic number and seeds for Floonet (#2188) * Genesis generator now loads a local wallet seed to build coinbase. * Floonet genesis block * Add floonet to generated grin-server.toml comments * Test with final Floonet genesis hashes * Fix get_header_for_output for genesis (#2192) * start search with min height 0 (#2195)
This commit is contained in:
+5
-33
@@ -62,32 +62,13 @@ pub const COINBASE_MATURITY: u64 = DAY_HEIGHT;
|
||||
/// function of block height (time). Starts at 90% losing a percent
|
||||
/// approximately every week. Represented as an integer between 0 and 100.
|
||||
pub fn secondary_pow_ratio(height: u64) -> u64 {
|
||||
if global::is_testnet() {
|
||||
if height < T4_CUCKAROO_HARDFORK {
|
||||
// Maintaining pre hardfork testnet4 behavior
|
||||
90u64.saturating_sub(height / WEEK_HEIGHT)
|
||||
} else {
|
||||
90u64.saturating_sub(height / (2 * YEAR_HEIGHT / 90))
|
||||
}
|
||||
} else {
|
||||
// Mainnet (or testing mainnet code).
|
||||
90u64.saturating_sub(height / (2 * YEAR_HEIGHT / 90))
|
||||
}
|
||||
90u64.saturating_sub(height / (2 * YEAR_HEIGHT / 90))
|
||||
}
|
||||
|
||||
/// The AR scale damping factor to use. Dependent on block height
|
||||
/// to account for pre HF behavior on testnet4.
|
||||
fn ar_scale_damp_factor(height: u64) -> u64 {
|
||||
if global::is_testnet() {
|
||||
if height < T4_CUCKAROO_HARDFORK {
|
||||
DIFFICULTY_DAMP_FACTOR
|
||||
} else {
|
||||
AR_SCALE_DAMP_FACTOR
|
||||
}
|
||||
} else {
|
||||
// Mainnet (or testing mainnet code).
|
||||
AR_SCALE_DAMP_FACTOR
|
||||
}
|
||||
fn ar_scale_damp_factor(_height: u64) -> u64 {
|
||||
AR_SCALE_DAMP_FACTOR
|
||||
}
|
||||
|
||||
/// Cuckoo-cycle proof size (cycle length)
|
||||
@@ -99,10 +80,6 @@ pub const DEFAULT_MIN_EDGE_BITS: u8 = 31;
|
||||
/// Cuckaroo proof-of-work edge_bits, meant to be ASIC resistant.
|
||||
pub const SECOND_POW_EDGE_BITS: u8 = 29;
|
||||
|
||||
/// Block height at which testnet 4 hard forks to use Cuckaroo instead of
|
||||
/// Cuckatoo for ASIC-resistant PoW
|
||||
pub const T4_CUCKAROO_HARDFORK: u64 = 64_000;
|
||||
|
||||
/// Original reference edge_bits to compute difficulty factors for higher
|
||||
/// Cuckoo graph sizes, changing this would hard fork
|
||||
pub const BASE_EDGE_BITS: u8 = 24;
|
||||
@@ -332,15 +309,10 @@ where
|
||||
/// Count the number of "secondary" (AR) blocks in the provided window of blocks.
|
||||
/// Note: we skip the first one, but testnet4 was incorrectly including it before
|
||||
/// the hardfork.
|
||||
fn ar_count(height: u64, diff_data: &[HeaderInfo]) -> u64 {
|
||||
let mut to_skip = 1;
|
||||
if global::is_testnet() && height < T4_CUCKAROO_HARDFORK {
|
||||
// Maintain behavior of testnet4 pre-HF.
|
||||
to_skip = 0;
|
||||
}
|
||||
fn ar_count(_height: u64, diff_data: &[HeaderInfo]) -> u64 {
|
||||
100 * diff_data
|
||||
.iter()
|
||||
.skip(to_skip)
|
||||
.skip(1)
|
||||
.filter(|n| n.is_secondary)
|
||||
.count() as u64
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ use crate::core::compact_block::{CompactBlock, CompactBlockBody};
|
||||
use crate::core::hash::{Hash, Hashed, ZERO_HASH};
|
||||
use crate::core::verifier_cache::VerifierCache;
|
||||
use crate::core::{
|
||||
transaction, Commitment, Input, KernelFeatures, Output, OutputFeatures, Transaction,
|
||||
transaction, Commitment, Input, Output, Transaction,
|
||||
TransactionBody, TxKernel,
|
||||
};
|
||||
use crate::global;
|
||||
@@ -535,8 +535,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
|
||||
}
|
||||
|
||||
@@ -663,14 +663,14 @@ impl Block {
|
||||
.body
|
||||
.outputs
|
||||
.iter()
|
||||
.filter(|out| out.features.contains(OutputFeatures::COINBASE_OUTPUT))
|
||||
.filter(|out| out.is_coinbase())
|
||||
.collect::<Vec<&Output>>();
|
||||
|
||||
let cb_kerns = self
|
||||
.body
|
||||
.kernels
|
||||
.iter()
|
||||
.filter(|kernel| kernel.features.contains(KernelFeatures::COINBASE_KERNEL))
|
||||
.filter(|kernel| kernel.is_coinbase())
|
||||
.collect::<Vec<&TxKernel>>();
|
||||
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@ use rand::{thread_rng, Rng};
|
||||
use crate::core::block::{Block, BlockHeader, Error};
|
||||
use crate::core::hash::Hashed;
|
||||
use crate::core::id::ShortIdentifiable;
|
||||
use crate::core::{KernelFeatures, Output, OutputFeatures, ShortId, TxKernel};
|
||||
use crate::core::{Output, ShortId, TxKernel};
|
||||
use crate::ser::{self, read_multi, Readable, Reader, VerifySortedAndUnique, Writeable, Writer};
|
||||
|
||||
/// Container for full (full) outputs and kernels and kern_ids for a compact block.
|
||||
@@ -168,7 +168,7 @@ impl From<Block> for CompactBlock {
|
||||
let out_full = block
|
||||
.outputs()
|
||||
.iter()
|
||||
.filter(|x| x.features.contains(OutputFeatures::COINBASE_OUTPUT))
|
||||
.filter(|x| x.is_coinbase())
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@@ -176,7 +176,7 @@ impl From<Block> for CompactBlock {
|
||||
let mut kern_ids = vec![];
|
||||
|
||||
for k in block.kernels() {
|
||||
if k.features.contains(KernelFeatures::COINBASE_KERNEL) {
|
||||
if k.is_coinbase() {
|
||||
kern_full.push(k.clone());
|
||||
} else {
|
||||
kern_ids.push(k.short_id(&header.hash(), nonce));
|
||||
|
||||
+110
-29
@@ -40,10 +40,12 @@ bitflags! {
|
||||
/// Options for a kernel's structure or use
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct KernelFeatures: u8 {
|
||||
/// No flags
|
||||
const DEFAULT_KERNEL = 0b00000000;
|
||||
/// Kernel matching a coinbase output
|
||||
const COINBASE_KERNEL = 0b00000001;
|
||||
/// plain kernel has fee, but no lock_height
|
||||
const PLAIN = 0;
|
||||
/// coinbase kernel has neither fee nor lock_height (both zero)
|
||||
const COINBASE = 1;
|
||||
/// absolute height locked kernel; has fee and lock_height
|
||||
const HEIGHT_LOCKED = 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +204,39 @@ impl PMMRable for TxKernel {
|
||||
}
|
||||
}
|
||||
|
||||
impl KernelFeatures {
|
||||
/// Is this a coinbase kernel?
|
||||
pub fn is_coinbase(&self) -> bool {
|
||||
self.contains(KernelFeatures::COINBASE)
|
||||
}
|
||||
|
||||
/// Is this a plain kernel?
|
||||
pub fn is_plain(&self) -> bool {
|
||||
!self.is_coinbase() && !self.is_height_locked()
|
||||
}
|
||||
|
||||
/// Is this a height locked kernel?
|
||||
pub fn is_height_locked(&self) -> bool {
|
||||
self.contains(KernelFeatures::HEIGHT_LOCKED)
|
||||
}
|
||||
}
|
||||
|
||||
impl TxKernel {
|
||||
/// Is this a coinbase kernel?
|
||||
pub fn is_coinbase(&self) -> bool {
|
||||
self.features.is_coinbase()
|
||||
}
|
||||
|
||||
/// Is this a plain kernel?
|
||||
pub fn is_plain(&self) -> bool {
|
||||
self.features.is_plain()
|
||||
}
|
||||
|
||||
/// Is this a height locked kernel?
|
||||
pub fn is_height_locked(&self) -> bool {
|
||||
self.features.is_height_locked()
|
||||
}
|
||||
|
||||
/// Return the excess commitment for this tx_kernel.
|
||||
pub fn excess(&self) -> Commitment {
|
||||
self.excess
|
||||
@@ -219,6 +253,10 @@ impl TxKernel {
|
||||
/// as a public key and checking the signature verifies with the fee as
|
||||
/// message.
|
||||
pub fn verify(&self) -> Result<(), Error> {
|
||||
if self.is_coinbase() && self.fee != 0 || !self.is_height_locked() && self.lock_height != 0
|
||||
{
|
||||
return Err(Error::InvalidKernelFeatures);
|
||||
}
|
||||
let secp = static_secp_instance();
|
||||
let secp = secp.lock();
|
||||
let sig = &self.excess_sig;
|
||||
@@ -242,7 +280,7 @@ impl TxKernel {
|
||||
/// Build an empty tx kernel with zero values.
|
||||
pub fn empty() -> TxKernel {
|
||||
TxKernel {
|
||||
features: KernelFeatures::DEFAULT_KERNEL,
|
||||
features: KernelFeatures::PLAIN,
|
||||
fee: 0,
|
||||
lock_height: 0,
|
||||
excess: Commitment::from_vec(vec![0; 33]),
|
||||
@@ -258,6 +296,7 @@ impl TxKernel {
|
||||
/// Builds a new tx kernel with the provided lock_height.
|
||||
pub fn with_lock_height(self, lock_height: u64) -> TxKernel {
|
||||
TxKernel {
|
||||
features: kernel_features(lock_height),
|
||||
lock_height,
|
||||
..self
|
||||
}
|
||||
@@ -586,25 +625,17 @@ impl TransactionBody {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Verify we have no outputs tagged as COINBASE_OUTPUT.
|
||||
// Verify we have no outputs tagged as COINBASE.
|
||||
fn verify_output_features(&self) -> Result<(), Error> {
|
||||
if self
|
||||
.outputs
|
||||
.iter()
|
||||
.any(|x| x.features.contains(OutputFeatures::COINBASE_OUTPUT))
|
||||
{
|
||||
if self.outputs.iter().any(|x| x.is_coinbase()) {
|
||||
return Err(Error::InvalidOutputFeatures);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Verify we have no kernels tagged as COINBASE_KERNEL.
|
||||
// Verify we have no kernels tagged as COINBASE.
|
||||
fn verify_kernel_features(&self) -> Result<(), Error> {
|
||||
if self
|
||||
.kernels
|
||||
.iter()
|
||||
.any(|x| x.features.contains(KernelFeatures::COINBASE_KERNEL))
|
||||
{
|
||||
if self.kernels.iter().any(|x| x.is_coinbase()) {
|
||||
return Err(Error::InvalidKernelFeatures);
|
||||
}
|
||||
Ok(())
|
||||
@@ -1081,6 +1112,16 @@ impl Input {
|
||||
pub fn commitment(&self) -> Commitment {
|
||||
self.commit
|
||||
}
|
||||
|
||||
/// Is this a coinbase input?
|
||||
pub fn is_coinbase(&self) -> bool {
|
||||
self.features.is_coinbase()
|
||||
}
|
||||
|
||||
/// Is this a plain input?
|
||||
pub fn is_plain(&self) -> bool {
|
||||
self.features.is_plain()
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
@@ -1088,9 +1129,9 @@ bitflags! {
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct OutputFeatures: u8 {
|
||||
/// No flags
|
||||
const DEFAULT_OUTPUT = 0b00000000;
|
||||
const PLAIN = 0;
|
||||
/// Output is a coinbase output, must not be spent until maturity
|
||||
const COINBASE_OUTPUT = 0b00000001;
|
||||
const COINBASE = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1160,12 +1201,34 @@ impl PMMRable for Output {
|
||||
}
|
||||
}
|
||||
|
||||
impl OutputFeatures {
|
||||
/// Is this a coinbase output?
|
||||
pub fn is_coinbase(&self) -> bool {
|
||||
self.contains(OutputFeatures::COINBASE)
|
||||
}
|
||||
|
||||
/// Is this a plain output?
|
||||
pub fn is_plain(&self) -> bool {
|
||||
!self.contains(OutputFeatures::COINBASE)
|
||||
}
|
||||
}
|
||||
|
||||
impl Output {
|
||||
/// Commitment for the output
|
||||
pub fn commitment(&self) -> Commitment {
|
||||
self.commit
|
||||
}
|
||||
|
||||
/// Is this a coinbase kernel?
|
||||
pub fn is_coinbase(&self) -> bool {
|
||||
self.features.is_coinbase()
|
||||
}
|
||||
|
||||
/// Is this a plain kernel?
|
||||
pub fn is_plain(&self) -> bool {
|
||||
self.features.is_plain()
|
||||
}
|
||||
|
||||
/// Range proof for the output
|
||||
pub fn proof(&self) -> RangeProof {
|
||||
self.proof
|
||||
@@ -1291,25 +1354,43 @@ impl From<Output> for OutputIdentifier {
|
||||
/// to produce a 32 byte message to sign.
|
||||
///
|
||||
/// testnet4: msg = (fee || lock_height)
|
||||
/// mainnet: msg = hash(fee || lock_height || features)
|
||||
/// mainnet: msg = hash(features) for coinbase kernels
|
||||
/// hash(features || fee) for plain kernels
|
||||
/// hash(features || fee || lock_height) for height locked kernels
|
||||
///
|
||||
pub fn kernel_sig_msg(
|
||||
fee: u64,
|
||||
lock_height: u64,
|
||||
features: KernelFeatures,
|
||||
) -> Result<secp::Message, Error> {
|
||||
if features.is_coinbase() && fee != 0 || !features.is_height_locked() && lock_height != 0 {
|
||||
return Err(Error::InvalidKernelFeatures);
|
||||
}
|
||||
let msg = if global::is_testnet() {
|
||||
let mut bytes = [0; 32];
|
||||
BigEndian::write_u64(&mut bytes[16..24], fee);
|
||||
BigEndian::write_u64(&mut bytes[24..], lock_height);
|
||||
secp::Message::from_slice(&bytes)?
|
||||
} else {
|
||||
let hash = (fee, lock_height, features).hash();
|
||||
let hash = match features {
|
||||
KernelFeatures::COINBASE => (features).hash(),
|
||||
KernelFeatures::PLAIN => (features, fee).hash(),
|
||||
_ => (features, fee, lock_height).hash(),
|
||||
};
|
||||
secp::Message::from_slice(&hash.as_bytes())?
|
||||
};
|
||||
Ok(msg)
|
||||
}
|
||||
|
||||
/// kernel features as determined by lock height
|
||||
pub fn kernel_features(lock_height: u64) -> KernelFeatures {
|
||||
if lock_height > 0 {
|
||||
KernelFeatures::HEIGHT_LOCKED
|
||||
} else {
|
||||
KernelFeatures::PLAIN
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
@@ -1328,7 +1409,7 @@ mod test {
|
||||
let sig = secp::Signature::from_raw_data(&[0; 64]).unwrap();
|
||||
|
||||
let kernel = TxKernel {
|
||||
features: KernelFeatures::DEFAULT_KERNEL,
|
||||
features: KernelFeatures::PLAIN,
|
||||
lock_height: 0,
|
||||
excess: commit,
|
||||
excess_sig: sig.clone(),
|
||||
@@ -1338,7 +1419,7 @@ mod test {
|
||||
let mut vec = vec![];
|
||||
ser::serialize(&mut vec, &kernel).expect("serialized failed");
|
||||
let kernel2: TxKernel = ser::deserialize(&mut &vec[..]).unwrap();
|
||||
assert_eq!(kernel2.features, KernelFeatures::DEFAULT_KERNEL);
|
||||
assert_eq!(kernel2.features, KernelFeatures::PLAIN);
|
||||
assert_eq!(kernel2.lock_height, 0);
|
||||
assert_eq!(kernel2.excess, commit);
|
||||
assert_eq!(kernel2.excess_sig, sig.clone());
|
||||
@@ -1346,7 +1427,7 @@ mod test {
|
||||
|
||||
// now check a kernel with lock_height serialize/deserialize correctly
|
||||
let kernel = TxKernel {
|
||||
features: KernelFeatures::DEFAULT_KERNEL,
|
||||
features: KernelFeatures::HEIGHT_LOCKED,
|
||||
lock_height: 100,
|
||||
excess: commit,
|
||||
excess_sig: sig.clone(),
|
||||
@@ -1356,7 +1437,7 @@ mod test {
|
||||
let mut vec = vec![];
|
||||
ser::serialize(&mut vec, &kernel).expect("serialized failed");
|
||||
let kernel2: TxKernel = ser::deserialize(&mut &vec[..]).unwrap();
|
||||
assert_eq!(kernel2.features, KernelFeatures::DEFAULT_KERNEL);
|
||||
assert_eq!(kernel2.features, KernelFeatures::HEIGHT_LOCKED);
|
||||
assert_eq!(kernel2.lock_height, 100);
|
||||
assert_eq!(kernel2.excess, commit);
|
||||
assert_eq!(kernel2.excess_sig, sig.clone());
|
||||
@@ -1383,7 +1464,7 @@ mod test {
|
||||
let commit = keychain.commit(5, &key_id).unwrap();
|
||||
|
||||
let input = Input {
|
||||
features: OutputFeatures::DEFAULT_OUTPUT,
|
||||
features: OutputFeatures::PLAIN,
|
||||
commit: commit,
|
||||
};
|
||||
|
||||
@@ -1394,16 +1475,16 @@ mod test {
|
||||
let nonce = 0;
|
||||
|
||||
let short_id = input.short_id(&block_hash, nonce);
|
||||
assert_eq!(short_id, ShortId::from_hex("df31d96e3cdb").unwrap());
|
||||
assert_eq!(short_id, ShortId::from_hex("c4b05f2ba649").unwrap());
|
||||
|
||||
// now generate the short_id for a *very* similar output (single feature flag
|
||||
// different) and check it generates a different short_id
|
||||
let input = Input {
|
||||
features: OutputFeatures::COINBASE_OUTPUT,
|
||||
features: OutputFeatures::COINBASE,
|
||||
commit: commit,
|
||||
};
|
||||
|
||||
let short_id = input.short_id(&block_hash, nonce);
|
||||
assert_eq!(short_id, ShortId::from_hex("784fc5afd5d9").unwrap());
|
||||
assert_eq!(short_id, ShortId::from_hex("3f0377c624e9").unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
+185
-94
@@ -14,12 +14,21 @@
|
||||
|
||||
//! Definition of the genesis block. Placeholder for now.
|
||||
|
||||
// required for genesis replacement
|
||||
//! #![allow(unused_imports)]
|
||||
|
||||
use chrono::prelude::{TimeZone, Utc};
|
||||
|
||||
use crate::consensus;
|
||||
use crate::core;
|
||||
use crate::global;
|
||||
use crate::pow::{Difficulty, Proof, ProofOfWork};
|
||||
use crate::util;
|
||||
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;
|
||||
|
||||
/// 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
|
||||
@@ -37,114 +46,196 @@ pub fn genesis_dev() -> core::Block {
|
||||
})
|
||||
}
|
||||
|
||||
/// First testnet genesis block, still subject to change (especially the date,
|
||||
/// will hopefully come before Christmas).
|
||||
pub fn genesis_testnet1() -> core::Block {
|
||||
core::Block::with_header(core::BlockHeader {
|
||||
/// Placeholder for floonet genesis block, will definitely change before
|
||||
/// release
|
||||
pub fn genesis_floo() -> core::Block {
|
||||
let gen = core::Block::with_header(core::BlockHeader {
|
||||
height: 0,
|
||||
timestamp: Utc.ymd(2017, 11, 16).and_hms(20, 0, 0),
|
||||
timestamp: Utc.ymd(2018, 12, 20).and_hms(20, 58, 32),
|
||||
prev_root: Hash::from_hex(
|
||||
"ae144568a9ec32faf57e9ca5b5f0997d33f30bd3352fd84c953e6526d847c26b",
|
||||
)
|
||||
.unwrap(),
|
||||
output_root: Hash::from_hex(
|
||||
"47d2570266451203c62cd003c706e3ec37e9cb4292316744abfa68a1b133bc1c",
|
||||
)
|
||||
.unwrap(),
|
||||
range_proof_root: Hash::from_hex(
|
||||
"53ea93e80fe37e9a0cbb9c1a1ddf467213922481a4435921aacf55ffb3f388fc",
|
||||
)
|
||||
.unwrap(),
|
||||
kernel_root: Hash::from_hex(
|
||||
"3ff7655b2846a1313dd72e1c516a2fa262638fabc8e0d4c1dddf80773bbd472d",
|
||||
)
|
||||
.unwrap(),
|
||||
total_kernel_offset: BlindingFactor::from_hex(
|
||||
"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
)
|
||||
.unwrap(),
|
||||
output_mmr_size: 1,
|
||||
kernel_mmr_size: 1,
|
||||
pow: ProofOfWork {
|
||||
total_difficulty: Difficulty::min(),
|
||||
secondary_scaling: 1,
|
||||
nonce: 28205,
|
||||
proof: Proof::new(vec![
|
||||
0x21e, 0x7a2, 0xeae, 0x144e, 0x1b1c, 0x1fbd, 0x203a, 0x214b, 0x293b, 0x2b74,
|
||||
0x2bfa, 0x2c26, 0x32bb, 0x346a, 0x34c7, 0x37c5, 0x4164, 0x42cc, 0x4cc3, 0x55af,
|
||||
0x5a70, 0x5b14, 0x5e1c, 0x5f76, 0x6061, 0x60f9, 0x61d7, 0x6318, 0x63a1, 0x63fb,
|
||||
0x649b, 0x64e5, 0x65a1, 0x6b69, 0x70f8, 0x71c7, 0x71cd, 0x7492, 0x7b11, 0x7db8,
|
||||
0x7f29, 0x7ff8,
|
||||
]),
|
||||
},
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
/// Second testnet genesis block (cuckoo30).
|
||||
pub fn genesis_testnet2() -> core::Block {
|
||||
core::Block::with_header(core::BlockHeader {
|
||||
height: 0,
|
||||
// previous: core::hash::Hash([0xff; 32]),
|
||||
timestamp: Utc.ymd(2018, 3, 26).and_hms(16, 0, 0),
|
||||
pow: ProofOfWork {
|
||||
total_difficulty: Difficulty::from_num(global::initial_block_difficulty()),
|
||||
secondary_scaling: 1,
|
||||
nonce: 1060,
|
||||
proof: Proof::new(vec![
|
||||
0x1940730, 0x333b9d0, 0x4739d6f, 0x4c6cfb1, 0x6e3d6c3, 0x74408a3, 0x7ba2bd2,
|
||||
0x83e2024, 0x8ca22b5, 0x9d39ab8, 0xb6646dd, 0xc6698b6, 0xc6f78fe, 0xc99b662,
|
||||
0xcf2ae8c, 0xcf41eed, 0xdd073e6, 0xded6af8, 0xf08d1a5, 0x1156a144, 0x11d1160a,
|
||||
0x131bb0a5, 0x137ad703, 0x13b0831f, 0x1421683f, 0x147e3c1f, 0x1496fda0, 0x150ba22b,
|
||||
0x15cc5bc6, 0x16edf697, 0x17ced40c, 0x17d84f9e, 0x18a515c1, 0x19320d9c, 0x19da4f6d,
|
||||
0x1b50bcb1, 0x1b8bc72f, 0x1c7b6964, 0x1d07b3a9, 0x1d189d4d, 0x1d1f9a15, 0x1dafcd41,
|
||||
]),
|
||||
},
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
/// Second testnet genesis block (cuckoo30). Temporary values for now.
|
||||
pub fn genesis_testnet3() -> core::Block {
|
||||
core::Block::with_header(core::BlockHeader {
|
||||
height: 0,
|
||||
// previous: core::hash::Hash([0xff; 32]),
|
||||
timestamp: Utc.ymd(2018, 7, 8).and_hms(18, 0, 0),
|
||||
pow: ProofOfWork {
|
||||
total_difficulty: Difficulty::from_num(global::initial_block_difficulty()),
|
||||
secondary_scaling: 1,
|
||||
nonce: 4956988373127691,
|
||||
proof: Proof::new(vec![
|
||||
0xa420dc, 0xc8ffee, 0x10e433e, 0x1de9428, 0x2ed4cea, 0x52d907b, 0x5af0e3f,
|
||||
0x6b8fcae, 0x8319b53, 0x845ca8c, 0x8d2a13e, 0x8d6e4cc, 0x9349e8d, 0xa7a33c5,
|
||||
0xaeac3cb, 0xb193e23, 0xb502e19, 0xb5d9804, 0xc9ac184, 0xd4f4de3, 0xd7a23b8,
|
||||
0xf1d8660, 0xf443756, 0x10b833d2, 0x11418fc5, 0x11b8aeaf, 0x131836ec, 0x132ab818,
|
||||
0x13a46a55, 0x13df89fe, 0x145d65b5, 0x166f9c3a, 0x166fe0ef, 0x178cb36f, 0x185baf68,
|
||||
0x1bbfe563, 0x1bd637b4, 0x1cfc8382, 0x1d1ed012, 0x1e391ca5, 0x1e999b4c, 0x1f7c6d21,
|
||||
]),
|
||||
},
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
/// 4th testnet genesis block (cuckatoo29 AR, 30+ AF). Temporary values for now (Pow won't verify)
|
||||
/// NB: Currently set to intenal pre-testnet values
|
||||
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()),
|
||||
secondary_scaling: global::initial_graph_weight(),
|
||||
nonce: 8612241555342799290,
|
||||
total_difficulty: Difficulty::from_num(10_u64.pow(6)),
|
||||
secondary_scaling: 1856,
|
||||
nonce: 22,
|
||||
proof: Proof {
|
||||
nonces: vec![
|
||||
0x46f3b4, 0x1135f8c, 0x1a1596f, 0x1e10f71, 0x41c03ea, 0x63fe8e7, 0x65af34f,
|
||||
0x73c16d3, 0x8216dc3, 0x9bc75d0, 0xae7d9ad, 0xc1cb12b, 0xc65e957, 0xf67a152,
|
||||
0xfac6559, 0x100c3d71, 0x11eea08b, 0x1225dfbb, 0x124d61a1, 0x132a14b4,
|
||||
0x13f4ec38, 0x1542d236, 0x155f2df0, 0x1577394e, 0x163c3513, 0x19349845,
|
||||
0x19d46953, 0x19f65ed4, 0x1a0411b9, 0x1a2fa039, 0x1a72a06c, 0x1b02ddd2,
|
||||
0x1b594d59, 0x1b7bffd3, 0x1befe12e, 0x1c82e4cd, 0x1d492478, 0x1de132a5,
|
||||
0x1e578b3c, 0x1ed96855, 0x1f222896, 0x1fea0da6,
|
||||
48398361, 50434294, 73758991, 93493375, 94716564, 101961133, 153506566,
|
||||
159476458, 164019912, 208165915, 216747111, 218441011, 221663358, 262514197,
|
||||
264746362, 278423427, 282069592, 284508695, 297003554, 327321117, 327780367,
|
||||
329474453, 333639856, 356316379, 366419120, 381872178, 386038638, 389726932,
|
||||
390055244, 392425788, 399530286, 426997994, 436531599, 456084550, 456375883,
|
||||
459156409, 474067792, 480904139, 487380747, 489307817, 496780560, 530227836,
|
||||
],
|
||||
edge_bits: 29,
|
||||
},
|
||||
},
|
||||
..Default::default()
|
||||
})
|
||||
});
|
||||
let kernel = core::TxKernel {
|
||||
features: core::KernelFeatures::COINBASE,
|
||||
fee: 0,
|
||||
lock_height: 0,
|
||||
excess: Commitment::from_vec(
|
||||
util::from_hex(
|
||||
"0817a9e97a070ba5f9fa185c093b4b13b262ed4b4712b6f7c92881b27168f9a2cb".to_string(),
|
||||
)
|
||||
.unwrap(),
|
||||
),
|
||||
excess_sig: Signature::from_raw_data(&[
|
||||
172, 131, 105, 224, 31, 11, 0, 70, 109, 54, 230, 184, 177, 138, 46, 137, 202, 215, 152,
|
||||
37, 192, 132, 88, 254, 110, 76, 57, 32, 42, 13, 19, 89, 82, 89, 116, 66, 30, 132, 120,
|
||||
148, 122, 100, 97, 38, 141, 219, 57, 184, 171, 130, 213, 235, 83, 202, 69, 13, 213, 60,
|
||||
150, 172, 33, 37, 209, 57,
|
||||
])
|
||||
.unwrap(),
|
||||
};
|
||||
let output = core::Output {
|
||||
features: core::OutputFeatures::COINBASE,
|
||||
commit: Commitment::from_vec(
|
||||
util::from_hex(
|
||||
"08f5523cbd8b2e1dae3eefdd9dd1069e0c8a7f055a0611da79f42530c5de0d044b".to_string(),
|
||||
)
|
||||
.unwrap(),
|
||||
),
|
||||
proof: RangeProof {
|
||||
plen: SINGLE_BULLET_PROOF_SIZE,
|
||||
proof: [
|
||||
47, 196, 194, 238, 233, 164, 218, 64, 54, 92, 83, 248, 225, 116, 189, 225, 202, 66,
|
||||
213, 63, 195, 209, 238, 189, 153, 198, 231, 219, 3, 146, 102, 67, 26, 7, 199, 150,
|
||||
160, 244, 48, 166, 113, 6, 241, 49, 133, 248, 201, 80, 34, 19, 118, 249, 44, 213,
|
||||
215, 235, 228, 187, 215, 116, 212, 203, 232, 183, 12, 66, 29, 11, 28, 17, 212, 104,
|
||||
126, 203, 103, 60, 176, 149, 182, 206, 70, 138, 180, 213, 76, 99, 25, 184, 40, 177,
|
||||
197, 179, 71, 63, 19, 72, 253, 129, 115, 107, 90, 249, 39, 108, 134, 10, 231, 172,
|
||||
172, 59, 207, 118, 175, 124, 197, 132, 73, 154, 148, 8, 73, 26, 231, 75, 24, 134,
|
||||
199, 93, 15, 43, 45, 49, 69, 167, 194, 23, 114, 16, 117, 209, 127, 123, 18, 209,
|
||||
12, 34, 219, 196, 37, 7, 226, 132, 70, 111, 113, 164, 203, 175, 105, 175, 196, 62,
|
||||
225, 138, 162, 176, 190, 109, 96, 210, 15, 38, 245, 200, 83, 155, 185, 111, 85,
|
||||
234, 6, 3, 246, 98, 175, 127, 94, 65, 29, 78, 27, 53, 32, 230, 85, 91, 195, 112,
|
||||
84, 135, 56, 207, 213, 165, 40, 248, 238, 202, 225, 142, 79, 89, 81, 197, 138, 65,
|
||||
14, 232, 145, 44, 73, 6, 43, 8, 43, 42, 127, 151, 68, 18, 19, 83, 14, 142, 180, 75,
|
||||
25, 4, 97, 166, 237, 212, 187, 106, 154, 36, 223, 231, 177, 58, 70, 1, 195, 113,
|
||||
144, 151, 45, 185, 0, 174, 116, 212, 122, 239, 96, 1, 122, 211, 41, 96, 230, 110,
|
||||
242, 145, 176, 230, 55, 143, 142, 234, 151, 49, 151, 109, 252, 120, 147, 244, 178,
|
||||
73, 196, 221, 150, 85, 69, 113, 50, 166, 92, 91, 98, 188, 77, 76, 48, 192, 112,
|
||||
184, 108, 143, 134, 56, 46, 119, 21, 71, 247, 119, 133, 225, 72, 15, 158, 60, 64,
|
||||
71, 57, 134, 243, 228, 58, 13, 58, 209, 71, 4, 72, 87, 129, 51, 46, 64, 188, 60,
|
||||
157, 56, 120, 23, 2, 47, 143, 79, 176, 54, 3, 47, 227, 124, 70, 242, 8, 59, 113,
|
||||
203, 51, 65, 138, 131, 121, 45, 131, 132, 171, 161, 49, 235, 129, 39, 164, 234, 69,
|
||||
172, 95, 28, 180, 118, 163, 151, 148, 66, 65, 104, 222, 232, 154, 22, 30, 149, 196,
|
||||
214, 163, 93, 76, 128, 142, 233, 106, 171, 213, 148, 59, 101, 56, 22, 127, 232, 4,
|
||||
63, 111, 9, 188, 163, 40, 158, 24, 65, 81, 203, 231, 93, 197, 102, 170, 70, 239,
|
||||
229, 13, 172, 110, 157, 226, 112, 182, 28, 150, 222, 62, 224, 94, 182, 220, 243,
|
||||
236, 62, 156, 129, 220, 127, 155, 141, 0, 243, 159, 113, 28, 158, 95, 205, 35, 72,
|
||||
132, 46, 235, 176, 146, 233, 93, 111, 4, 105, 236, 176, 165, 102, 168, 188, 121,
|
||||
105, 175, 197, 114, 97, 40, 2, 165, 153, 85, 135, 114, 147, 95, 216, 50, 108, 52,
|
||||
225, 186, 215, 110, 122, 230, 14, 246, 141, 180, 41, 22, 132, 58, 8, 31, 187, 221,
|
||||
231, 14, 33, 52, 88, 219, 200, 77, 246, 134, 18, 0, 113, 144, 6, 146, 54, 24, 113,
|
||||
14, 64, 182, 116, 229, 250, 201, 126, 84, 192, 80, 13, 57, 232, 55, 113, 139, 249,
|
||||
166, 231, 123, 101, 236, 147, 144, 2, 9, 51, 2, 189, 188, 200, 66, 29, 16, 22, 150,
|
||||
45, 220, 15, 161, 180, 214, 244, 104, 41, 77, 171, 246, 243, 56, 47, 63, 103, 216,
|
||||
151, 199, 249, 169, 165, 119, 200, 243, 161, 83, 46, 225, 195, 92, 96, 150, 0, 165,
|
||||
170, 14, 211, 226, 244, 70, 218, 137, 254, 197, 175, 208, 119, 199, 121, 4, 7, 190,
|
||||
118, 55, 197, 208, 41, 109, 161, 34, 33, 210, 58, 99, 81, 97, 57, 156, 57, 144, 83,
|
||||
97, 49, 248, 89, 201, 88, 169, 9, 211, 34, 136, 174, 195, 224, 51, 103, 12, 237,
|
||||
172, 46, 216, 5, 168,
|
||||
],
|
||||
},
|
||||
};
|
||||
gen.with_reward(output, kernel)
|
||||
}
|
||||
|
||||
/// 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,
|
||||
// previous: core::hash::Hash([0xff; 32]),
|
||||
timestamp: Utc.ymd(2018, 8, 14).and_hms(0, 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(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, // REPLACE
|
||||
proof: Proof {
|
||||
nonces: vec![0; 42], // REPLACE
|
||||
edge_bits: 29,
|
||||
},
|
||||
},
|
||||
..Default::default()
|
||||
})
|
||||
});
|
||||
let kernel = core::TxKernel {
|
||||
features: core::KernelFeatures::COINBASE,
|
||||
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,
|
||||
commit: Commitment::from_vec(vec![]), // REPLACE
|
||||
proof: RangeProof {
|
||||
plen: SINGLE_BULLET_PROOF_SIZE,
|
||||
proof: [0; SINGLE_BULLET_PROOF_SIZE], // REPLACE
|
||||
},
|
||||
};
|
||||
gen.with_reward(output, kernel)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::core::hash::Hashed;
|
||||
use crate::ser;
|
||||
|
||||
#[test]
|
||||
fn floonet_genesis_hash() {
|
||||
let gen_hash = genesis_floo().hash();
|
||||
println!("floonet genesis hash: {}", gen_hash.to_hex());
|
||||
let gen_bin = ser::ser_vec(&genesis_floo()).unwrap();
|
||||
println!("floonet genesis full hash: {}\n", gen_bin.hash().to_hex());
|
||||
assert_eq!(
|
||||
gen_hash.to_hex(),
|
||||
"cb272478ee4abbf41a3d8cc8f2f828785cf38bd7f0dcacfdd6db5f8f2d8f6e24"
|
||||
);
|
||||
assert_eq!(
|
||||
gen_bin.hash().to_hex(),
|
||||
"5fcc7afebc2dcfb98f982dd4d9ff7878fca45038d22677ef6360745c90505035"
|
||||
);
|
||||
}
|
||||
|
||||
// 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 = ser::ser_vec(&genesis_main()).unwrap();
|
||||
println!("mainnet genesis full hash: {}\n", gen_bin.hash().to_hex());
|
||||
//assert_eq!(gene_hash.to_hex, "");
|
||||
}
|
||||
}
|
||||
|
||||
+16
-52
@@ -20,7 +20,7 @@ use crate::consensus::HeaderInfo;
|
||||
use crate::consensus::{
|
||||
graph_weight, BASE_EDGE_BITS, BLOCK_TIME_SEC, COINBASE_MATURITY, CUT_THROUGH_HORIZON,
|
||||
DAY_HEIGHT, DEFAULT_MIN_EDGE_BITS, DIFFICULTY_ADJUST_WINDOW, INITIAL_DIFFICULTY, PROOFSIZE,
|
||||
SECOND_POW_EDGE_BITS, STATE_SYNC_THRESHOLD, T4_CUCKAROO_HARDFORK, UNIT_DIFFICULTY,
|
||||
SECOND_POW_EDGE_BITS, STATE_SYNC_THRESHOLD,
|
||||
};
|
||||
use crate::pow::{self, new_cuckaroo_ctx, new_cuckatoo_ctx, EdgeType, PoWContext};
|
||||
/// An enum collecting sets of parameters used throughout the
|
||||
@@ -62,13 +62,6 @@ pub const TESTING_INITIAL_GRAPH_WEIGHT: u32 = 1;
|
||||
/// Testing initial block difficulty
|
||||
pub const TESTING_INITIAL_DIFFICULTY: u64 = 1;
|
||||
|
||||
/// Testnet 2 initial block difficulty, high to see how it goes
|
||||
pub const TESTNET2_INITIAL_DIFFICULTY: u64 = 1000;
|
||||
|
||||
/// Testnet 3 initial block difficulty, moderately high, taking into account
|
||||
/// a 30x Cuckoo adjustment factor
|
||||
pub const TESTNET3_INITIAL_DIFFICULTY: u64 = 30000;
|
||||
|
||||
/// If a peer's last updated difficulty is 2 hours ago and its difficulty's lower than ours,
|
||||
/// we're sure this peer is a stuck node, and we will kick out such kind of stuck peers.
|
||||
pub const STUCK_PEER_KICK_TIME: i64 = 2 * 3600 * 1000;
|
||||
@@ -79,13 +72,6 @@ const PEER_EXPIRATION_DAYS: i64 = 7 * 2;
|
||||
/// Constant that expresses defunct peer timeout in seconds to be used in checks.
|
||||
pub const PEER_EXPIRATION_REMOVE_TIME: i64 = PEER_EXPIRATION_DAYS * 24 * 3600;
|
||||
|
||||
/// Testnet 4 initial block difficulty
|
||||
/// 1_000 times natural scale factor for cuckatoo29
|
||||
pub const TESTNET4_INITIAL_DIFFICULTY: u64 = 1_000 * UNIT_DIFFICULTY;
|
||||
|
||||
/// Cuckatoo edge_bits on T4
|
||||
pub const TESTNET4_MIN_EDGE_BITS: u8 = 30;
|
||||
|
||||
/// Trigger compaction check on average every day for all nodes.
|
||||
/// Randomized per node - roll the dice on every block to decide.
|
||||
/// Will compact the txhashset to remove pruned data.
|
||||
@@ -101,21 +87,15 @@ pub enum ChainTypes {
|
||||
AutomatedTesting,
|
||||
/// For User testing
|
||||
UserTesting,
|
||||
/// First test network
|
||||
Testnet1,
|
||||
/// Second test network
|
||||
Testnet2,
|
||||
/// Third test network
|
||||
Testnet3,
|
||||
/// Fourth test network
|
||||
Testnet4,
|
||||
/// Protocol testing network
|
||||
Floonet,
|
||||
/// Main production network
|
||||
Mainnet,
|
||||
}
|
||||
|
||||
impl Default for ChainTypes {
|
||||
fn default() -> ChainTypes {
|
||||
ChainTypes::Testnet4
|
||||
ChainTypes::Floonet
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,7 +129,7 @@ pub fn set_mining_mode(mode: ChainTypes) {
|
||||
/// Return either a cuckoo context or a cuckatoo context
|
||||
/// Single change point
|
||||
pub fn create_pow_context<T>(
|
||||
height: u64,
|
||||
_height: u64,
|
||||
edge_bits: u8,
|
||||
proof_size: usize,
|
||||
max_sols: u32,
|
||||
@@ -163,12 +143,9 @@ where
|
||||
ChainTypes::Mainnet if edge_bits == 29 => new_cuckaroo_ctx(edge_bits, proof_size),
|
||||
ChainTypes::Mainnet => new_cuckatoo_ctx(edge_bits, proof_size, max_sols),
|
||||
|
||||
// T4 has Cuckatoo for everything up to hard fork, then Cuckaroo29 for AR
|
||||
// and Cuckatoo30+ for AF PoW
|
||||
ChainTypes::Testnet4 if edge_bits == 29 && height >= T4_CUCKAROO_HARDFORK => {
|
||||
new_cuckaroo_ctx(edge_bits, proof_size)
|
||||
}
|
||||
ChainTypes::Testnet4 => new_cuckatoo_ctx(edge_bits, proof_size, max_sols),
|
||||
// Same for Floonet
|
||||
ChainTypes::Floonet if edge_bits == 29 => new_cuckaroo_ctx(edge_bits, proof_size),
|
||||
ChainTypes::Floonet => new_cuckatoo_ctx(edge_bits, proof_size, max_sols),
|
||||
|
||||
// Everything else is Cuckatoo only
|
||||
_ => new_cuckatoo_ctx(edge_bits, proof_size, max_sols),
|
||||
@@ -186,8 +163,6 @@ pub fn min_edge_bits() -> u8 {
|
||||
match *param_ref {
|
||||
ChainTypes::AutomatedTesting => AUTOMATED_TESTING_MIN_EDGE_BITS,
|
||||
ChainTypes::UserTesting => USER_TESTING_MIN_EDGE_BITS,
|
||||
ChainTypes::Testnet1 => USER_TESTING_MIN_EDGE_BITS,
|
||||
ChainTypes::Testnet4 => TESTNET4_MIN_EDGE_BITS,
|
||||
_ => DEFAULT_MIN_EDGE_BITS,
|
||||
}
|
||||
}
|
||||
@@ -200,7 +175,6 @@ pub fn base_edge_bits() -> u8 {
|
||||
match *param_ref {
|
||||
ChainTypes::AutomatedTesting => AUTOMATED_TESTING_MIN_EDGE_BITS,
|
||||
ChainTypes::UserTesting => USER_TESTING_MIN_EDGE_BITS,
|
||||
ChainTypes::Testnet1 => USER_TESTING_MIN_EDGE_BITS,
|
||||
_ => BASE_EDGE_BITS,
|
||||
}
|
||||
}
|
||||
@@ -231,10 +205,7 @@ pub fn initial_block_difficulty() -> u64 {
|
||||
match *param_ref {
|
||||
ChainTypes::AutomatedTesting => TESTING_INITIAL_DIFFICULTY,
|
||||
ChainTypes::UserTesting => TESTING_INITIAL_DIFFICULTY,
|
||||
ChainTypes::Testnet1 => TESTING_INITIAL_DIFFICULTY,
|
||||
ChainTypes::Testnet2 => TESTNET2_INITIAL_DIFFICULTY,
|
||||
ChainTypes::Testnet3 => TESTNET3_INITIAL_DIFFICULTY,
|
||||
ChainTypes::Testnet4 => TESTNET4_INITIAL_DIFFICULTY,
|
||||
ChainTypes::Floonet => INITIAL_DIFFICULTY,
|
||||
ChainTypes::Mainnet => INITIAL_DIFFICULTY,
|
||||
}
|
||||
}
|
||||
@@ -244,10 +215,7 @@ pub fn initial_graph_weight() -> u32 {
|
||||
match *param_ref {
|
||||
ChainTypes::AutomatedTesting => TESTING_INITIAL_GRAPH_WEIGHT,
|
||||
ChainTypes::UserTesting => TESTING_INITIAL_GRAPH_WEIGHT,
|
||||
ChainTypes::Testnet1 => TESTING_INITIAL_GRAPH_WEIGHT,
|
||||
ChainTypes::Testnet2 => TESTING_INITIAL_GRAPH_WEIGHT,
|
||||
ChainTypes::Testnet3 => TESTING_INITIAL_GRAPH_WEIGHT,
|
||||
ChainTypes::Testnet4 => graph_weight(0, SECOND_POW_EDGE_BITS) as u32,
|
||||
ChainTypes::Floonet => graph_weight(0, SECOND_POW_EDGE_BITS) as u32,
|
||||
ChainTypes::Mainnet => graph_weight(0, SECOND_POW_EDGE_BITS) as u32,
|
||||
}
|
||||
}
|
||||
@@ -288,20 +256,14 @@ pub fn is_user_testing_mode() -> bool {
|
||||
/// Production defined as a live public network, testnet[n] or mainnet.
|
||||
pub fn is_production_mode() -> bool {
|
||||
let param_ref = CHAIN_TYPE.read();
|
||||
ChainTypes::Testnet1 == *param_ref
|
||||
|| ChainTypes::Testnet2 == *param_ref
|
||||
|| ChainTypes::Testnet3 == *param_ref
|
||||
|| ChainTypes::Testnet4 == *param_ref
|
||||
ChainTypes::Floonet == *param_ref
|
||||
|| ChainTypes::Mainnet == *param_ref
|
||||
}
|
||||
|
||||
/// Are we in one of our (many) testnets?
|
||||
pub fn is_testnet() -> bool {
|
||||
let param_ref = CHAIN_TYPE.read();
|
||||
ChainTypes::Testnet1 == *param_ref
|
||||
|| ChainTypes::Testnet2 == *param_ref
|
||||
|| ChainTypes::Testnet3 == *param_ref
|
||||
|| ChainTypes::Testnet4 == *param_ref
|
||||
ChainTypes::Floonet == *param_ref
|
||||
}
|
||||
|
||||
/// Helper function to get a nonce known to create a valid POW on
|
||||
@@ -315,8 +277,10 @@ pub fn get_genesis_nonce() -> u64 {
|
||||
ChainTypes::AutomatedTesting => 0,
|
||||
// Magic nonce for current genesis block at cuckatoo15
|
||||
ChainTypes::UserTesting => 27944,
|
||||
// Magic nonce for genesis block for testnet2 (cuckatoo29)
|
||||
_ => panic!("Pre-set"),
|
||||
// Placeholder, obviously not the right value
|
||||
ChainTypes::Floonet => 0,
|
||||
// Placeholder, obviously not the right value
|
||||
ChainTypes::Mainnet => 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -241,34 +241,35 @@ pub fn verify_partial_sig(
|
||||
/// let commit = keychain.commit(value, &key_id).unwrap();
|
||||
/// let rproof = proof::create(&keychain, value, &key_id, commit, None).unwrap();
|
||||
/// let output = Output {
|
||||
/// features: OutputFeatures::COINBASE_OUTPUT,
|
||||
/// features: OutputFeatures::COINBASE,
|
||||
/// commit: commit,
|
||||
/// proof: rproof,
|
||||
/// };
|
||||
/// let height = 20;
|
||||
/// let over_commit = secp.commit_value(reward(fees)).unwrap();
|
||||
/// let out_commit = output.commitment();
|
||||
/// let msg = kernel_sig_msg(0, height, KernelFeatures::DEFAULT_KERNEL).unwrap();
|
||||
/// let msg = kernel_sig_msg(0, height, KernelFeatures::HEIGHT_LOCKED).unwrap();
|
||||
/// let excess = secp.commit_sum(vec![out_commit], vec![over_commit]).unwrap();
|
||||
/// let pubkey = excess.to_pubkey(&secp).unwrap();
|
||||
/// let sig = aggsig::sign_from_key_id(&secp, &keychain, &msg, &key_id, Some(&pubkey)).unwrap();
|
||||
/// let sig = aggsig::sign_from_key_id(&secp, &keychain, &msg, value, &key_id, Some(&pubkey)).unwrap();
|
||||
/// ```
|
||||
|
||||
pub fn sign_from_key_id<K>(
|
||||
secp: &Secp256k1,
|
||||
k: &K,
|
||||
msg: &Message,
|
||||
value: u64,
|
||||
key_id: &Identifier,
|
||||
blind_sum: Option<&PublicKey>,
|
||||
) -> Result<Signature, Error>
|
||||
where
|
||||
K: Keychain,
|
||||
{
|
||||
let skey = k.derive_key(key_id)?;
|
||||
let skey = k.derive_key(value, key_id)?;
|
||||
let sig = aggsig::sign_single(
|
||||
secp,
|
||||
&msg,
|
||||
&skey.secret_key,
|
||||
&skey,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
@@ -314,17 +315,17 @@ where
|
||||
/// let commit = keychain.commit(value, &key_id).unwrap();
|
||||
/// let rproof = proof::create(&keychain, value, &key_id, commit, None).unwrap();
|
||||
/// let output = Output {
|
||||
/// features: OutputFeatures::COINBASE_OUTPUT,
|
||||
/// features: OutputFeatures::COINBASE,
|
||||
/// commit: commit,
|
||||
/// proof: rproof,
|
||||
/// };
|
||||
/// let height = 20;
|
||||
/// let over_commit = secp.commit_value(reward(fees)).unwrap();
|
||||
/// let out_commit = output.commitment();
|
||||
/// let msg = kernel_sig_msg(0, height, KernelFeatures::DEFAULT_KERNEL).unwrap();
|
||||
/// let msg = kernel_sig_msg(0, height, KernelFeatures::HEIGHT_LOCKED).unwrap();
|
||||
/// let excess = secp.commit_sum(vec![out_commit], vec![over_commit]).unwrap();
|
||||
/// let pubkey = excess.to_pubkey(&secp).unwrap();
|
||||
/// let sig = aggsig::sign_from_key_id(&secp, &keychain, &msg, &key_id, Some(&pubkey)).unwrap();
|
||||
/// let sig = aggsig::sign_from_key_id(&secp, &keychain, &msg, value, &key_id, Some(&pubkey)).unwrap();
|
||||
///
|
||||
/// // Verify the signature from the excess commit
|
||||
/// let sig_verifies =
|
||||
|
||||
@@ -54,7 +54,7 @@ where
|
||||
move |build, (tx, kern, sum)| -> (Transaction, TxKernel, BlindSum) {
|
||||
let commit = build.keychain.commit(value, &key_id).unwrap();
|
||||
let input = Input::new(features, commit);
|
||||
(tx.with_input(input), kern, sum.sub_key_id(key_id.to_path()))
|
||||
(tx.with_input(input), kern, sum.sub_key_id(key_id.to_value_path(value)))
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -69,7 +69,7 @@ where
|
||||
"Building input (spending regular output): {}, {}",
|
||||
value, key_id
|
||||
);
|
||||
build_input(value, OutputFeatures::DEFAULT_OUTPUT, key_id)
|
||||
build_input(value, OutputFeatures::PLAIN, key_id)
|
||||
}
|
||||
|
||||
/// Adds a coinbase input spending a coinbase output.
|
||||
@@ -78,7 +78,7 @@ where
|
||||
K: Keychain,
|
||||
{
|
||||
debug!("Building input (spending coinbase): {}, {}", value, key_id);
|
||||
build_input(value, OutputFeatures::COINBASE_OUTPUT, key_id)
|
||||
build_input(value, OutputFeatures::COINBASE, key_id)
|
||||
}
|
||||
|
||||
/// Adds an output with the provided value and key identifier from the
|
||||
@@ -97,12 +97,12 @@ where
|
||||
|
||||
(
|
||||
tx.with_output(Output {
|
||||
features: OutputFeatures::DEFAULT_OUTPUT,
|
||||
features: OutputFeatures::PLAIN,
|
||||
commit: commit,
|
||||
proof: rproof,
|
||||
}),
|
||||
kern,
|
||||
sum.add_key_id(key_id.to_path()),
|
||||
sum.add_key_id(key_id.to_value_path(value)),
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -26,7 +26,7 @@ where
|
||||
K: Keychain,
|
||||
{
|
||||
// hash(commit|wallet root secret key (m)) as nonce
|
||||
let root_key = k.derive_key(&K::root_key_id())?.secret_key;
|
||||
let root_key = k.derive_key(0, &K::root_key_id())?;
|
||||
let res = blake2::blake2b::blake2b(32, &commit.0, &root_key.0[..]);
|
||||
let res = res.as_bytes();
|
||||
let mut ret_val = [0; 32];
|
||||
@@ -53,11 +53,11 @@ where
|
||||
K: Keychain,
|
||||
{
|
||||
let commit = k.commit(amount, key_id)?;
|
||||
let skey = k.derive_key(key_id)?;
|
||||
let skey = k.derive_key(amount, key_id)?;
|
||||
let nonce = create_nonce(k, &commit)?;
|
||||
let message = ProofMessage::from_bytes(&key_id.serialize_path());
|
||||
Ok(k.secp()
|
||||
.bullet_proof(amount, skey.secret_key, nonce, extra_data, Some(message)))
|
||||
.bullet_proof(amount, skey, nonce, extra_data, Some(message)))
|
||||
}
|
||||
|
||||
/// Verify a proof
|
||||
|
||||
@@ -27,7 +27,6 @@ pub fn output<K>(
|
||||
keychain: &K,
|
||||
key_id: &Identifier,
|
||||
fees: u64,
|
||||
height: u64,
|
||||
) -> Result<(Output, TxKernel), Error>
|
||||
where
|
||||
K: Keychain,
|
||||
@@ -40,7 +39,7 @@ where
|
||||
let rproof = proof::create(keychain, value, key_id, commit, None)?;
|
||||
|
||||
let output = Output {
|
||||
features: OutputFeatures::COINBASE_OUTPUT,
|
||||
features: OutputFeatures::COINBASE,
|
||||
commit: commit,
|
||||
proof: rproof,
|
||||
};
|
||||
@@ -53,22 +52,18 @@ where
|
||||
let pubkey = excess.to_pubkey(&secp)?;
|
||||
|
||||
// NOTE: Remember we sign the fee *and* the lock_height.
|
||||
// For a coinbase output the fee is 0 and the lock_height is
|
||||
// the lock_height of the coinbase output itself,
|
||||
// not the lock_height of the tx (there is no tx for a coinbase output).
|
||||
// This output will not be spendable earlier than lock_height (and we sign this
|
||||
// here).
|
||||
let msg = kernel_sig_msg(0, height, KernelFeatures::COINBASE_KERNEL)?;
|
||||
let sig = aggsig::sign_from_key_id(&secp, keychain, &msg, &key_id, Some(&pubkey))?;
|
||||
// For a coinbase output the fee is 0 and the lock_height is 0
|
||||
let msg = kernel_sig_msg(0, 0, KernelFeatures::COINBASE)?;
|
||||
let sig = aggsig::sign_from_key_id(&secp, keychain, &msg, value, &key_id, Some(&pubkey))?;
|
||||
|
||||
let proof = TxKernel {
|
||||
features: KernelFeatures::COINBASE_KERNEL,
|
||||
features: KernelFeatures::COINBASE,
|
||||
excess: excess,
|
||||
excess_sig: sig,
|
||||
fee: 0,
|
||||
// lock_height here is the height of the block (tx should be valid immediately)
|
||||
// *not* the lock_height of the coinbase output (only spendable 1,000 blocks later)
|
||||
lock_height: height,
|
||||
// lock_height here is 0
|
||||
// *not* the maturity of the coinbase output (only spendable 1,440 blocks later)
|
||||
lock_height: 0,
|
||||
};
|
||||
Ok((output, proof))
|
||||
}
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
//! around during an interactive wallet exchange
|
||||
|
||||
use crate::blake2::blake2b::blake2b;
|
||||
use crate::core::committed::Committed;
|
||||
use crate::core::transaction::{kernel_sig_msg, KernelFeatures, Transaction};
|
||||
use crate::core::verifier_cache::LruVerifierCache;
|
||||
use crate::core::amount_to_hr_string;
|
||||
use crate::core::committed::Committed;
|
||||
use crate::core::transaction::{kernel_features, kernel_sig_msg, Transaction};
|
||||
use crate::core::verifier_cache::LruVerifierCache;
|
||||
use crate::keychain::{BlindSum, BlindingFactor, Keychain};
|
||||
use crate::libtx::error::{Error, ErrorKind};
|
||||
use crate::libtx::{aggsig, build, tx_fee};
|
||||
@@ -160,8 +160,7 @@ impl Slate {
|
||||
// Currently includes the fee and the lock_height.
|
||||
fn msg_to_sign(&self) -> Result<secp::Message, Error> {
|
||||
// Currently we only support interactively creating a tx with a "default" kernel.
|
||||
let features = KernelFeatures::DEFAULT_KERNEL;
|
||||
|
||||
let features = kernel_features(self.lock_height);
|
||||
let msg = kernel_sig_msg(self.fee, self.lock_height, features)?;
|
||||
Ok(msg)
|
||||
}
|
||||
|
||||
+1
-1
@@ -69,7 +69,7 @@ pub fn verify_size(bh: &BlockHeader) -> Result<(), Error> {
|
||||
|
||||
/// Mines a genesis block using the internal miner
|
||||
pub fn mine_genesis_block() -> Result<Block, Error> {
|
||||
let mut gen = genesis::genesis_testnet2();
|
||||
let mut gen = genesis::genesis_dev();
|
||||
if global::is_user_testing_mode() || global::is_automated_testing_mode() {
|
||||
gen = genesis::genesis_dev();
|
||||
gen.header.timestamp = Utc::now();
|
||||
|
||||
Reference in New Issue
Block a user