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:
Ignotus Peverell
2018-12-20 18:12:08 -08:00
committed by GitHub
55 changed files with 978 additions and 453 deletions
+5 -33
View File
@@ -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
}
+5 -5
View File
@@ -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>>();
{
+3 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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,
}
}
+9 -8
View File
@@ -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 =
+5 -5
View File
@@ -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)),
)
},
)
+3 -3
View File
@@ -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
+8 -13
View File
@@ -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))
}
+4 -5
View File
@@ -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
View File
@@ -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();