mirror of https://github.com/ethereum/go-ethereum
commit
1f26a1b863
@ -1,14 +1,23 @@ |
||||
# making our travis.yml play well with C++11 by obtaining g++4.8 |
||||
# Taken from this file: |
||||
# https://github.com/beark/ftl/blob/master/.travis.yml |
||||
language: go |
||||
go: |
||||
- 1.4.2 |
||||
|
||||
before_install: |
||||
# for g++4.8 and C++11 |
||||
- sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test |
||||
|
||||
# Set up go-ethereum |
||||
- sudo apt-get update -y -qq |
||||
- sudo apt-get install -yqq libgmp3-dev |
||||
- git clone --depth=10 https://github.com/ethereum/go-ethereum ${GOPATH}/src/github.com/ethereum/go-ethereum |
||||
# use canned dependencies from the go-ethereum repository |
||||
- export GOPATH=$GOPATH:$GOPATH/src/github.com/ethereum/go-ethereum/Godeps/_workspace/ |
||||
- echo $GOPATH |
||||
|
||||
install: |
||||
# need to explicitly request version 1.48 since by default we get 1.46 which does not work with C++11 |
||||
- sudo apt-get install -qq --yes --force-yes g++-4.8 |
||||
- sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 50 |
||||
# need to explicitly request version 1.48 since by default we get 1.46 which does not work with C++11 |
||||
- sudo apt-get install -qq wget cmake bash libboost-test1.48-dev libboost-system1.48-dev libboost-filesystem1.48-dev nodejs python-pip python-dev |
||||
- sudo apt-get install -qq wget cmake bash libboost-test1.48-dev libboost-system1.48-dev libboost-filesystem1.48-dev nodejs python-pip python-dev valgrind |
||||
- sudo pip install virtualenv -q |
||||
script: "./test/test.sh" |
||||
|
@ -1,7 +1,22 @@ |
||||
[![Build Status](https://travis-ci.org/ethereum/ethash.svg?branch=master)](https://travis-ci.org/ethereum/ethash) |
||||
|
||||
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/debris/ethash?branch=master&svg=true)](https://ci.appveyor.com/project/debris/ethash-nr37r/branch/master) |
||||
|
||||
# Ethash |
||||
|
||||
For details on this project, please see the Ethereum wiki: |
||||
https://github.com/ethereum/wiki/wiki/Ethash |
||||
|
||||
### Coding Style for C++ code: |
||||
|
||||
Follow the same exact style as in [cpp-ethereum](https://github.com/ethereum/cpp-ethereum/blob/develop/CodingStandards.txt) |
||||
|
||||
### Coding Style for C code: |
||||
|
||||
The main thing above all is code consistency. |
||||
|
||||
- Tabs for indentation. A tab is 4 spaces |
||||
- Try to stick to the [K&R](http://en.wikipedia.org/wiki/Indent_style#K.26R_style), |
||||
especially for the C code. |
||||
- Keep the line lengths reasonable. No hard limit on 80 characters but don't go further |
||||
than 110. Some people work with multiple buffers next to each other. |
||||
Make them like you :) |
||||
|
@ -0,0 +1,43 @@ |
||||
version: 1.0.0.{build} |
||||
|
||||
environment: |
||||
BOOST_ROOT: "c:/projects/ethash/deps/boost" |
||||
|
||||
branches: |
||||
only: |
||||
- master |
||||
- develop |
||||
|
||||
os: Windows Server 2012 R2 |
||||
|
||||
clone_folder: c:\projects\ethash |
||||
|
||||
#platform: Any CPU |
||||
#configuration: Debug |
||||
|
||||
install: |
||||
# by default, all script lines are interpreted as batch |
||||
|
||||
# scripts to run before build |
||||
before_build: |
||||
- echo "Downloading boost..." |
||||
- mkdir c:\projects\ethash\deps |
||||
- cd c:\projects\ethash\deps |
||||
- curl -O https://build.ethdev.com/builds/windows-precompiled/boost.tar.gz |
||||
- echo "Unzipping boost..." |
||||
- 7z x boost.tar.gz > nul |
||||
- 7z x boost.tar > nul |
||||
- ls |
||||
- echo "Running cmake..." |
||||
- cd c:\projects\ethash |
||||
- cmake . |
||||
|
||||
build: |
||||
project: ALL_BUILD.vcxproj # path to Visual Studio solution or project |
||||
|
||||
after_build: |
||||
- echo "Running tests..." |
||||
- cd c:\projects\ethash\test\c\Debug |
||||
- Test.exe |
||||
- echo "Finished!" |
||||
|
@ -0,0 +1,176 @@ |
||||
package ethash |
||||
|
||||
import ( |
||||
"bytes" |
||||
"crypto/rand" |
||||
"encoding/hex" |
||||
"log" |
||||
"math/big" |
||||
"os" |
||||
"sync" |
||||
"testing" |
||||
|
||||
"github.com/ethereum/go-ethereum/common" |
||||
) |
||||
|
||||
func init() { |
||||
// glog.SetV(6)
|
||||
// glog.SetToStderr(true)
|
||||
} |
||||
|
||||
type testBlock struct { |
||||
difficulty *big.Int |
||||
hashNoNonce common.Hash |
||||
nonce uint64 |
||||
mixDigest common.Hash |
||||
number uint64 |
||||
} |
||||
|
||||
func (b *testBlock) Difficulty() *big.Int { return b.difficulty } |
||||
func (b *testBlock) HashNoNonce() common.Hash { return b.hashNoNonce } |
||||
func (b *testBlock) Nonce() uint64 { return b.nonce } |
||||
func (b *testBlock) MixDigest() common.Hash { return b.mixDigest } |
||||
func (b *testBlock) NumberU64() uint64 { return b.number } |
||||
|
||||
var validBlocks = []*testBlock{ |
||||
// from proof of concept nine testnet, epoch 0
|
||||
{ |
||||
number: 22, |
||||
hashNoNonce: common.HexToHash("372eca2454ead349c3df0ab5d00b0b706b23e49d469387db91811cee0358fc6d"), |
||||
difficulty: big.NewInt(132416), |
||||
nonce: 0x495732e0ed7a801c, |
||||
}, |
||||
// from proof of concept nine testnet, epoch 1
|
||||
{ |
||||
number: 30001, |
||||
hashNoNonce: common.HexToHash("7e44356ee3441623bc72a683fd3708fdf75e971bbe294f33e539eedad4b92b34"), |
||||
difficulty: big.NewInt(1532671), |
||||
nonce: 0x318df1c8adef7e5e, |
||||
}, |
||||
// from proof of concept nine testnet, epoch 2
|
||||
{ |
||||
number: 60000, |
||||
hashNoNonce: common.HexToHash("5fc898f16035bf5ac9c6d9077ae1e3d5fc1ecc3c9fd5bee8bb00e810fdacbaa0"), |
||||
difficulty: big.NewInt(2467358), |
||||
nonce: 0x50377003e5d830ca, |
||||
}, |
||||
} |
||||
|
||||
func TestEthashVerifyValid(t *testing.T) { |
||||
eth := New() |
||||
for i, block := range validBlocks { |
||||
if !eth.Verify(block) { |
||||
t.Errorf("block %d (%x) did not validate.", i, block.hashNoNonce[:6]) |
||||
} |
||||
} |
||||
} |
||||
|
||||
func TestEthashConcurrentVerify(t *testing.T) { |
||||
eth, err := NewForTesting() |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
defer os.RemoveAll(eth.Full.Dir) |
||||
|
||||
block := &testBlock{difficulty: big.NewInt(10)} |
||||
nonce, _ := eth.Search(block, nil) |
||||
block.nonce = nonce |
||||
|
||||
// Verify the block concurrently to check for data races.
|
||||
var wg sync.WaitGroup |
||||
wg.Add(100) |
||||
for i := 0; i < 100; i++ { |
||||
go func() { |
||||
if !eth.Verify(block) { |
||||
t.Error("Block could not be verified") |
||||
} |
||||
wg.Done() |
||||
}() |
||||
} |
||||
wg.Wait() |
||||
} |
||||
|
||||
func TestEthashConcurrentSearch(t *testing.T) { |
||||
eth, err := NewForTesting() |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
eth.Turbo(true) |
||||
defer os.RemoveAll(eth.Full.Dir) |
||||
|
||||
// launch n searches concurrently.
|
||||
var ( |
||||
block = &testBlock{difficulty: big.NewInt(35000)} |
||||
nsearch = 10 |
||||
wg = new(sync.WaitGroup) |
||||
found = make(chan uint64) |
||||
stop = make(chan struct{}) |
||||
) |
||||
rand.Read(block.hashNoNonce[:]) |
||||
wg.Add(nsearch) |
||||
for i := 0; i < nsearch; i++ { |
||||
go func() { |
||||
nonce, _ := eth.Search(block, stop) |
||||
select { |
||||
case found <- nonce: |
||||
case <-stop: |
||||
} |
||||
wg.Done() |
||||
}() |
||||
} |
||||
|
||||
// wait for one of them to find the nonce
|
||||
nonce := <-found |
||||
// stop the others
|
||||
close(stop) |
||||
wg.Wait() |
||||
|
||||
if block.nonce = nonce; !eth.Verify(block) { |
||||
t.Error("Block could not be verified") |
||||
} |
||||
} |
||||
|
||||
func TestEthashSearchAcrossEpoch(t *testing.T) { |
||||
eth, err := NewForTesting() |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
defer os.RemoveAll(eth.Full.Dir) |
||||
|
||||
for i := epochLength - 40; i < epochLength+40; i++ { |
||||
block := &testBlock{number: i, difficulty: big.NewInt(90)} |
||||
rand.Read(block.hashNoNonce[:]) |
||||
nonce, _ := eth.Search(block, nil) |
||||
block.nonce = nonce |
||||
if !eth.Verify(block) { |
||||
t.Fatalf("Block could not be verified") |
||||
} |
||||
} |
||||
} |
||||
|
||||
func TestGetSeedHash(t *testing.T) { |
||||
seed0, err := GetSeedHash(0) |
||||
if err != nil { |
||||
t.Errorf("Failed to get seedHash for block 0: %v", err) |
||||
} |
||||
if bytes.Compare(seed0, make([]byte, 32)) != 0 { |
||||
log.Printf("seedHash for block 0 should be 0s, was: %v\n", seed0) |
||||
} |
||||
seed1, err := GetSeedHash(30000) |
||||
if err != nil { |
||||
t.Error(err) |
||||
} |
||||
|
||||
// From python:
|
||||
// > from pyethash import get_seedhash
|
||||
// > get_seedhash(30000)
|
||||
expectedSeed1, err := hex.DecodeString("290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563") |
||||
if err != nil { |
||||
t.Error(err) |
||||
} |
||||
|
||||
if bytes.Compare(seed1, expectedSeed1) != 0 { |
||||
log.Printf("seedHash for block 1 should be: %v,\nactual value: %v\n", expectedSeed1, seed1) |
||||
} |
||||
|
||||
} |
@ -0,0 +1,25 @@ |
||||
package ethash |
||||
|
||||
/* |
||||
#cgo CFLAGS: -std=gnu99 -Wall |
||||
#cgo windows CFLAGS: -mno-stack-arg-probe |
||||
#cgo LDFLAGS: -lm |
||||
|
||||
#include "src/libethash/internal.c" |
||||
#include "src/libethash/sha3.c" |
||||
#include "src/libethash/io.c" |
||||
|
||||
#ifdef _WIN32 |
||||
# include "src/libethash/util_win32.c" |
||||
# include "src/libethash/io_win32.c" |
||||
# include "src/libethash/mmap_win32.c" |
||||
#else |
||||
# include "src/libethash/io_posix.c" |
||||
#endif |
||||
|
||||
// 'gateway function' for calling back into go.
|
||||
extern int ethashGoCallback(unsigned); |
||||
int ethashGoCallback_cgo(unsigned percent) { return ethashGoCallback(percent); } |
||||
|
||||
*/ |
||||
import "C" |
2
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/CMakeLists.txt
generated
vendored
2
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/CMakeLists.txt
generated
vendored
143
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.cpp
generated
vendored
143
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.cpp
generated
vendored
26
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.h
generated
vendored
26
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash-cl/ethash_cl_miner.h
generated
vendored
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,47 @@ |
||||
/*
|
||||
This file is part of ethash. |
||||
|
||||
ethash is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU General Public License as published by |
||||
the Free Software Foundation, either version 3 of the License, or |
||||
(at your option) any later version. |
||||
|
||||
ethash is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU General Public License for more details. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with ethash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
/** @file mmap.h
|
||||
* @author Lefteris Karapetsas <lefteris@ethdev.com> |
||||
* @date 2015 |
||||
*/ |
||||
#pragma once |
||||
#if defined(__MINGW32__) || defined(_WIN32) |
||||
#include <sys/types.h> |
||||
|
||||
#define PROT_READ 0x1 |
||||
#define PROT_WRITE 0x2 |
||||
/* This flag is only available in WinXP+ */ |
||||
#ifdef FILE_MAP_EXECUTE |
||||
#define PROT_EXEC 0x4 |
||||
#else |
||||
#define PROT_EXEC 0x0 |
||||
#define FILE_MAP_EXECUTE 0 |
||||
#endif |
||||
|
||||
#define MAP_SHARED 0x01 |
||||
#define MAP_PRIVATE 0x02 |
||||
#define MAP_ANONYMOUS 0x20 |
||||
#define MAP_ANON MAP_ANONYMOUS |
||||
#define MAP_FAILED ((void *) -1) |
||||
|
||||
void* mmap(void* start, size_t length, int prot, int flags, int fd, off_t offset); |
||||
void munmap(void* addr, size_t length); |
||||
#else // posix, yay! ^_^
|
||||
#include <sys/mman.h> |
||||
#endif |
||||
|
||||
|
@ -0,0 +1,84 @@ |
||||
/* mmap() replacement for Windows
|
||||
* |
||||
* Author: Mike Frysinger <vapier@gentoo.org> |
||||
* Placed into the public domain |
||||
*/ |
||||
|
||||
/* References:
|
||||
* CreateFileMapping: http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx
|
||||
* CloseHandle: http://msdn.microsoft.com/en-us/library/ms724211(VS.85).aspx
|
||||
* MapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366761(VS.85).aspx
|
||||
* UnmapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366882(VS.85).aspx
|
||||
*/ |
||||
|
||||
#include <io.h> |
||||
#include <windows.h> |
||||
#include "mmap.h" |
||||
|
||||
#ifdef __USE_FILE_OFFSET64 |
||||
# define DWORD_HI(x) (x >> 32) |
||||
# define DWORD_LO(x) ((x) & 0xffffffff) |
||||
#else |
||||
# define DWORD_HI(x) (0) |
||||
# define DWORD_LO(x) (x) |
||||
#endif |
||||
|
||||
void* mmap(void* start, size_t length, int prot, int flags, int fd, off_t offset) |
||||
{ |
||||
if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC)) |
||||
return MAP_FAILED; |
||||
if (fd == -1) { |
||||
if (!(flags & MAP_ANON) || offset) |
||||
return MAP_FAILED; |
||||
} else if (flags & MAP_ANON) |
||||
return MAP_FAILED; |
||||
|
||||
DWORD flProtect; |
||||
if (prot & PROT_WRITE) { |
||||
if (prot & PROT_EXEC) |
||||
flProtect = PAGE_EXECUTE_READWRITE; |
||||
else |
||||
flProtect = PAGE_READWRITE; |
||||
} else if (prot & PROT_EXEC) { |
||||
if (prot & PROT_READ) |
||||
flProtect = PAGE_EXECUTE_READ; |
||||
else if (prot & PROT_EXEC) |
||||
flProtect = PAGE_EXECUTE; |
||||
} else |
||||
flProtect = PAGE_READONLY; |
||||
|
||||
off_t end = length + offset; |
||||
HANDLE mmap_fd, h; |
||||
if (fd == -1) |
||||
mmap_fd = INVALID_HANDLE_VALUE; |
||||
else |
||||
mmap_fd = (HANDLE)_get_osfhandle(fd); |
||||
h = CreateFileMapping(mmap_fd, NULL, flProtect, DWORD_HI(end), DWORD_LO(end), NULL); |
||||
if (h == NULL) |
||||
return MAP_FAILED; |
||||
|
||||
DWORD dwDesiredAccess; |
||||
if (prot & PROT_WRITE) |
||||
dwDesiredAccess = FILE_MAP_WRITE; |
||||
else |
||||
dwDesiredAccess = FILE_MAP_READ; |
||||
if (prot & PROT_EXEC) |
||||
dwDesiredAccess |= FILE_MAP_EXECUTE; |
||||
if (flags & MAP_PRIVATE) |
||||
dwDesiredAccess |= FILE_MAP_COPY; |
||||
void *ret = MapViewOfFile(h, dwDesiredAccess, DWORD_HI(offset), DWORD_LO(offset), length); |
||||
if (ret == NULL) { |
||||
ret = MAP_FAILED; |
||||
} |
||||
// since we are handling the file ourselves with fd, close the Windows Handle here
|
||||
CloseHandle(h); |
||||
return ret; |
||||
} |
||||
|
||||
void munmap(void* addr, size_t length) |
||||
{ |
||||
UnmapViewOfFile(addr); |
||||
} |
||||
|
||||
#undef DWORD_HI |
||||
#undef DWORD_LO |
14
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/sha3_cryptopp.cpp
generated
vendored
14
Godeps/_workspace/src/github.com/ethereum/ethash/src/libethash/sha3_cryptopp.cpp
generated
vendored
@ -1,82 +0,0 @@ |
||||
package ethashTest |
||||
|
||||
import ( |
||||
"bytes" |
||||
"crypto/rand" |
||||
"encoding/hex" |
||||
"log" |
||||
"math/big" |
||||
"testing" |
||||
|
||||
"github.com/ethereum/ethash" |
||||
"github.com/ethereum/go-ethereum/core" |
||||
"github.com/ethereum/go-ethereum/ethdb" |
||||
) |
||||
|
||||
func TestEthash(t *testing.T) { |
||||
seedHash := make([]byte, 32) |
||||
_, err := rand.Read(seedHash) |
||||
if err != nil { |
||||
panic(err) |
||||
} |
||||
|
||||
db, err := ethdb.NewMemDatabase() |
||||
if err != nil { |
||||
panic(err) |
||||
} |
||||
|
||||
blockProcessor, err := core.NewCanonical(5, db) |
||||
if err != nil { |
||||
panic(err) |
||||
} |
||||
|
||||
log.Println("Block Number: ", blockProcessor.ChainManager().CurrentBlock().Number()) |
||||
|
||||
e := ethash.New(blockProcessor.ChainManager()) |
||||
|
||||
miningHash := make([]byte, 32) |
||||
if _, err := rand.Read(miningHash); err != nil { |
||||
panic(err) |
||||
} |
||||
diff := big.NewInt(10000) |
||||
log.Println("difficulty", diff) |
||||
|
||||
nonce := uint64(0) |
||||
|
||||
ghash_full := e.FullHash(nonce, miningHash) |
||||
log.Printf("ethash full (on nonce): %x %x\n", ghash_full, nonce) |
||||
|
||||
ghash_light := e.LightHash(nonce, miningHash) |
||||
log.Printf("ethash light (on nonce): %x %x\n", ghash_light, nonce) |
||||
|
||||
if bytes.Compare(ghash_full, ghash_light) != 0 { |
||||
t.Errorf("full: %x, light: %x", ghash_full, ghash_light) |
||||
} |
||||
} |
||||
|
||||
func TestGetSeedHash(t *testing.T) { |
||||
seed0, err := ethash.GetSeedHash(0) |
||||
if err != nil { |
||||
t.Errorf("Failed to get seedHash for block 0: %v", err) |
||||
} |
||||
if bytes.Compare(seed0, []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) != 0 { |
||||
log.Printf("seedHash for block 0 should be 0s, was: %v\n", seed0) |
||||
} |
||||
seed1, err := ethash.GetSeedHash(30000) |
||||
if err != nil { |
||||
t.Error(err) |
||||
} |
||||
|
||||
// From python:
|
||||
// > from pyethash import get_seedhash
|
||||
// > get_seedhash(30000)
|
||||
expectedSeed1, err := hex.DecodeString("290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563") |
||||
if err != nil { |
||||
t.Error(err) |
||||
} |
||||
|
||||
if bytes.Compare(seed1, expectedSeed1) != 0 { |
||||
log.Printf("seedHash for block 1 should be: %v,\nactual value: %v\n", expectedSeed1, seed1) |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue