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 | ||||
| matrix: | ||||
|   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 | ||||
|       dist: trusty | ||||
|       sudo: required | ||||
|   | ||||
| @@ -182,13 +182,13 @@ func doInstall(cmdline []string) { | ||||
| 	// Check Go version. People regularly open issues about compilation | ||||
| 	// failure with outdated Go. This should save them the trouble. | ||||
| 	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 | ||||
| 		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("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.") | ||||
| 			os.Exit(1) | ||||
| 		} | ||||
|   | ||||
| @@ -19,6 +19,7 @@ package ethash | ||||
| import ( | ||||
| 	"encoding/binary" | ||||
| 	"hash" | ||||
| 	"math/big" | ||||
| 	"reflect" | ||||
| 	"runtime" | ||||
| 	"sync" | ||||
| @@ -47,6 +48,48 @@ const ( | ||||
| 	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 | ||||
| // reused between hash runs instead of requiring new ones to be created. | ||||
| 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" | ||||
| ) | ||||
|  | ||||
| // 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. | ||||
| func TestCacheGeneration(t *testing.T) { | ||||
| 	tests := []struct { | ||||
|   | ||||
| @@ -53,7 +53,6 @@ var ( | ||||
| 	errDuplicateUncle    = errors.New("duplicate uncle") | ||||
| 	errUncleIsAncestor   = errors.New("uncle is ancestor") | ||||
| 	errDanglingUncle     = errors.New("uncle's parent is not ancestor") | ||||
| 	errNonceOutOfRange   = errors.New("nonce out of range") | ||||
| 	errInvalidDifficulty = errors.New("non-positive difficulty") | ||||
| 	errInvalidMixDigest  = errors.New("invalid mix digest") | ||||
| 	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 { | ||||
| 		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 | ||||
| 	if header.Difficulty.Sign() <= 0 { | ||||
| 		return errInvalidDifficulty | ||||
| 	} | ||||
|  | ||||
| 	// Recompute the digest and PoW value and verify against the header | ||||
| 	number := header.Number.Uint64() | ||||
|  | ||||
| 	cache := ethash.cache(number) | ||||
| 	size := datasetSize(number) | ||||
| 	if ethash.config.PowMode == ModeTest { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user