forked from cerc-io/plugeth
Merge pull request #16207 from karalabe/drop-go1.7
travis, build, consensus: drop support for Go 1.7
This commit is contained in:
commit
8f43c97433
11
.travis.yml
11
.travis.yml
@ -3,17 +3,6 @@ go_import_path: github.com/ethereum/go-ethereum
|
|||||||
sudo: false
|
sudo: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- os: linux
|
|
||||||
dist: trusty
|
|
||||||
sudo: required
|
|
||||||
go: 1.7.x
|
|
||||||
script:
|
|
||||||
- sudo modprobe fuse
|
|
||||||
- sudo chmod 666 /dev/fuse
|
|
||||||
- sudo chown root:$USER /etc/fuse.conf
|
|
||||||
- go run build/ci.go install
|
|
||||||
- go run build/ci.go test -coverage
|
|
||||||
|
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: trusty
|
dist: trusty
|
||||||
sudo: required
|
sudo: required
|
||||||
|
@ -182,13 +182,13 @@ func doInstall(cmdline []string) {
|
|||||||
// Check Go version. People regularly open issues about compilation
|
// Check Go version. People regularly open issues about compilation
|
||||||
// failure with outdated Go. This should save them the trouble.
|
// failure with outdated Go. This should save them the trouble.
|
||||||
if !strings.Contains(runtime.Version(), "devel") {
|
if !strings.Contains(runtime.Version(), "devel") {
|
||||||
// Figure out the minor version number since we can't textually compare (1.10 < 1.7)
|
// Figure out the minor version number since we can't textually compare (1.10 < 1.8)
|
||||||
var minor int
|
var minor int
|
||||||
fmt.Sscanf(strings.TrimPrefix(runtime.Version(), "go1."), "%d", &minor)
|
fmt.Sscanf(strings.TrimPrefix(runtime.Version(), "go1."), "%d", &minor)
|
||||||
|
|
||||||
if minor < 7 {
|
if minor < 8 {
|
||||||
log.Println("You have Go version", runtime.Version())
|
log.Println("You have Go version", runtime.Version())
|
||||||
log.Println("go-ethereum requires at least Go version 1.7 and cannot")
|
log.Println("go-ethereum requires at least Go version 1.8 and cannot")
|
||||||
log.Println("be compiled with an earlier version. Please upgrade your Go installation.")
|
log.Println("be compiled with an earlier version. Please upgrade your Go installation.")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ package ethash
|
|||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"hash"
|
"hash"
|
||||||
|
"math/big"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
@ -47,6 +48,48 @@ const (
|
|||||||
loopAccesses = 64 // Number of accesses in hashimoto loop
|
loopAccesses = 64 // Number of accesses in hashimoto loop
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// cacheSize returns the size of the ethash verification cache that belongs to a certain
|
||||||
|
// block number.
|
||||||
|
func cacheSize(block uint64) uint64 {
|
||||||
|
epoch := int(block / epochLength)
|
||||||
|
if epoch < maxEpoch {
|
||||||
|
return cacheSizes[epoch]
|
||||||
|
}
|
||||||
|
return calcCacheSize(epoch)
|
||||||
|
}
|
||||||
|
|
||||||
|
// calcCacheSize calculates the cache size for epoch. The cache size grows linearly,
|
||||||
|
// however, we always take the highest prime below the linearly growing threshold in order
|
||||||
|
// to reduce the risk of accidental regularities leading to cyclic behavior.
|
||||||
|
func calcCacheSize(epoch int) uint64 {
|
||||||
|
size := cacheInitBytes + cacheGrowthBytes*uint64(epoch) - hashBytes
|
||||||
|
for !new(big.Int).SetUint64(size / hashBytes).ProbablyPrime(1) { // Always accurate for n < 2^64
|
||||||
|
size -= 2 * hashBytes
|
||||||
|
}
|
||||||
|
return size
|
||||||
|
}
|
||||||
|
|
||||||
|
// datasetSize returns the size of the ethash mining dataset that belongs to a certain
|
||||||
|
// block number.
|
||||||
|
func datasetSize(block uint64) uint64 {
|
||||||
|
epoch := int(block / epochLength)
|
||||||
|
if epoch < maxEpoch {
|
||||||
|
return datasetSizes[epoch]
|
||||||
|
}
|
||||||
|
return calcDatasetSize(epoch)
|
||||||
|
}
|
||||||
|
|
||||||
|
// calcDatasetSize calculates the dataset size for epoch. The dataset size grows linearly,
|
||||||
|
// however, we always take the highest prime below the linearly growing threshold in order
|
||||||
|
// to reduce the risk of accidental regularities leading to cyclic behavior.
|
||||||
|
func calcDatasetSize(epoch int) uint64 {
|
||||||
|
size := datasetInitBytes + datasetGrowthBytes*uint64(epoch) - mixBytes
|
||||||
|
for !new(big.Int).SetUint64(size / mixBytes).ProbablyPrime(1) { // Always accurate for n < 2^64
|
||||||
|
size -= 2 * mixBytes
|
||||||
|
}
|
||||||
|
return size
|
||||||
|
}
|
||||||
|
|
||||||
// hasher is a repetitive hasher allowing the same hash data structures to be
|
// hasher is a repetitive hasher allowing the same hash data structures to be
|
||||||
// reused between hash runs instead of requiring new ones to be created.
|
// reused between hash runs instead of requiring new ones to be created.
|
||||||
type hasher func(dest []byte, data []byte)
|
type hasher func(dest []byte, data []byte)
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
// Copyright 2017 The go-ethereum Authors
|
|
||||||
// This file is part of the go-ethereum library.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library 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 Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
// +build !go1.8
|
|
||||||
|
|
||||||
package ethash
|
|
||||||
|
|
||||||
// cacheSize calculates and returns the size of the ethash verification cache that
|
|
||||||
// belongs to a certain block number. The cache size grows linearly, however, we
|
|
||||||
// always take the highest prime below the linearly growing threshold in order to
|
|
||||||
// reduce the risk of accidental regularities leading to cyclic behavior.
|
|
||||||
func cacheSize(block uint64) uint64 {
|
|
||||||
// If we have a pre-generated value, use that
|
|
||||||
epoch := int(block / epochLength)
|
|
||||||
if epoch < maxEpoch {
|
|
||||||
return cacheSizes[epoch]
|
|
||||||
}
|
|
||||||
// We don't have a way to verify primes fast before Go 1.8
|
|
||||||
panic("fast prime testing unsupported in Go < 1.8")
|
|
||||||
}
|
|
||||||
|
|
||||||
// datasetSize calculates and returns the size of the ethash mining dataset that
|
|
||||||
// belongs to a certain block number. The dataset size grows linearly, however, we
|
|
||||||
// always take the highest prime below the linearly growing threshold in order to
|
|
||||||
// reduce the risk of accidental regularities leading to cyclic behavior.
|
|
||||||
func datasetSize(block uint64) uint64 {
|
|
||||||
// If we have a pre-generated value, use that
|
|
||||||
epoch := int(block / epochLength)
|
|
||||||
if epoch < maxEpoch {
|
|
||||||
return datasetSizes[epoch]
|
|
||||||
}
|
|
||||||
// We don't have a way to verify primes fast before Go 1.8
|
|
||||||
panic("fast prime testing unsupported in Go < 1.8")
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
// Copyright 2017 The go-ethereum Authors
|
|
||||||
// This file is part of the go-ethereum library.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library 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 Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
// +build go1.8
|
|
||||||
|
|
||||||
package ethash
|
|
||||||
|
|
||||||
import "math/big"
|
|
||||||
|
|
||||||
// cacheSize returns the size of the ethash verification cache that belongs to a certain
|
|
||||||
// block number.
|
|
||||||
func cacheSize(block uint64) uint64 {
|
|
||||||
epoch := int(block / epochLength)
|
|
||||||
if epoch < maxEpoch {
|
|
||||||
return cacheSizes[epoch]
|
|
||||||
}
|
|
||||||
return calcCacheSize(epoch)
|
|
||||||
}
|
|
||||||
|
|
||||||
// calcCacheSize calculates the cache size for epoch. The cache size grows linearly,
|
|
||||||
// however, we always take the highest prime below the linearly growing threshold in order
|
|
||||||
// to reduce the risk of accidental regularities leading to cyclic behavior.
|
|
||||||
func calcCacheSize(epoch int) uint64 {
|
|
||||||
size := cacheInitBytes + cacheGrowthBytes*uint64(epoch) - hashBytes
|
|
||||||
for !new(big.Int).SetUint64(size / hashBytes).ProbablyPrime(1) { // Always accurate for n < 2^64
|
|
||||||
size -= 2 * hashBytes
|
|
||||||
}
|
|
||||||
return size
|
|
||||||
}
|
|
||||||
|
|
||||||
// datasetSize returns the size of the ethash mining dataset that belongs to a certain
|
|
||||||
// block number.
|
|
||||||
func datasetSize(block uint64) uint64 {
|
|
||||||
epoch := int(block / epochLength)
|
|
||||||
if epoch < maxEpoch {
|
|
||||||
return datasetSizes[epoch]
|
|
||||||
}
|
|
||||||
return calcDatasetSize(epoch)
|
|
||||||
}
|
|
||||||
|
|
||||||
// calcDatasetSize calculates the dataset size for epoch. The dataset size grows linearly,
|
|
||||||
// however, we always take the highest prime below the linearly growing threshold in order
|
|
||||||
// to reduce the risk of accidental regularities leading to cyclic behavior.
|
|
||||||
func calcDatasetSize(epoch int) uint64 {
|
|
||||||
size := datasetInitBytes + datasetGrowthBytes*uint64(epoch) - mixBytes
|
|
||||||
for !new(big.Int).SetUint64(size / mixBytes).ProbablyPrime(1) { // Always accurate for n < 2^64
|
|
||||||
size -= 2 * mixBytes
|
|
||||||
}
|
|
||||||
return size
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
// Copyright 2017 The go-ethereum Authors
|
|
||||||
// This file is part of the go-ethereum library.
|
|
||||||
//
|
|
||||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// The go-ethereum library 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 Lesser General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Lesser General Public License
|
|
||||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
// +build go1.8
|
|
||||||
|
|
||||||
package ethash
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
// Tests whether the dataset size calculator works correctly by cross checking the
|
|
||||||
// hard coded lookup table with the value generated by it.
|
|
||||||
func TestSizeCalculations(t *testing.T) {
|
|
||||||
// Verify all the cache and dataset sizes from the lookup table.
|
|
||||||
for epoch, want := range cacheSizes {
|
|
||||||
if size := calcCacheSize(epoch); size != want {
|
|
||||||
t.Errorf("cache %d: cache size mismatch: have %d, want %d", epoch, size, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for epoch, want := range datasetSizes {
|
|
||||||
if size := calcDatasetSize(epoch); size != want {
|
|
||||||
t.Errorf("dataset %d: dataset size mismatch: have %d, want %d", epoch, size, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -30,6 +30,22 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Tests whether the dataset size calculator works correctly by cross checking the
|
||||||
|
// hard coded lookup table with the value generated by it.
|
||||||
|
func TestSizeCalculations(t *testing.T) {
|
||||||
|
// Verify all the cache and dataset sizes from the lookup table.
|
||||||
|
for epoch, want := range cacheSizes {
|
||||||
|
if size := calcCacheSize(epoch); size != want {
|
||||||
|
t.Errorf("cache %d: cache size mismatch: have %d, want %d", epoch, size, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for epoch, want := range datasetSizes {
|
||||||
|
if size := calcDatasetSize(epoch); size != want {
|
||||||
|
t.Errorf("dataset %d: dataset size mismatch: have %d, want %d", epoch, size, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Tests that verification caches can be correctly generated.
|
// Tests that verification caches can be correctly generated.
|
||||||
func TestCacheGeneration(t *testing.T) {
|
func TestCacheGeneration(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
@ -53,7 +53,6 @@ var (
|
|||||||
errDuplicateUncle = errors.New("duplicate uncle")
|
errDuplicateUncle = errors.New("duplicate uncle")
|
||||||
errUncleIsAncestor = errors.New("uncle is ancestor")
|
errUncleIsAncestor = errors.New("uncle is ancestor")
|
||||||
errDanglingUncle = errors.New("uncle's parent is not ancestor")
|
errDanglingUncle = errors.New("uncle's parent is not ancestor")
|
||||||
errNonceOutOfRange = errors.New("nonce out of range")
|
|
||||||
errInvalidDifficulty = errors.New("non-positive difficulty")
|
errInvalidDifficulty = errors.New("non-positive difficulty")
|
||||||
errInvalidMixDigest = errors.New("invalid mix digest")
|
errInvalidMixDigest = errors.New("invalid mix digest")
|
||||||
errInvalidPoW = errors.New("invalid proof-of-work")
|
errInvalidPoW = errors.New("invalid proof-of-work")
|
||||||
@ -474,18 +473,13 @@ func (ethash *Ethash) VerifySeal(chain consensus.ChainReader, header *types.Head
|
|||||||
if ethash.shared != nil {
|
if ethash.shared != nil {
|
||||||
return ethash.shared.VerifySeal(chain, header)
|
return ethash.shared.VerifySeal(chain, header)
|
||||||
}
|
}
|
||||||
// Sanity check that the block number is below the lookup table size (60M blocks)
|
|
||||||
number := header.Number.Uint64()
|
|
||||||
if number/epochLength >= maxEpoch {
|
|
||||||
// Go < 1.7 cannot calculate new cache/dataset sizes (no fast prime check)
|
|
||||||
return errNonceOutOfRange
|
|
||||||
}
|
|
||||||
// Ensure that we have a valid difficulty for the block
|
// Ensure that we have a valid difficulty for the block
|
||||||
if header.Difficulty.Sign() <= 0 {
|
if header.Difficulty.Sign() <= 0 {
|
||||||
return errInvalidDifficulty
|
return errInvalidDifficulty
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recompute the digest and PoW value and verify against the header
|
// Recompute the digest and PoW value and verify against the header
|
||||||
|
number := header.Number.Uint64()
|
||||||
|
|
||||||
cache := ethash.cache(number)
|
cache := ethash.cache(number)
|
||||||
size := datasetSize(number)
|
size := datasetSize(number)
|
||||||
if ethash.config.PowMode == ModeTest {
|
if ethash.config.PowMode == ModeTest {
|
||||||
|
Loading…
Reference in New Issue
Block a user