Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

ethash: implement Progpow #9762

Merged
merged 53 commits into from
Feb 20, 2019
Merged
Show file tree
Hide file tree
Changes from 51 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
2522e67
ethash: initial implementation of progpow
andresilva Sep 24, 2018
61f1922
progpow: use wrapping arithmetic
andresilva Oct 12, 2018
7c64f93
progpow: cleanup comments
andresilva Oct 12, 2018
4700ee8
progpow: fix keccak_f800
andresilva Oct 12, 2018
d252dd1
progpow: reorder definitions
andresilva Oct 12, 2018
fde1d2e
progpow: general fixing
andresilva Oct 12, 2018
3a37dc4
progpow: add basic tests from geth
andresilva Oct 15, 2018
2b14323
progpow: generate c_dag and add test
andresilva Oct 15, 2018
af1c0f6
progpow: fix progpow_init and progpow_loop
andresilva Oct 16, 2018
526daa6
progpow: fix and add new test
andresilva Oct 16, 2018
a19aa8d
progpow: tabify
andresilva Oct 16, 2018
7303491
progpow: add shared testvectors from geth and aleth
andresilva Oct 16, 2018
7630b33
progpow: add benchmarks
andresilva Oct 16, 2018
afe53ff
progpow: don't read bytes from dag
andresilva Oct 16, 2018
2fa0b3e
ethash: use criterion for progpow benchmarks
andresilva Oct 17, 2018
54a32a3
progpow: dont borrow hash on fnv1a_hash
andresilva Oct 17, 2018
025bc14
progpow: don't borrow operand on progpow merge
andresilva Oct 17, 2018
408d35e
progpow: hardcode dag lookup function
andresilva Oct 18, 2018
ae2d37e
progpow: read double words directly from the dag
andresilva Oct 18, 2018
e881d1f
progpow: inline some small functions
andresilva Oct 18, 2018
2f0c1a9
progpow: remove some bounds checking from the main loop
andresilva Oct 18, 2018
6c95cc8
progpow: remove unreachable match cases
andresilva Oct 18, 2018
2c28dc6
progpow: remove bounds check in keccak_f800_round
andresilva Oct 18, 2018
e22a9c3
progpow: fix ptr::swap
andresilva Oct 18, 2018
0e53756
progpow: force loop unroll in keccak_f800_round
andresilva Oct 18, 2018
7b77ab5
progpow: remove unnecessary branching in progpow_loop
andresilva Oct 18, 2018
9a9c710
progpow: force loop unroll in fill_mix
andresilva Oct 18, 2018
85c14cd
progpow: silence unused warning
andresilva Oct 18, 2018
a927d0b
progpow: dont run last keccak_f800_round out of the loop
andresilva Oct 19, 2018
2fc39b7
progpow: fix output of keccak_f800_short
andresilva Oct 19, 2018
e5c7d16
ethcore: support progpow in ethash engine
andresilva Oct 25, 2018
ecf937a
ethash: fix typo
andresilva Oct 25, 2018
04c5a8c
ethcore, ethash: fix tests
andresilva Oct 25, 2018
c5dc35a
json: fix ethash spec tests
andresilva Oct 26, 2018
a21993a
ethash: update quick_get_difficulty for progpow
andresilva Nov 8, 2018
9514419
ethash: drop light cache on progpow transition block
andresilva Nov 8, 2018
7c8873d
ethash: fix quick_get_difficulty tests
andresilva Nov 9, 2018
46aa1d4
progpow: update to spec v0.9.0
andresilva Dec 10, 2018
5f3c7be
progpow: update to spec v0.9.1
andresilva Dec 10, 2018
42b5194
progpow: update to spec v0.9.2
andresilva Dec 10, 2018
c8d074f
Merge branch 'master' into andre/progpow
andresilva Dec 10, 2018
af81890
ethash: rename progpow benchmarks
andresilva Dec 10, 2018
665e765
fix Cargo.lock bad merge
andresilva Dec 10, 2018
7afd3dc
Merge branch 'master' into andre/progpow
andresilva Dec 17, 2018
c7467b3
Merge branch 'master' into andre/progpow
andresilva Feb 18, 2019
4c00879
ethash: only export modules for benchmarks
andresilva Feb 18, 2019
89308fe
ethash: progpow: remove unsafe unchecked indexing
andresilva Feb 18, 2019
01bb1b5
ethash: create enum for pow algorithm
andresilva Feb 18, 2019
fea5b57
ethash: box the progpow cdag
andresilva Feb 19, 2019
0ca3119
ethash: skip slow progpow test vectors on ci
andresilva Feb 19, 2019
da02f9b
ethash: don't skip progpow test vectors
andresilva Feb 19, 2019
e30bd98
ethash: progpow: update copyright date
niklasad1 Feb 19, 2019
06551ce
ethcore: remove verification of ci-skip-tests on non-test builds
andresilva Feb 19, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ default = ["accounts"]
accounts = ["ethcore-accounts", "parity-rpc/accounts"]
miner-debug = ["ethcore/miner-debug"]
json-tests = ["ethcore/json-tests"]
ci-skip-issue = ["ethcore/ci-skip-issue"]
ci-skip-tests = ["ethcore/ci-skip-tests"]
test-heavy = ["ethcore/test-heavy"]
evm-debug = ["ethcore/evm-debug"]
evm-debug-tests = ["ethcore/evm-debug-tests"]
Expand Down
12 changes: 11 additions & 1 deletion ethash/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,19 @@ parking_lot = "0.7"
primal = "0.2.3"

[dev-dependencies]
tempdir = "0.3"
criterion = "0.2"
rustc-hex = "1.0"
serde_json = "1.0"
tempdir = "0.3"

[features]
default = []
bench = []

[[bench]]
name = "basic"
harness = false

[[bench]]
name = "progpow"
harness = false
28 changes: 14 additions & 14 deletions ethash/benches/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,38 +40,38 @@ criterion_main!(basic);
fn bench_light_compute_memmap(b: &mut Criterion) {
use std::env;

let builder = NodeCacheBuilder::new(OptimizeFor::Memory);
let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value());
let light = builder.light(&env::temp_dir(), 486382);

b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| light.compute(&HASH, NONCE)));
b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| light.compute(&HASH, NONCE, u64::max_value())));
}

fn bench_light_compute_memory(b: &mut Criterion) {
use std::env;

let builder = NodeCacheBuilder::new(OptimizeFor::Cpu);
let builder = NodeCacheBuilder::new(OptimizeFor::Cpu, u64::max_value());
let light = builder.light(&env::temp_dir(), 486382);

b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| light.compute(&HASH, NONCE)));
b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| light.compute(&HASH, NONCE, u64::max_value())));
}

fn bench_light_new_round_trip_memmap(b: &mut Criterion) {
use std::env;

b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| {
let builder = NodeCacheBuilder::new(OptimizeFor::Memory);
let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value());
let light = builder.light(&env::temp_dir(), 486382);
light.compute(&HASH, NONCE);
light.compute(&HASH, NONCE, u64::max_value());
}));
}

fn bench_light_new_round_trip_memory(b: &mut Criterion) {
use std::env;

b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| {
let builder = NodeCacheBuilder::new(OptimizeFor::Cpu);
let builder = NodeCacheBuilder::new(OptimizeFor::Cpu, u64::max_value());
let light = builder.light(&env::temp_dir(), 486382);
light.compute(&HASH, NONCE);
light.compute(&HASH, NONCE, u64::max_value());
}));
}

Expand All @@ -81,15 +81,15 @@ fn bench_light_from_file_round_trip_memory(b: &mut Criterion) {
let dir = env::temp_dir();
let height = 486382;
{
let builder = NodeCacheBuilder::new(OptimizeFor::Cpu);
let builder = NodeCacheBuilder::new(OptimizeFor::Cpu, u64::max_value());
let mut dummy = builder.light(&dir, height);
dummy.to_file().unwrap();
}

b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| {
let builder = NodeCacheBuilder::new(OptimizeFor::Cpu);
let builder = NodeCacheBuilder::new(OptimizeFor::Cpu, u64::max_value());
let light = builder.light_from_file(&dir, 486382).unwrap();
light.compute(&HASH, NONCE);
light.compute(&HASH, NONCE, u64::max_value());
}));
}

Expand All @@ -100,14 +100,14 @@ fn bench_light_from_file_round_trip_memmap(b: &mut Criterion) {
let height = 486382;

{
let builder = NodeCacheBuilder::new(OptimizeFor::Memory);
let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value());
let mut dummy = builder.light(&dir, height);
dummy.to_file().unwrap();
}

b.bench_function("bench_light_compute_memmap", move |b| b.iter(|| {
let builder = NodeCacheBuilder::new(OptimizeFor::Memory);
let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value());
let light = builder.light_from_file(&dir, 486382).unwrap();
light.compute(&HASH, NONCE);
light.compute(&HASH, NONCE, u64::max_value());
}));
}
86 changes: 86 additions & 0 deletions ethash/benches/progpow.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#[macro_use]
extern crate criterion;
extern crate ethash;
extern crate rustc_hex;
extern crate tempdir;

use criterion::Criterion;
use ethash::progpow;

use tempdir::TempDir;
use rustc_hex::FromHex;
use ethash::{NodeCacheBuilder, OptimizeFor};
use ethash::compute::light_compute;

fn bench_hashimoto_light(c: &mut Criterion) {
let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value());
let tempdir = TempDir::new("").unwrap();
let light = builder.light(&tempdir.path(), 1);
let h = FromHex::from_hex("c9149cc0386e689d789a1c2f3d5d169a61a6218ed30e74414dc736e442ef3d1f").unwrap();
let mut hash = [0; 32];
hash.copy_from_slice(&h);

c.bench_function("hashimoto_light", move |b| {
b.iter(|| light_compute(&light, &hash, 0))
});
}

fn bench_progpow_light(c: &mut Criterion) {
let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value());
let tempdir = TempDir::new("").unwrap();
let cache = builder.new_cache(tempdir.into_path(), 0);

let h = FromHex::from_hex("c9149cc0386e689d789a1c2f3d5d169a61a6218ed30e74414dc736e442ef3d1f").unwrap();
let mut hash = [0; 32];
hash.copy_from_slice(&h);

c.bench_function("progpow_light", move |b| {
b.iter(|| {
let c_dag = progpow::generate_cdag(cache.as_ref());
progpow::progpow(
hash,
0,
0,
cache.as_ref(),
&c_dag,
);
})
});
}

fn bench_progpow_optimal_light(c: &mut Criterion) {
let builder = NodeCacheBuilder::new(OptimizeFor::Memory, u64::max_value());
let tempdir = TempDir::new("").unwrap();
let cache = builder.new_cache(tempdir.into_path(), 0);
let c_dag = progpow::generate_cdag(cache.as_ref());

let h = FromHex::from_hex("c9149cc0386e689d789a1c2f3d5d169a61a6218ed30e74414dc736e442ef3d1f").unwrap();
let mut hash = [0; 32];
hash.copy_from_slice(&h);

c.bench_function("progpow_optimal_light", move |b| {
b.iter(|| {
progpow::progpow(
hash,
0,
0,
cache.as_ref(),
&c_dag,
);
})
});
}

fn bench_keccak_f800_long(c: &mut Criterion) {
c.bench_function("keccak_f800_long(0, 0, 0)", |b| {
b.iter(|| progpow::keccak_f800_long([0; 32], 0, [0; 8]))
});
}

criterion_group!(benches,
bench_hashimoto_light,
bench_progpow_light,
bench_progpow_optimal_light,
bench_keccak_f800_long,
);
criterion_main!(benches);
86 changes: 86 additions & 0 deletions ethash/res/progpow_testvectors.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
[
[
0,
"0000000000000000000000000000000000000000000000000000000000000000",
"0000000000000000",
"faeb1be51075b03a4ff44b335067951ead07a3b078539ace76fd56fc410557a3",
"63155f732f2bf556967f906155b510c917e48e99685ead76ea83f4eca03ab12b"
],
[
49,
"63155f732f2bf556967f906155b510c917e48e99685ead76ea83f4eca03ab12b",
"0000000006ff2c47",
"c789c1180f890ec555ff42042913465481e8e6bc512cb981e1c1108dc3f2227d",
"9e7248f20914913a73d80a70174c331b1d34f260535ac3631d770e656b5dd922"
],
[
50,
"9e7248f20914913a73d80a70174c331b1d34f260535ac3631d770e656b5dd922",
"00000000076e482e",
"c7340542c2a06b3a7dc7222635f7cd402abf8b528ae971ddac6bbe2b0c7cb518",
"de37e1824c86d35d154cf65a88de6d9286aec4f7f10c3fc9f0fa1bcc2687188d"
],
[
99,
"de37e1824c86d35d154cf65a88de6d9286aec4f7f10c3fc9f0fa1bcc2687188d",
"000000003917afab",
"f5e60b2c5bfddd136167a30cbc3c8dbdbd15a512257dee7964e0bc6daa9f8ba7",
"ac7b55e801511b77e11d52e9599206101550144525b5679f2dab19386f23dcce"
],
[
29950,
"ac7b55e801511b77e11d52e9599206101550144525b5679f2dab19386f23dcce",
"005d409dbc23a62a",
"07393d15805eb08ee6fc6cb3ad4ad1010533bd0ff92d6006850246829f18fd6e",
"e43d7e0bdc8a4a3f6e291a5ed790b9fa1a0948a2b9e33c844888690847de19f5"
],
[
29999,
"e43d7e0bdc8a4a3f6e291a5ed790b9fa1a0948a2b9e33c844888690847de19f5",
"005db5fa4c2a3d03",
"7551bddf977491da2f6cfc1679299544b23483e8f8ee0931c4c16a796558a0b8",
"d34519f72c97cae8892c277776259db3320820cb5279a299d0ef1e155e5c6454"
],
[
30000,
"d34519f72c97cae8892c277776259db3320820cb5279a299d0ef1e155e5c6454",
"005db8607994ff30",
"f1c2c7c32266af9635462e6ce1c98ebe4e7e3ecab7a38aaabfbf2e731e0fbff4",
"8b6ce5da0b06d18db7bd8492d9e5717f8b53e7e098d9fef7886d58a6e913ef64"
],
[
30049,
"8b6ce5da0b06d18db7bd8492d9e5717f8b53e7e098d9fef7886d58a6e913ef64",
"005e2e215a8ca2e7",
"57fe6a9fbf920b4e91deeb66cb0efa971e08229d1a160330e08da54af0689add",
"c2c46173481b9ced61123d2e293b42ede5a1b323210eb2a684df0874ffe09047"
],
[
30050,
"c2c46173481b9ced61123d2e293b42ede5a1b323210eb2a684df0874ffe09047",
"005e30899481055e",
"ba30c61cc5a2c74a5ecaf505965140a08f24a296d687e78720f0b48baf712f2d",
"ea42197eb2ba79c63cb5e655b8b1f612c5f08aae1a49ff236795a3516d87bc71"
],
[
30099,
"ea42197eb2ba79c63cb5e655b8b1f612c5f08aae1a49ff236795a3516d87bc71",
"005ea6aef136f88b",
"cfd5e46048cd133d40f261fe8704e51d3f497fc14203ac6a9ef6a0841780b1cd",
"49e15ba4bf501ce8fe8876101c808e24c69a859be15de554bf85dbc095491bd6"
],
[
59950,
"49e15ba4bf501ce8fe8876101c808e24c69a859be15de554bf85dbc095491bd6",
"02ebe0503bd7b1da",
"21511fbaa31fb9f5fc4998a754e97b3083a866f4de86fa7500a633346f56d773",
"f5c50ba5c0d6210ddb16250ec3efda178de857b2b1703d8d5403bd0f848e19cf"
],
[
59999,
"f5c50ba5c0d6210ddb16250ec3efda178de857b2b1703d8d5403bd0f848e19cf",
"02edb6275bd221e3",
"653eda37d337e39d311d22be9bbd3458d3abee4e643bee4a7280a6d08106ef98",
"341562d10d4afb706ec2c8d5537cb0c810de02b4ebb0a0eea5ae335af6fb2e88"
]
]
8 changes: 5 additions & 3 deletions ethash/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ pub struct NodeCacheBuilder {
// TODO: Remove this locking and just use an `Rc`?
seedhash: Arc<Mutex<SeedHashCompute>>,
optimize_for: OptimizeFor,
progpow_transition: u64,
}

// TODO: Abstract the "optimize for" logic
Expand All @@ -82,17 +83,18 @@ pub struct NodeCache {

impl NodeCacheBuilder {
pub fn light(&self, cache_dir: &Path, block_number: u64) -> Light {
Light::new_with_builder(self, cache_dir, block_number)
Light::new_with_builder(self, cache_dir, block_number, self.progpow_transition)
}

pub fn light_from_file(&self, cache_dir: &Path, block_number: u64) -> io::Result<Light> {
Light::from_file_with_builder(self, cache_dir, block_number)
Light::from_file_with_builder(self, cache_dir, block_number, self.progpow_transition)
}

pub fn new<T: Into<Option<OptimizeFor>>>(optimize_for: T) -> Self {
pub fn new<T: Into<Option<OptimizeFor>>>(optimize_for: T, progpow_transition: u64) -> Self {
NodeCacheBuilder {
seedhash: Arc::new(Mutex::new(SeedHashCompute::default())),
optimize_for: optimize_for.into().unwrap_or_default(),
progpow_transition
}
}

Expand Down
Loading