Merge pull request #16207 from karalabe/drop-go1.7
travis, build, consensus: drop support for Go 1.7
This commit is contained in:
		
							
								
								
									
										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 { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user