mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-20 19:11:08 +03:00
header version 4 accompanied by new AR PoW (#3334)
This commit is contained in:
parent
450d235358
commit
f4295917a0
6 changed files with 339 additions and 39 deletions
|
@ -133,6 +133,9 @@ pub const FLOONET_FIRST_HARD_FORK: u64 = 185_040;
|
||||||
/// Floonet second hard fork height, set to happen around 2019-12-19
|
/// Floonet second hard fork height, set to happen around 2019-12-19
|
||||||
pub const FLOONET_SECOND_HARD_FORK: u64 = 298_080;
|
pub const FLOONET_SECOND_HARD_FORK: u64 = 298_080;
|
||||||
|
|
||||||
|
/// Floonet second hard fork height, set to happen around 2020-06-20
|
||||||
|
pub const FLOONET_THIRD_HARD_FORK: u64 = 552_960;
|
||||||
|
|
||||||
/// AutomatedTesting and UserTesting HF1 height.
|
/// AutomatedTesting and UserTesting HF1 height.
|
||||||
pub const TESTING_FIRST_HARD_FORK: u64 = 3;
|
pub const TESTING_FIRST_HARD_FORK: u64 = 3;
|
||||||
|
|
||||||
|
@ -154,8 +157,10 @@ pub fn header_version(height: u64) -> HeaderVersion {
|
||||||
HeaderVersion(1)
|
HeaderVersion(1)
|
||||||
} else if height < FLOONET_SECOND_HARD_FORK {
|
} else if height < FLOONET_SECOND_HARD_FORK {
|
||||||
HeaderVersion(2)
|
HeaderVersion(2)
|
||||||
} else if height < 3 * HARD_FORK_INTERVAL {
|
} else if height < FLOONET_THIRD_HARD_FORK {
|
||||||
HeaderVersion(3)
|
HeaderVersion(3)
|
||||||
|
} else if height < 4 * HARD_FORK_INTERVAL {
|
||||||
|
HeaderVersion(4)
|
||||||
} else {
|
} else {
|
||||||
HeaderVersion(hf_interval)
|
HeaderVersion(hf_interval)
|
||||||
}
|
}
|
||||||
|
@ -179,7 +184,7 @@ pub fn header_version(height: u64) -> HeaderVersion {
|
||||||
/// Check whether the block version is valid at a given height, implements
|
/// Check whether the block version is valid at a given height, implements
|
||||||
/// 6 months interval scheduled hard forks for the first 2 years.
|
/// 6 months interval scheduled hard forks for the first 2 years.
|
||||||
pub fn valid_header_version(height: u64, version: HeaderVersion) -> bool {
|
pub fn valid_header_version(height: u64, version: HeaderVersion) -> bool {
|
||||||
height < 3 * HARD_FORK_INTERVAL && version == header_version(height)
|
height < 4 * HARD_FORK_INTERVAL && version == header_version(height)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Number of blocks used to calculate difficulty adjustments
|
/// Number of blocks used to calculate difficulty adjustments
|
||||||
|
@ -199,8 +204,7 @@ pub const DIFFICULTY_DAMP_FACTOR: u64 = 3;
|
||||||
pub const AR_SCALE_DAMP_FACTOR: u64 = 13;
|
pub const AR_SCALE_DAMP_FACTOR: u64 = 13;
|
||||||
|
|
||||||
/// Compute weight of a graph as number of siphash bits defining the graph
|
/// Compute weight of a graph as number of siphash bits defining the graph
|
||||||
/// Must be made dependent on height to phase out C31 in early 2020
|
/// The height dependence allows a 30-week linear transition from C31+ to C32+ starting after 1 year
|
||||||
/// Later phase outs are on hold for now
|
|
||||||
pub fn graph_weight(height: u64, edge_bits: u8) -> u64 {
|
pub fn graph_weight(height: u64, edge_bits: u8) -> u64 {
|
||||||
let mut xpr_edge_bits = edge_bits as u64;
|
let mut xpr_edge_bits = edge_bits as u64;
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,8 @@ use crate::consensus::{
|
||||||
};
|
};
|
||||||
use crate::core::block::HeaderVersion;
|
use crate::core::block::HeaderVersion;
|
||||||
use crate::pow::{
|
use crate::pow::{
|
||||||
self, new_cuckaroo_ctx, new_cuckarood_ctx, new_cuckaroom_ctx, new_cuckatoo_ctx, EdgeType,
|
self, new_cuckaroo_ctx, new_cuckarood_ctx, new_cuckaroom_ctx, new_cuckarooz_ctx,
|
||||||
PoWContext,
|
new_cuckatoo_ctx, EdgeType, PoWContext,
|
||||||
};
|
};
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use util::OneTime;
|
use util::OneTime;
|
||||||
|
@ -225,8 +225,11 @@ where
|
||||||
{
|
{
|
||||||
let chain_type = get_chain_type();
|
let chain_type = get_chain_type();
|
||||||
match chain_type {
|
match chain_type {
|
||||||
// Mainnet has Cuckaroo(d)29 for AR and Cuckatoo31+ for AF
|
// Mainnet has Cuckaroo{,d,m,z}29 for AR and Cuckatoo31+ for AF
|
||||||
ChainTypes::Mainnet if edge_bits > 29 => new_cuckatoo_ctx(edge_bits, proof_size, max_sols),
|
ChainTypes::Mainnet if edge_bits > 29 => new_cuckatoo_ctx(edge_bits, proof_size, max_sols),
|
||||||
|
ChainTypes::Mainnet if valid_header_version(height, HeaderVersion(4)) => {
|
||||||
|
new_cuckarooz_ctx(edge_bits, proof_size)
|
||||||
|
}
|
||||||
ChainTypes::Mainnet if valid_header_version(height, HeaderVersion(3)) => {
|
ChainTypes::Mainnet if valid_header_version(height, HeaderVersion(3)) => {
|
||||||
new_cuckaroom_ctx(edge_bits, proof_size)
|
new_cuckaroom_ctx(edge_bits, proof_size)
|
||||||
}
|
}
|
||||||
|
@ -237,6 +240,9 @@ where
|
||||||
|
|
||||||
// Same for Floonet
|
// Same for Floonet
|
||||||
ChainTypes::Floonet if edge_bits > 29 => new_cuckatoo_ctx(edge_bits, proof_size, max_sols),
|
ChainTypes::Floonet if edge_bits > 29 => new_cuckatoo_ctx(edge_bits, proof_size, max_sols),
|
||||||
|
ChainTypes::Floonet if valid_header_version(height, HeaderVersion(4)) => {
|
||||||
|
new_cuckarooz_ctx(edge_bits, proof_size)
|
||||||
|
}
|
||||||
ChainTypes::Floonet if valid_header_version(height, HeaderVersion(3)) => {
|
ChainTypes::Floonet if valid_header_version(height, HeaderVersion(3)) => {
|
||||||
new_cuckaroom_ctx(edge_bits, proof_size)
|
new_cuckaroom_ctx(edge_bits, proof_size)
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ mod common;
|
||||||
pub mod cuckaroo;
|
pub mod cuckaroo;
|
||||||
pub mod cuckarood;
|
pub mod cuckarood;
|
||||||
pub mod cuckaroom;
|
pub mod cuckaroom;
|
||||||
|
pub mod cuckarooz;
|
||||||
pub mod cuckatoo;
|
pub mod cuckatoo;
|
||||||
mod error;
|
mod error;
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
@ -51,6 +52,7 @@ mod types;
|
||||||
pub use crate::pow::cuckaroo::{new_cuckaroo_ctx, CuckarooContext};
|
pub use crate::pow::cuckaroo::{new_cuckaroo_ctx, CuckarooContext};
|
||||||
pub use crate::pow::cuckarood::{new_cuckarood_ctx, CuckaroodContext};
|
pub use crate::pow::cuckarood::{new_cuckarood_ctx, CuckaroodContext};
|
||||||
pub use crate::pow::cuckaroom::{new_cuckaroom_ctx, CuckaroomContext};
|
pub use crate::pow::cuckaroom::{new_cuckaroom_ctx, CuckaroomContext};
|
||||||
|
pub use crate::pow::cuckarooz::{new_cuckarooz_ctx, CuckaroozContext};
|
||||||
pub use crate::pow::cuckatoo::{new_cuckatoo_ctx, CuckatooContext};
|
pub use crate::pow::cuckatoo::{new_cuckatoo_ctx, CuckatooContext};
|
||||||
pub use crate::pow::error::Error;
|
pub use crate::pow::error::Error;
|
||||||
use chrono::prelude::{DateTime, NaiveDateTime, Utc};
|
use chrono::prelude::{DateTime, NaiveDateTime, Utc};
|
||||||
|
|
193
core/src/pow/cuckarooz.rs
Normal file
193
core/src/pow/cuckarooz.rs
Normal file
|
@ -0,0 +1,193 @@
|
||||||
|
// Copyright 2020 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.
|
||||||
|
|
||||||
|
//! Implementation of Cuckarooz Cycle, based on Cuckoo Cycle designed by
|
||||||
|
//! John Tromp. Ported to Rust from https://github.com/tromp/cuckoo.
|
||||||
|
//!
|
||||||
|
//! Cuckarooz is a variation of Cuckaroo that's tweaked at the third HardFork
|
||||||
|
//! to maintain ASIC-Resistance, as introduced in
|
||||||
|
//! https://forum.grin.mw/t/introducing-the-final-tweak-cuckarooz
|
||||||
|
//! It completes the choices of undirected vs directed edges and bipartite vs
|
||||||
|
//! monopartite graphs, and is named after the last letter of the alphabet
|
||||||
|
//! accordingly.
|
||||||
|
|
||||||
|
use crate::global;
|
||||||
|
use crate::pow::common::{CuckooParams, EdgeType};
|
||||||
|
use crate::pow::error::{Error, ErrorKind};
|
||||||
|
use crate::pow::siphash::siphash_block;
|
||||||
|
use crate::pow::{PoWContext, Proof};
|
||||||
|
|
||||||
|
/// Instantiate a new CuckaroozContext as a PowContext. Note that this can't
|
||||||
|
/// be moved in the PoWContext trait as this particular trait needs to be
|
||||||
|
/// convertible to an object trait.
|
||||||
|
pub fn new_cuckarooz_ctx<T>(
|
||||||
|
edge_bits: u8,
|
||||||
|
proof_size: usize,
|
||||||
|
) -> Result<Box<dyn PoWContext<T>>, Error>
|
||||||
|
where
|
||||||
|
T: EdgeType + 'static,
|
||||||
|
{
|
||||||
|
let params = CuckooParams::new(edge_bits, proof_size)?;
|
||||||
|
Ok(Box::new(CuckaroozContext { params }))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cuckarooz cycle context. Only includes the verifier for now.
|
||||||
|
pub struct CuckaroozContext<T>
|
||||||
|
where
|
||||||
|
T: EdgeType,
|
||||||
|
{
|
||||||
|
params: CuckooParams<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PoWContext<T> for CuckaroozContext<T>
|
||||||
|
where
|
||||||
|
T: EdgeType,
|
||||||
|
{
|
||||||
|
fn set_header_nonce(
|
||||||
|
&mut self,
|
||||||
|
header: Vec<u8>,
|
||||||
|
nonce: Option<u32>,
|
||||||
|
_solve: bool,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
self.params.reset_header_nonce(header, nonce)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_cycles(&mut self) -> Result<Vec<Proof>, Error> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn verify(&self, proof: &Proof) -> Result<(), Error> {
|
||||||
|
if proof.proof_size() != global::proofsize() {
|
||||||
|
return Err(ErrorKind::Verification("wrong cycle length".to_owned()).into());
|
||||||
|
}
|
||||||
|
let nonces = &proof.nonces;
|
||||||
|
let mut uvs = vec![0u64; 2 * proof.proof_size()];
|
||||||
|
let mut xoruv: u64 = 0;
|
||||||
|
|
||||||
|
for n in 0..proof.proof_size() {
|
||||||
|
if nonces[n] > to_u64!(self.params.edge_mask) {
|
||||||
|
return Err(ErrorKind::Verification("edge too big".to_owned()).into());
|
||||||
|
}
|
||||||
|
if n > 0 && nonces[n] <= nonces[n - 1] {
|
||||||
|
return Err(ErrorKind::Verification("edges not ascending".to_owned()).into());
|
||||||
|
}
|
||||||
|
// 21 is standard siphash rotation constant
|
||||||
|
let edge = to_edge!(
|
||||||
|
T,
|
||||||
|
siphash_block(&self.params.siphash_keys, nonces[n], 21, true)
|
||||||
|
);
|
||||||
|
uvs[2 * n] = to_u64!(edge & self.params.edge_mask);
|
||||||
|
uvs[2 * n + 1] = to_u64!((edge >> 32) & self.params.edge_mask);
|
||||||
|
xoruv ^= uvs[2 * n] ^ uvs[2 * n + 1];
|
||||||
|
}
|
||||||
|
if xoruv != 0 {
|
||||||
|
return Err(ErrorKind::Verification("endpoints don't match up".to_owned()).into());
|
||||||
|
}
|
||||||
|
let mut n = 0;
|
||||||
|
let mut i = 0;
|
||||||
|
let mut j;
|
||||||
|
loop {
|
||||||
|
// follow cycle
|
||||||
|
j = i;
|
||||||
|
let mut k = j;
|
||||||
|
loop {
|
||||||
|
k = (k + 1) % (2 * self.params.proof_size);
|
||||||
|
if k == i {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if uvs[k] == uvs[i] {
|
||||||
|
// find other edge endpoint matching one at i
|
||||||
|
if j != i {
|
||||||
|
return Err(ErrorKind::Verification("branch in cycle".to_owned()).into());
|
||||||
|
}
|
||||||
|
j = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if j == i {
|
||||||
|
return Err(ErrorKind::Verification("cycle dead ends".to_owned()).into());
|
||||||
|
}
|
||||||
|
i = j ^ 1;
|
||||||
|
n += 1;
|
||||||
|
if i == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if n == self.params.proof_size {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(ErrorKind::Verification("cycle too short".to_owned()).into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
// empty header, nonce 71
|
||||||
|
static V1_19_HASH: [u64; 4] = [
|
||||||
|
0xd129f63fba4d9a85,
|
||||||
|
0x457dcb3666c5e09c,
|
||||||
|
0x045247a2e2ee75f7,
|
||||||
|
0x1a0f2e1bcb9d93ff,
|
||||||
|
];
|
||||||
|
static V1_19_SOL: [u64; 42] = [
|
||||||
|
0x33b6, 0x487b, 0x88b7, 0x10bf6, 0x15144, 0x17cb7, 0x22621, 0x2358e, 0x23775, 0x24fb3,
|
||||||
|
0x26b8a, 0x2876c, 0x2973e, 0x2f4ba, 0x30a62, 0x3a36b, 0x3ba5d, 0x3be67, 0x3ec56, 0x43141,
|
||||||
|
0x4b9c5, 0x4fa06, 0x51a5c, 0x523e5, 0x53d08, 0x57d34, 0x5c2de, 0x60bba, 0x62509, 0x64d69,
|
||||||
|
0x6803f, 0x68af4, 0x6bd52, 0x6f041, 0x6f900, 0x70051, 0x7097d, 0x735e8, 0x742c2, 0x79ae5,
|
||||||
|
0x7f64d, 0x7fd49,
|
||||||
|
];
|
||||||
|
|
||||||
|
// empty header, nonce 15
|
||||||
|
static V2_29_HASH: [u64; 4] = [
|
||||||
|
0x34bb4c75c929a2f5,
|
||||||
|
0x21df13263aa81235,
|
||||||
|
0x37d00939eae4be06,
|
||||||
|
0x473251cbf6941553,
|
||||||
|
];
|
||||||
|
static V2_29_SOL: [u64; 42] = [
|
||||||
|
0x49733a, 0x1d49107, 0x253d2ca, 0x5ad5e59, 0x5b671bd, 0x5dcae1c, 0x5f9a589, 0x65e9afc,
|
||||||
|
0x6a59a45, 0x7d9c6d3, 0x7df96e4, 0x8b26174, 0xa17b430, 0xa1c8c0d, 0xa8a0327, 0xabd7402,
|
||||||
|
0xacb7c77, 0xb67524f, 0xc1c15a6, 0xc7e2c26, 0xc7f5d8d, 0xcae478a, 0xdea9229, 0xe1ab49e,
|
||||||
|
0xf57c7db, 0xfb4e8c5, 0xff314aa, 0x110ccc12, 0x143e546f, 0x17007af8, 0x17140ea2,
|
||||||
|
0x173d7c5d, 0x175cd13f, 0x178b8880, 0x1801edc5, 0x18c8f56b, 0x18c8fe6d, 0x19f1a31a,
|
||||||
|
0x1bb028d1, 0x1caaa65a, 0x1cf29bc2, 0x1dbde27d,
|
||||||
|
];
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cuckarooz19_29_vectors() {
|
||||||
|
global::set_local_chain_type(global::ChainTypes::Mainnet);
|
||||||
|
let mut ctx19 = new_impl::<u64>(19, 42);
|
||||||
|
ctx19.params.siphash_keys = V1_19_HASH.clone();
|
||||||
|
assert!(ctx19
|
||||||
|
.verify(&Proof::new(V1_19_SOL.to_vec().clone()))
|
||||||
|
.is_ok());
|
||||||
|
assert!(ctx19.verify(&Proof::zero(42)).is_err());
|
||||||
|
let mut ctx29 = new_impl::<u64>(29, 42);
|
||||||
|
ctx29.params.siphash_keys = V2_29_HASH.clone();
|
||||||
|
assert!(ctx29
|
||||||
|
.verify(&Proof::new(V2_29_SOL.to_vec().clone()))
|
||||||
|
.is_ok());
|
||||||
|
assert!(ctx29.verify(&Proof::zero(42)).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_impl<T>(edge_bits: u8, proof_size: usize) -> CuckaroozContext<T>
|
||||||
|
where
|
||||||
|
T: EdgeType,
|
||||||
|
{
|
||||||
|
let params = CuckooParams::new(edge_bits, proof_size).unwrap();
|
||||||
|
CuckaroozContext { params }
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
use grin_core::consensus::{
|
use grin_core::consensus::{
|
||||||
secondary_pow_ratio, valid_header_version, FLOONET_FIRST_HARD_FORK, FLOONET_SECOND_HARD_FORK,
|
secondary_pow_ratio, valid_header_version, FLOONET_FIRST_HARD_FORK, FLOONET_SECOND_HARD_FORK,
|
||||||
YEAR_HEIGHT,
|
FLOONET_THIRD_HARD_FORK, HARD_FORK_INTERVAL,
|
||||||
};
|
};
|
||||||
use grin_core::core::HeaderVersion;
|
use grin_core::core::HeaderVersion;
|
||||||
use grin_core::global;
|
use grin_core::global;
|
||||||
|
@ -84,7 +84,6 @@ fn hard_forks() {
|
||||||
FLOONET_FIRST_HARD_FORK,
|
FLOONET_FIRST_HARD_FORK,
|
||||||
HeaderVersion(1)
|
HeaderVersion(1)
|
||||||
));
|
));
|
||||||
assert!(!valid_header_version(YEAR_HEIGHT, HeaderVersion(1)));
|
|
||||||
assert!(valid_header_version(
|
assert!(valid_header_version(
|
||||||
FLOONET_SECOND_HARD_FORK - 1,
|
FLOONET_SECOND_HARD_FORK - 1,
|
||||||
HeaderVersion(2)
|
HeaderVersion(2)
|
||||||
|
@ -105,19 +104,70 @@ fn hard_forks() {
|
||||||
FLOONET_SECOND_HARD_FORK,
|
FLOONET_SECOND_HARD_FORK,
|
||||||
HeaderVersion(1)
|
HeaderVersion(1)
|
||||||
));
|
));
|
||||||
|
assert!(valid_header_version(
|
||||||
assert!(!valid_header_version(YEAR_HEIGHT - 1, HeaderVersion(2)));
|
FLOONET_THIRD_HARD_FORK - 1,
|
||||||
assert!(valid_header_version(YEAR_HEIGHT - 1, HeaderVersion(3)));
|
|
||||||
assert!(valid_header_version(YEAR_HEIGHT, HeaderVersion(3)));
|
|
||||||
assert!(valid_header_version(YEAR_HEIGHT + 1, HeaderVersion(3)));
|
|
||||||
// v4 not active yet
|
|
||||||
assert!(!valid_header_version(YEAR_HEIGHT * 3 / 2, HeaderVersion(4)));
|
|
||||||
assert!(!valid_header_version(YEAR_HEIGHT * 3 / 2, HeaderVersion(3)));
|
|
||||||
assert!(!valid_header_version(YEAR_HEIGHT * 3 / 2, HeaderVersion(2)));
|
|
||||||
assert!(!valid_header_version(YEAR_HEIGHT * 3 / 2, HeaderVersion(1)));
|
|
||||||
assert!(!valid_header_version(YEAR_HEIGHT * 2, HeaderVersion(3)));
|
|
||||||
assert!(!valid_header_version(
|
|
||||||
YEAR_HEIGHT * 3 / 2 + 1,
|
|
||||||
HeaderVersion(3)
|
HeaderVersion(3)
|
||||||
));
|
));
|
||||||
|
assert!(valid_header_version(
|
||||||
|
FLOONET_THIRD_HARD_FORK,
|
||||||
|
HeaderVersion(4)
|
||||||
|
));
|
||||||
|
assert!(valid_header_version(
|
||||||
|
FLOONET_THIRD_HARD_FORK + 1,
|
||||||
|
HeaderVersion(4)
|
||||||
|
));
|
||||||
|
assert!(!valid_header_version(
|
||||||
|
FLOONET_THIRD_HARD_FORK,
|
||||||
|
HeaderVersion(3)
|
||||||
|
));
|
||||||
|
assert!(!valid_header_version(
|
||||||
|
FLOONET_THIRD_HARD_FORK,
|
||||||
|
HeaderVersion(2)
|
||||||
|
));
|
||||||
|
assert!(!valid_header_version(
|
||||||
|
FLOONET_THIRD_HARD_FORK,
|
||||||
|
HeaderVersion(1)
|
||||||
|
));
|
||||||
|
|
||||||
|
assert!(!valid_header_version(
|
||||||
|
HARD_FORK_INTERVAL * 2 - 1,
|
||||||
|
HeaderVersion(1)
|
||||||
|
));
|
||||||
|
assert!(!valid_header_version(
|
||||||
|
HARD_FORK_INTERVAL * 2 - 1,
|
||||||
|
HeaderVersion(2)
|
||||||
|
));
|
||||||
|
assert!(valid_header_version(
|
||||||
|
HARD_FORK_INTERVAL * 2 - 1,
|
||||||
|
HeaderVersion(3)
|
||||||
|
));
|
||||||
|
assert!(valid_header_version(
|
||||||
|
HARD_FORK_INTERVAL * 2,
|
||||||
|
HeaderVersion(3)
|
||||||
|
));
|
||||||
|
assert!(valid_header_version(
|
||||||
|
HARD_FORK_INTERVAL * 2 + 1,
|
||||||
|
HeaderVersion(3)
|
||||||
|
));
|
||||||
|
// v5 not active yet
|
||||||
|
assert!(!valid_header_version(
|
||||||
|
HARD_FORK_INTERVAL * 4,
|
||||||
|
HeaderVersion(5)
|
||||||
|
));
|
||||||
|
assert!(!valid_header_version(
|
||||||
|
HARD_FORK_INTERVAL * 4,
|
||||||
|
HeaderVersion(4)
|
||||||
|
));
|
||||||
|
assert!(!valid_header_version(
|
||||||
|
HARD_FORK_INTERVAL * 4,
|
||||||
|
HeaderVersion(3)
|
||||||
|
));
|
||||||
|
assert!(!valid_header_version(
|
||||||
|
HARD_FORK_INTERVAL * 4,
|
||||||
|
HeaderVersion(2)
|
||||||
|
));
|
||||||
|
assert!(!valid_header_version(
|
||||||
|
HARD_FORK_INTERVAL * 4,
|
||||||
|
HeaderVersion(1)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
|
@ -438,25 +438,70 @@ fn hard_forks() {
|
||||||
assert!(valid_header_version(0, HeaderVersion(1)));
|
assert!(valid_header_version(0, HeaderVersion(1)));
|
||||||
assert!(valid_header_version(10, HeaderVersion(1)));
|
assert!(valid_header_version(10, HeaderVersion(1)));
|
||||||
assert!(!valid_header_version(10, HeaderVersion(2)));
|
assert!(!valid_header_version(10, HeaderVersion(2)));
|
||||||
assert!(valid_header_version(YEAR_HEIGHT / 2 - 1, HeaderVersion(1)));
|
assert!(valid_header_version(
|
||||||
assert!(valid_header_version(YEAR_HEIGHT / 2, HeaderVersion(2)));
|
HARD_FORK_INTERVAL - 1,
|
||||||
assert!(valid_header_version(YEAR_HEIGHT / 2 + 1, HeaderVersion(2)));
|
HeaderVersion(1)
|
||||||
assert!(!valid_header_version(YEAR_HEIGHT / 2, HeaderVersion(1)));
|
));
|
||||||
assert!(!valid_header_version(YEAR_HEIGHT, HeaderVersion(1)));
|
assert!(!valid_header_version(HARD_FORK_INTERVAL, HeaderVersion(1)));
|
||||||
|
assert!(valid_header_version(HARD_FORK_INTERVAL, HeaderVersion(2)));
|
||||||
|
assert!(valid_header_version(
|
||||||
|
HARD_FORK_INTERVAL + 1,
|
||||||
|
HeaderVersion(2)
|
||||||
|
));
|
||||||
|
|
||||||
assert!(valid_header_version(YEAR_HEIGHT - 1, HeaderVersion(2)));
|
assert!(valid_header_version(
|
||||||
assert!(valid_header_version(YEAR_HEIGHT, HeaderVersion(3)));
|
HARD_FORK_INTERVAL * 2 - 1,
|
||||||
assert!(valid_header_version(YEAR_HEIGHT + 1, HeaderVersion(3)));
|
HeaderVersion(2)
|
||||||
assert!(!valid_header_version(YEAR_HEIGHT, HeaderVersion(2)));
|
));
|
||||||
assert!(!valid_header_version(YEAR_HEIGHT * 3 / 2, HeaderVersion(2)));
|
|
||||||
// v4 not active yet
|
|
||||||
assert!(!valid_header_version(YEAR_HEIGHT * 3 / 2, HeaderVersion(4)));
|
|
||||||
assert!(!valid_header_version(YEAR_HEIGHT * 3 / 2, HeaderVersion(3)));
|
|
||||||
assert!(!valid_header_version(YEAR_HEIGHT * 3 / 2, HeaderVersion(2)));
|
|
||||||
assert!(!valid_header_version(YEAR_HEIGHT * 3 / 2, HeaderVersion(1)));
|
|
||||||
assert!(!valid_header_version(YEAR_HEIGHT * 2, HeaderVersion(3)));
|
|
||||||
assert!(!valid_header_version(
|
assert!(!valid_header_version(
|
||||||
YEAR_HEIGHT * 3 / 2 + 1,
|
HARD_FORK_INTERVAL * 2,
|
||||||
|
HeaderVersion(2)
|
||||||
|
));
|
||||||
|
assert!(valid_header_version(
|
||||||
|
HARD_FORK_INTERVAL * 2,
|
||||||
HeaderVersion(3)
|
HeaderVersion(3)
|
||||||
));
|
));
|
||||||
|
assert!(valid_header_version(
|
||||||
|
HARD_FORK_INTERVAL * 2 + 1,
|
||||||
|
HeaderVersion(3)
|
||||||
|
));
|
||||||
|
|
||||||
|
assert!(valid_header_version(
|
||||||
|
HARD_FORK_INTERVAL * 3 - 1,
|
||||||
|
HeaderVersion(3)
|
||||||
|
));
|
||||||
|
assert!(!valid_header_version(
|
||||||
|
HARD_FORK_INTERVAL * 3,
|
||||||
|
HeaderVersion(3)
|
||||||
|
));
|
||||||
|
assert!(valid_header_version(
|
||||||
|
HARD_FORK_INTERVAL * 3,
|
||||||
|
HeaderVersion(4)
|
||||||
|
));
|
||||||
|
assert!(valid_header_version(
|
||||||
|
HARD_FORK_INTERVAL * 3 + 1,
|
||||||
|
HeaderVersion(4)
|
||||||
|
));
|
||||||
|
|
||||||
|
// v5 not active yet
|
||||||
|
assert!(!valid_header_version(
|
||||||
|
HARD_FORK_INTERVAL * 4,
|
||||||
|
HeaderVersion(5)
|
||||||
|
));
|
||||||
|
assert!(!valid_header_version(
|
||||||
|
HARD_FORK_INTERVAL * 4,
|
||||||
|
HeaderVersion(4)
|
||||||
|
));
|
||||||
|
assert!(!valid_header_version(
|
||||||
|
HARD_FORK_INTERVAL * 4,
|
||||||
|
HeaderVersion(3)
|
||||||
|
));
|
||||||
|
assert!(!valid_header_version(
|
||||||
|
HARD_FORK_INTERVAL * 4,
|
||||||
|
HeaderVersion(2)
|
||||||
|
));
|
||||||
|
assert!(!valid_header_version(
|
||||||
|
HARD_FORK_INTERVAL * 4,
|
||||||
|
HeaderVersion(1)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue