diff --git a/.gitignore b/.gitignore index f628db8e5e..64dce13a3a 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,5 @@ profile.cov /dashboard/assets/package-lock.json **/yarn-error.log + +/build/cache/ \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000000..e0e99a8292 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,51 @@ +# This file configures github.com/golangci/golangci-lint. + +run: + timeout: 3m + tests: true + # default is true. Enables skipping of directories: + # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ + skip-dirs-use-default: true + skip-files: + - core/genesis_alloc.go + +# TODO: Too many errors, turn on one by one +linters: + disable-all: true + enable: + - goimports + - typecheck + # - deadcode + # - goconst + # - govet + # - ineffassign + # - misspell + # - staticcheck + # - unconvert + # - unused + # - varcheck + +linters-settings: + gofmt: + simplify: true + goconst: + min-len: 3 # minimum length of string constant + min-occurrences: 6 # minimum number of occurrences + +issues: + exclude-rules: + - path: crypto/blake2b/ + linters: + - deadcode + - path: crypto/bn256/cloudflare + linters: + - deadcode + - path: p2p/discv5/ + linters: + - deadcode + - path: core/vm/instructions_test.go + linters: + - goconst + - path: cmd/faucet/ + linters: + - deadcode \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..018366fa74 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,36 @@ +language: go +go_import_path: github.com/ethereum/go-ethereum +sudo: false +jobs: + include: + # This builder only tests code linters on latest version of Go + - stage: lint + os: linux + dist: bionic + go: 1.16.x + env: + - lint + git: + submodules: false # avoid cloning ethereum/tests + script: + - go run build/ci.go lint + + # These builders run the tests + # - stage: build + # os: linux + # arch: amd64 + # dist: bionic + # go: 1.16.x + # env: + # - GO111MODULE=auto + # script: + # - go run build/ci.go test -coverage $TEST_PACKAGES + + # - stage: build + # os: linux + # dist: bionic + # go: 1.15.x + # env: + # - GO111MODULE=auto + # script: + # - go run build/ci.go test -coverage $TEST_PACKAGES \ No newline at end of file diff --git a/build/checksums.txt b/build/checksums.txt new file mode 100644 index 0000000000..e667b30ce6 --- /dev/null +++ b/build/checksums.txt @@ -0,0 +1,33 @@ +# This file contains sha256 checksums of optional build dependencies. + +ae4f6b6e2a1677d31817984655a762074b5356da50fb58722b99104870d43503 go1.16.4.src.tar.gz +18fe94775763db3878717393b6d41371b0b45206055e49b3838328120c977d13 go1.16.4.darwin-amd64.tar.gz +cb6b972cc42e669f3585c648198cd5b6f6d7a0811d413ad64b50c02ba06ccc3a go1.16.4.darwin-arm64.tar.gz +cd1b146ef6e9006f27dd99e9687773e7fef30e8c985b7d41bff33e955a3bb53a go1.16.4.linux-386.tar.gz +7154e88f5a8047aad4b80ebace58a059e36e7e2e4eb3b383127a28c711b4ff59 go1.16.4.linux-amd64.tar.gz +8b18eb05ddda2652d69ab1b1dd1f40dd731799f43c6a58b512ad01ae5b5bba21 go1.16.4.linux-arm64.tar.gz +a53391a800ddec749ee90d38992babb27b95cfb864027350c737b9aa8e069494 go1.16.4.linux-armv6l.tar.gz +e75c0b114a09eb5499874162b208931dc260de0fedaeedac8621bf263c974605 go1.16.4.windows-386.zip +d40139b7ade8a3008e3240a6f86fe8f899a9c465c917e11dac8758af216f5eb0 go1.16.4.windows-amd64.zip +7cf2bc8a175d6d656861165bfc554f92dc78d2abf5afe5631db3579555d97409 go1.16.4.freebsd-386.tar.gz +ccdd2b76de1941b60734408fda0d750aaa69330d8a07430eed4c56bdb3502f6f go1.16.4.freebsd-amd64.tar.gz +80cfac566e344096a8df8f37bbd21f89e76a6fbe601406565d71a87a665fc125 go1.16.4.linux-ppc64le.tar.gz +d6431881b3573dc29ecc24fbeab5e5ec25d8c9273aa543769c86a1a3bbac1ddf go1.16.4.linux-s390x.tar.gz + +7e9a47ab540aa3e8472fbf8120d28bed3b9d9cf625b955818e8bc69628d7187c golangci-lint-1.39.0-darwin-amd64.tar.gz +574daa2c9c299b01672a6daeb1873b5f12e413cdb6dc0e30f2ff163956778064 golangci-lint-1.39.0-darwin-arm64.tar.gz +6225f7014987324ab78e9b511f294e3f25be013728283c33918c67c8576d543e golangci-lint-1.39.0-freebsd-386.tar.gz +6b3e76e1e5eaf0159411c8e2727f8d533989d3bb19f10e9caa6e0b9619ee267d golangci-lint-1.39.0-freebsd-amd64.tar.gz +a301cacfff87ed9b00313d95278533c25a4527a06b040a17d969b4b7e1b8a90d golangci-lint-1.39.0-freebsd-armv7.tar.gz +25bfd96a29c3112f508d5e4fc860dbad7afce657233c343acfa20715717d51e7 golangci-lint-1.39.0-freebsd-armv6.tar.gz +9687e4ff15545cfc722b0e46107a94195166a505023b48a316579af25ad09505 golangci-lint-1.39.0-linux-armv7.tar.gz +a7fa7ab2bfc99cbe5e5bcbf5684f5a997f920afbbe2f253d2feb1001d5e3c8b3 golangci-lint-1.39.0-linux-armv6.tar.gz +c8f9634115beddb4ed9129c1f7ecd4c97c99d07aeef33e3707234097eeb51b7b golangci-lint-1.39.0-linux-mips64le.tar.gz +d1234c213b74751f1af413302dde0e9a6d4d29aecef034af7abb07dc1b6e887f golangci-lint-1.39.0-linux-arm64.tar.gz +df25d9267168323b163147acb823ab0215a8a3bb6898a4a9320afdfedde66817 golangci-lint-1.39.0-linux-386.tar.gz +1767e75fba357b7651b1a796d38453558f371c60af805505ec99e166908c04b5 golangci-lint-1.39.0-linux-ppc64le.tar.gz +25fd75bf3186b3d930ecae10185689968fd18fd8fa6f9f555d6beb04348c20f6 golangci-lint-1.39.0-linux-s390x.tar.gz +3a73aa7468087caa62673c8adea99b4e4dff846dc72707222db85f8679b40cbf golangci-lint-1.39.0-linux-amd64.tar.gz +578caceccf81739bda67dbfec52816709d03608c6878888ecdc0e186a094a41b golangci-lint-1.39.0-linux-mips64.tar.gz +494b66ba0e32c8ddf6c4f6b1d05729b110900f6017eda943057e43598c17d7a8 golangci-lint-1.39.0-windows-386.zip +52ec2e13a3cbb47147244dff8cfc35103563deb76e0459133058086fc35fb2c7 golangci-lint-1.39.0-windows-amd64.zip diff --git a/build/ci.go b/build/ci.go index ea5ada3781..22cbf4dee2 100644 --- a/build/ci.go +++ b/build/ci.go @@ -239,39 +239,40 @@ func doTest(cmdline []string) { build.MustRun(gotest) } -// runs gometalinter on requested packages +// doLint runs golangci-lint on requested packages. func doLint(cmdline []string) { + var ( + cachedir = flag.String("cachedir", "./build/cache", "directory for caching golangci-lint binary.") + ) flag.CommandLine.Parse(cmdline) packages := []string{"./..."} if len(flag.CommandLine.Args()) > 0 { packages = flag.CommandLine.Args() } - // Get metalinter and install all supported linters - build.MustRun(goTool("get", "gopkg.in/alecthomas/gometalinter.v2")) - build.MustRunCommand(filepath.Join(GOBIN, "gometalinter.v2"), "--install") - // Run fast linters batched together - configs := []string{ - "--vendor", - "--tests", - "--deadline=2m", - "--disable-all", - "--enable=goimports", - "--enable=varcheck", - "--enable=vet", - "--enable=gofmt", - "--enable=misspell", - "--enable=goconst", - "--min-occurrences=6", // for goconst - } - build.MustRunCommand(filepath.Join(GOBIN, "gometalinter.v2"), append(configs, packages...)...) + linter := downloadLinter(*cachedir) + lflags := []string{"run", "--config", ".golangci.yml"} + build.MustRunCommand(linter, append(lflags, packages...)...) + fmt.Println("You have achieved perfection.") - // Run slow linters one by one - for _, linter := range []string{"unconvert", "gosimple"} { - configs = []string{"--vendor", "--tests", "--deadline=10m", "--disable-all", "--enable=" + linter} - build.MustRunCommand(filepath.Join(GOBIN, "gometalinter.v2"), append(configs, packages...)...) +} + +// downloadLinter downloads and unpacks golangci-lint. +func downloadLinter(cachedir string) string { + const version = "1.39.0" + + csdb := build.MustLoadChecksums("build/checksums.txt") + base := fmt.Sprintf("golangci-lint-%s-%s-%s", version, runtime.GOOS, runtime.GOARCH) + url := fmt.Sprintf("https://github.com/golangci/golangci-lint/releases/download/v%s/%s.tar.gz", version, base) + archivePath := filepath.Join(cachedir, base+".tar.gz") + if err := csdb.DownloadFile(url, archivePath); err != nil { + log.Fatal(err) } + if err := build.ExtractArchive(archivePath, cachedir); err != nil { + log.Fatal(err) + } + return filepath.Join(cachedir, base, "golangci-lint") } // Cross compilation diff --git a/cmd/XDC/usage.go b/cmd/XDC/usage.go index 7d1bd18a2d..afed20617d 100644 --- a/cmd/XDC/usage.go +++ b/cmd/XDC/usage.go @@ -216,7 +216,7 @@ var AppHelpFlagGroups = []flagGroup{ // }, //}, { - Name: "LOGGING AND DEBUGGING", + Name: "LOGGING AND DEBUGGING", Flags: append([]cli.Flag{ //utils.FakePoWFlag, //utils.NoCompactionFlag, diff --git a/cmd/gc/main.go b/cmd/gc/main.go index 746a362767..4964c9f167 100644 --- a/cmd/gc/main.go +++ b/cmd/gc/main.go @@ -18,7 +18,7 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" - "github.com/hashicorp/golang-lru" + lru "github.com/hashicorp/golang-lru" "github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb/util" ) @@ -56,11 +56,11 @@ func main() { head := rawdb.ReadHeadBlockHash(lddb) headNumber := rawdb.ReadHeaderNumber(lddb, head) if headNumber == nil { - fmt.Println("Unable to retrieve header number for block ", head); + fmt.Println("Unable to retrieve header number for block ", head) } currentHeader := rawdb.ReadHeader(lddb, head, *headNumber) if currentHeader == nil { - fmt.Println("Unable to retrieve header number for block ", head); + fmt.Println("Unable to retrieve header number for block ", head) } tridb := trie.NewDatabase(lddb) catchEventInterupt(lddb.LDB()) diff --git a/cmd/puppeth/wizard_genesis.go b/cmd/puppeth/wizard_genesis.go index 3f2edad759..ea77881634 100644 --- a/cmd/puppeth/wizard_genesis.go +++ b/cmd/puppeth/wizard_genesis.go @@ -304,13 +304,13 @@ func (w *wizard) makeGenesis() { contractBackend.ForEachStorageAt(ctx, multiSignWalletTeamAddr, nil, f) // Team balance. balance := big.NewInt(0) // 20 billion - balance.Add(balance, big.NewInt(30*1000*1000)) - balance.Mul(balance, big.NewInt(1000000000000000000)) - subBalance := big.NewInt(0) // i * 50k - subBalance.Add(subBalance, big.NewInt(int64(len(signers))*10*1000*1000)) - subBalance.Mul(subBalance, big.NewInt(1000000000000000000)) - balance.Sub(balance, subBalance) // 12m - i * 50k - genesis.Alloc[common.HexToAddress(common.TeamAddr)] = core.GenesisAccount{ + balance.Add(balance, big.NewInt(30*1000*1000)) + balance.Mul(balance, big.NewInt(1000000000000000000)) + subBalance := big.NewInt(0) // i * 50k + subBalance.Add(subBalance, big.NewInt(int64(len(signers))*10*1000*1000)) + subBalance.Mul(subBalance, big.NewInt(1000000000000000000)) + balance.Sub(balance, subBalance) // 12m - i * 50k + genesis.Alloc[common.HexToAddress(common.TeamAddr)] = core.GenesisAccount{ Balance: balance, Code: code, Storage: storage, diff --git a/cmd/swarm/access_test.go b/cmd/swarm/access_test.go index d8d8e182ce..eef98403a5 100644 --- a/cmd/swarm/access_test.go +++ b/cmd/swarm/access_test.go @@ -26,6 +26,7 @@ import ( gorand "math/rand" "net/http" "os" + //"runtime" "strings" "testing" diff --git a/cmd/swarm/upload_test.go b/cmd/swarm/upload_test.go index 60dd245e1e..dd6c8e3034 100644 --- a/cmd/swarm/upload_test.go +++ b/cmd/swarm/upload_test.go @@ -25,6 +25,7 @@ import ( "os" "path" "path/filepath" + //"runtime" "strings" "testing" diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index a00ddd3978..f54f94b020 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -33,8 +33,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/fdlimit" "github.com/ethereum/go-ethereum/consensus" - "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/consensus/XDPoS" + "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/vm" diff --git a/common/hexutil/json.go b/common/hexutil/json.go index ac12ce14cf..74a11d5931 100644 --- a/common/hexutil/json.go +++ b/common/hexutil/json.go @@ -296,7 +296,7 @@ func checkText(input []byte, wantPrefix bool) ([]byte, error) { if bytesHaveXDCPrefix(input) { input = input[3:] } else if bytesHave0xPrefix(input) { - input = input[2:] + input = input[2:] } else if wantPrefix { return nil, ErrMissingPrefix } diff --git a/common/types.go b/common/types.go index a70b87f9b6..8d098a36bc 100644 --- a/common/types.go +++ b/common/types.go @@ -33,7 +33,7 @@ import ( // Lengths of hashes and addresses in bytes. const ( // HashLength is the expected length of the hash - HashLength = 32 + HashLength = 32 // AddressLength is the expected length of the address AddressLength = 20 MasternodeVotingSMC = "xdc0000000000000000000000000000000000000088" diff --git a/consensus/XDPoS/XDPoS.go b/consensus/XDPoS/XDPoS.go index 72649d536d..97be5cb81f 100644 --- a/consensus/XDPoS/XDPoS.go +++ b/consensus/XDPoS/XDPoS.go @@ -45,7 +45,7 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" - "github.com/hashicorp/golang-lru" + lru "github.com/hashicorp/golang-lru" "golang.org/x/crypto/sha3" ) @@ -219,7 +219,7 @@ func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, er // Ethereum testnet following the Ropsten attacks. type XDPoS struct { config *params.XDPoSConfig // Consensus engine configuration parameters - db ethdb.Database // Database to store and retrieve snapshot checkpoints + db ethdb.Database // Database to store and retrieve snapshot checkpoints recents *lru.ARCCache // Snapshots for recent block to speed up reorgs signatures *lru.ARCCache // Signatures of recent blocks to speed up mining @@ -862,7 +862,7 @@ func (c *XDPoS) Prepare(chain consensus.ChainReader, header *types.Header) error // Ensure the timestamp has the correct delay - header.Time = parent.Time+ c.config.Period + header.Time = parent.Time + c.config.Period if int64(header.Time) < time.Now().Unix() { header.Time = uint64(time.Now().Unix()) } @@ -936,7 +936,7 @@ func (c *XDPoS) Authorize(signer common.Address, signFn clique.SignerFn) { // Seal implements consensus.Engine, attempting to create a sealed block using // the local signing credentials. -func (c *XDPoS) Seal(chain consensus.ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) (error) { +func (c *XDPoS) Seal(chain consensus.ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { header := block.Header() // Sealing the genesis block is not supported diff --git a/consensus/XDPoS/XDPoS_test.go b/consensus/XDPoS/XDPoS_test.go index 22bea0e450..aae3987799 100644 --- a/consensus/XDPoS/XDPoS_test.go +++ b/consensus/XDPoS/XDPoS_test.go @@ -76,11 +76,11 @@ func TestCompareSignersLists(t *testing.T) { t.Error("Failed with empty list") } if !compareSignersLists([]common.Address{common.BytesToAddress([]byte("cccccccccccccccccccccccccccccccccccccccc"))}, - []common.Address{common.BytesToAddress([]byte("cccccccccccccccccccccccccccccccccccccccc"))}) { + []common.Address{common.BytesToAddress([]byte("cccccccccccccccccccccccccccccccccccccccc"))}) { t.Error("Failed with list has only one signer") } if compareSignersLists([]common.Address{common.BytesToAddress([]byte("aaaaaaaaaaaaaaaa"))}, - []common.Address{common.BytesToAddress([]byte("cccccccccccccccccccccccccccccccccccccccc"))}) { + []common.Address{common.BytesToAddress([]byte("cccccccccccccccccccccccccccccccccccccccc"))}) { t.Error("Failed with list has only one signer") } } diff --git a/consensus/XDPoS/api.go b/consensus/XDPoS/api.go index 612632a182..72fa392d41 100644 --- a/consensus/XDPoS/api.go +++ b/consensus/XDPoS/api.go @@ -26,7 +26,7 @@ import ( // mechanisms of the proof-of-authority scheme. type API struct { chain consensus.ChainReader - XDPoS *XDPoS + XDPoS *XDPoS } // GetSnapshot retrieves the state snapshot at a given block. diff --git a/contracts/blocksigner/blocksigner.go b/contracts/blocksigner/blocksigner.go index 557045f45c..724dddbf90 100644 --- a/contracts/blocksigner/blocksigner.go +++ b/contracts/blocksigner/blocksigner.go @@ -16,10 +16,11 @@ package blocksigner import ( + "math/big" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/contracts/blocksigner/contract" - "math/big" ) type BlockSigner struct { diff --git a/contracts/blocksigner/blocksigner_test.go b/contracts/blocksigner/blocksigner_test.go index 291de80c93..8ca1140f28 100644 --- a/contracts/blocksigner/blocksigner_test.go +++ b/contracts/blocksigner/blocksigner_test.go @@ -21,12 +21,13 @@ import ( "testing" "time" + "math/rand" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/crypto" - "math/rand" ) var ( diff --git a/contracts/multisigwallet/multisigwallet.go b/contracts/multisigwallet/multisigwallet.go index e899b9ac0c..fd42811192 100644 --- a/contracts/multisigwallet/multisigwallet.go +++ b/contracts/multisigwallet/multisigwallet.go @@ -16,10 +16,11 @@ package multisigwallet import ( + "math/big" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/contracts/multisigwallet/contract" - "math/big" ) type MultiSigWallet struct { diff --git a/contracts/utils_test.go b/contracts/utils_test.go index 0bf5589639..34e7d1279e 100644 --- a/contracts/utils_test.go +++ b/contracts/utils_test.go @@ -19,6 +19,11 @@ import ( "bytes" "context" "crypto/ecdsa" + "math/big" + "math/rand" + "testing" + "time" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/common" @@ -27,10 +32,6 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "math/big" - "math/rand" - "testing" - "time" ) var ( diff --git a/core/headerchain.go b/core/headerchain.go index 896afd9bbf..8ce51de760 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -33,7 +33,7 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" - "github.com/hashicorp/golang-lru" + lru "github.com/hashicorp/golang-lru" ) const ( diff --git a/core/state_processor.go b/core/state_processor.go index c9514cb88f..8a34641642 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -17,6 +17,9 @@ package core import ( + "runtime" + "sync" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/misc" @@ -26,10 +29,6 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" ) -import ( - "runtime" - "sync" -) // StateProcessor is a basic Processor, which takes care of transitioning // state from one point to another. diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go index 588ef9ec3d..9340a8b790 100644 --- a/core/tx_pool_test.go +++ b/core/tx_pool_test.go @@ -849,8 +849,10 @@ func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) { // // This logic should not hold for local transactions, unless the local tracking // mechanism is disabled. -func TestTransactionQueueTimeLimiting(t *testing.T) { testTransactionQueueTimeLimiting(t, false) } -func TestTransactionQueueTimeLimitingNoLocals(t *testing.T) { testTransactionQueueTimeLimiting(t, true) } +func TestTransactionQueueTimeLimiting(t *testing.T) { testTransactionQueueTimeLimiting(t, false) } +func TestTransactionQueueTimeLimitingNoLocals(t *testing.T) { + testTransactionQueueTimeLimiting(t, true) +} func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) { // Reduce the eviction interval to a testable amount @@ -956,8 +958,10 @@ func TestTransactionPendingLimiting(t *testing.T) { // Tests that the transaction limits are enforced the same way irrelevant whether // the transactions are added one by one or in batches. -func TestTransactionQueueLimitingEquivalency(t *testing.T) { testTransactionLimitingEquivalency(t, 1) } -func TestTransactionPendingLimitingEquivalency(t *testing.T) { testTransactionLimitingEquivalency(t, 0) } +func TestTransactionQueueLimitingEquivalency(t *testing.T) { testTransactionLimitingEquivalency(t, 1) } +func TestTransactionPendingLimitingEquivalency(t *testing.T) { + testTransactionLimitingEquivalency(t, 0) +} func testTransactionLimitingEquivalency(t *testing.T, origin uint64) { t.Parallel() diff --git a/core/types/block_test.go b/core/types/block_test.go index 923bc64fe5..cb9100277f 100644 --- a/core/types/block_test.go +++ b/core/types/block_test.go @@ -21,9 +21,10 @@ import ( "testing" "bytes" + "reflect" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/rlp" - "reflect" ) // from bcValidBlockTest.json, "SimpleTx" diff --git a/crypto/bn256/bn256_fast.go b/crypto/bn256/bn256_fast.go index 5c081493b0..aab969eddc 100644 --- a/crypto/bn256/bn256_fast.go +++ b/crypto/bn256/bn256_fast.go @@ -7,7 +7,7 @@ // Package bn256 implements the Optimal Ate pairing over a 256-bit Barreto-Naehrig curve. package bn256 -import "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare" +import bn256 "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare" // G1 is an abstract cyclic group. The zero value is suitable for use as the // output of an operation, but cannot be used as an input. diff --git a/eth/backend.go b/eth/backend.go index 7028b30a9b..7e8b2b66ab 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -20,22 +20,24 @@ package eth import ( "errors" "fmt" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/eth/filters" - "github.com/ethereum/go-ethereum/rlp" "math/big" "runtime" "sync" "sync/atomic" "time" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/eth/filters" + "github.com/ethereum/go-ethereum/rlp" + "bytes" + "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" - "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/consensus/XDPoS" + "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/contracts" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/bloombits" diff --git a/eth/backend_test.go b/eth/backend_test.go index 28d889f055..f5c699abe2 100644 --- a/eth/backend_test.go +++ b/eth/backend_test.go @@ -1,9 +1,10 @@ package eth import ( - "github.com/ethereum/go-ethereum/params" "math/big" "testing" + + "github.com/ethereum/go-ethereum/params" ) func TestRewardInflation(t *testing.T) { diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index 9c35e69b38..10ca82cb00 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -428,12 +428,14 @@ func assertOwnForkedChain(t *testing.T, tester *downloadTester, common int, leng // Tests that simple synchronization against a canonical chain works correctly. // In this test common ancestor lookup should be short circuited and not require // binary searching. -func TestCanonicalSynchronisation62(t *testing.T) { testCanonicalSynchronisation(t, 62, FullSync) } -func TestCanonicalSynchronisation63Full(t *testing.T) { testCanonicalSynchronisation(t, 63, FullSync) } -func TestCanonicalSynchronisation63Fast(t *testing.T) { testCanonicalSynchronisation(t, 63, FastSync) } -func TestCanonicalSynchronisation64Full(t *testing.T) { testCanonicalSynchronisation(t, 64, FullSync) } -func TestCanonicalSynchronisation64Fast(t *testing.T) { testCanonicalSynchronisation(t, 64, FastSync) } -func TestCanonicalSynchronisation64Light(t *testing.T) { testCanonicalSynchronisation(t, 64, LightSync) } +func TestCanonicalSynchronisation62(t *testing.T) { testCanonicalSynchronisation(t, 62, FullSync) } +func TestCanonicalSynchronisation63Full(t *testing.T) { testCanonicalSynchronisation(t, 63, FullSync) } +func TestCanonicalSynchronisation63Fast(t *testing.T) { testCanonicalSynchronisation(t, 63, FastSync) } +func TestCanonicalSynchronisation64Full(t *testing.T) { testCanonicalSynchronisation(t, 64, FullSync) } +func TestCanonicalSynchronisation64Fast(t *testing.T) { testCanonicalSynchronisation(t, 64, FastSync) } +func TestCanonicalSynchronisation64Light(t *testing.T) { + testCanonicalSynchronisation(t, 64, LightSync) +} func testCanonicalSynchronisation(t *testing.T, protocol int, mode SyncMode) { t.Parallel() diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go index 0991459a02..855bf2a914 100644 --- a/eth/fetcher/fetcher.go +++ b/eth/fetcher/fetcher.go @@ -19,10 +19,11 @@ package fetcher import ( "errors" - "github.com/hashicorp/golang-lru" "math/rand" "time" + lru "github.com/hashicorp/golang-lru" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/prque" "github.com/ethereum/go-ethereum/consensus" diff --git a/eth/handler.go b/eth/handler.go index 94d6cdff71..5eba905e6e 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -20,13 +20,14 @@ import ( "encoding/json" "errors" "fmt" - "github.com/hashicorp/golang-lru" "math" "math/big" "sync" "sync/atomic" "time" + lru "github.com/hashicorp/golang-lru" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core" @@ -794,7 +795,7 @@ func (pm *ProtocolManager) minedBroadcastLoop() { // automatically stops if unsubscribe for obj := range pm.minedBlockSub.Chan() { if ev, ok := obj.Data.(core.NewMinedBlockEvent); ok { - pm.BroadcastBlock(ev.Block, true) // First propagate block to peers + pm.BroadcastBlock(ev.Block, true) // First propagate block to peers //pm.BroadcastBlock(ev.Block, false) // Only then announce to the rest } } diff --git a/internal/build/archive.go b/internal/build/archive.go new file mode 100644 index 0000000000..8b3ac23d1d --- /dev/null +++ b/internal/build/archive.go @@ -0,0 +1,288 @@ +// Copyright 2016 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 . + +package build + +import ( + "archive/tar" + "archive/zip" + "compress/gzip" + "fmt" + "io" + "os" + "path/filepath" + "strings" +) + +type Archive interface { + // Directory adds a new directory entry to the archive and sets the + // directory for subsequent calls to Header. + Directory(name string) error + + // Header adds a new file to the archive. The file is added to the directory + // set by Directory. The content of the file must be written to the returned + // writer. + Header(os.FileInfo) (io.Writer, error) + + // Close flushes the archive and closes the underlying file. + Close() error +} + +func NewArchive(file *os.File) (Archive, string) { + switch { + case strings.HasSuffix(file.Name(), ".zip"): + return NewZipArchive(file), strings.TrimSuffix(file.Name(), ".zip") + case strings.HasSuffix(file.Name(), ".tar.gz"): + return NewTarballArchive(file), strings.TrimSuffix(file.Name(), ".tar.gz") + default: + return nil, "" + } +} + +// AddFile appends an existing file to an archive. +func AddFile(a Archive, file string) error { + fd, err := os.Open(file) + if err != nil { + return err + } + defer fd.Close() + fi, err := fd.Stat() + if err != nil { + return err + } + w, err := a.Header(fi) + if err != nil { + return err + } + if _, err := io.Copy(w, fd); err != nil { + return err + } + return nil +} + +// WriteArchive creates an archive containing the given files. +func WriteArchive(name string, files []string) (err error) { + archfd, err := os.Create(name) + if err != nil { + return err + } + + defer func() { + archfd.Close() + // Remove the half-written archive on failure. + if err != nil { + os.Remove(name) + } + }() + archive, basename := NewArchive(archfd) + if archive == nil { + return fmt.Errorf("unknown archive extension") + } + fmt.Println(name) + if err := archive.Directory(basename); err != nil { + return err + } + for _, file := range files { + fmt.Println(" +", filepath.Base(file)) + if err := AddFile(archive, file); err != nil { + return err + } + } + return archive.Close() +} + +type ZipArchive struct { + dir string + zipw *zip.Writer + file io.Closer +} + +func NewZipArchive(w io.WriteCloser) Archive { + return &ZipArchive{"", zip.NewWriter(w), w} +} + +func (a *ZipArchive) Directory(name string) error { + a.dir = name + "/" + return nil +} + +func (a *ZipArchive) Header(fi os.FileInfo) (io.Writer, error) { + head, err := zip.FileInfoHeader(fi) + if err != nil { + return nil, fmt.Errorf("can't make zip header: %v", err) + } + head.Name = a.dir + head.Name + head.Method = zip.Deflate + w, err := a.zipw.CreateHeader(head) + if err != nil { + return nil, fmt.Errorf("can't add zip header: %v", err) + } + return w, nil +} + +func (a *ZipArchive) Close() error { + if err := a.zipw.Close(); err != nil { + return err + } + return a.file.Close() +} + +type TarballArchive struct { + dir string + tarw *tar.Writer + gzw *gzip.Writer + file io.Closer +} + +func NewTarballArchive(w io.WriteCloser) Archive { + gzw := gzip.NewWriter(w) + tarw := tar.NewWriter(gzw) + return &TarballArchive{"", tarw, gzw, w} +} + +func (a *TarballArchive) Directory(name string) error { + a.dir = name + "/" + return a.tarw.WriteHeader(&tar.Header{ + Name: a.dir, + Mode: 0755, + Typeflag: tar.TypeDir, + }) +} + +func (a *TarballArchive) Header(fi os.FileInfo) (io.Writer, error) { + head, err := tar.FileInfoHeader(fi, "") + if err != nil { + return nil, fmt.Errorf("can't make tar header: %v", err) + } + head.Name = a.dir + head.Name + if err := a.tarw.WriteHeader(head); err != nil { + return nil, fmt.Errorf("can't add tar header: %v", err) + } + return a.tarw, nil +} + +func (a *TarballArchive) Close() error { + if err := a.tarw.Close(); err != nil { + return err + } + if err := a.gzw.Close(); err != nil { + return err + } + return a.file.Close() +} + +// ExtractArchive unpacks a .zip or .tar.gz archive to the destination directory. +func ExtractArchive(archive string, dest string) error { + ar, err := os.Open(archive) + if err != nil { + return err + } + defer ar.Close() + + switch { + case strings.HasSuffix(archive, ".tar.gz"): + return extractTarball(ar, dest) + case strings.HasSuffix(archive, ".zip"): + return extractZip(ar, dest) + default: + return fmt.Errorf("unhandled archive type %s", archive) + } +} + +// extractTarball unpacks a .tar.gz file. +func extractTarball(ar io.Reader, dest string) error { + gzr, err := gzip.NewReader(ar) + if err != nil { + return err + } + defer gzr.Close() + + tr := tar.NewReader(gzr) + for { + // Move to the next file header. + header, err := tr.Next() + if err != nil { + if err == io.EOF { + return nil + } + return err + } + // We only care about regular files, directory modes + // and special file types are not supported. + if header.Typeflag == tar.TypeReg { + armode := header.FileInfo().Mode() + err := extractFile(header.Name, armode, tr, dest) + if err != nil { + return fmt.Errorf("extract %s: %v", header.Name, err) + } + } + } +} + +// extractZip unpacks the given .zip file. +func extractZip(ar *os.File, dest string) error { + info, err := ar.Stat() + if err != nil { + return err + } + zr, err := zip.NewReader(ar, info.Size()) + if err != nil { + return err + } + + for _, zf := range zr.File { + if !zf.Mode().IsRegular() { + continue + } + + data, err := zf.Open() + if err != nil { + return err + } + err = extractFile(zf.Name, zf.Mode(), data, dest) + data.Close() + if err != nil { + return fmt.Errorf("extract %s: %v", zf.Name, err) + } + } + return nil +} + +// extractFile extracts a single file from an archive. +func extractFile(arpath string, armode os.FileMode, data io.Reader, dest string) error { + // Check that path is inside destination directory. + target := filepath.Join(dest, filepath.FromSlash(arpath)) + if !strings.HasPrefix(target, filepath.Clean(dest)+string(os.PathSeparator)) { + return fmt.Errorf("path %q escapes archive destination", target) + } + + // Ensure the destination directory exists. + if err := os.MkdirAll(filepath.Dir(target), 0755); err != nil { + return err + } + + // Copy file data. + file, err := os.OpenFile(target, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, armode) + if err != nil { + return err + } + if _, err := io.Copy(file, data); err != nil { + file.Close() + os.Remove(target) + return err + } + return file.Close() +} diff --git a/internal/build/download.go b/internal/build/download.go new file mode 100644 index 0000000000..0ed0b5e130 --- /dev/null +++ b/internal/build/download.go @@ -0,0 +1,151 @@ +// Copyright 2019 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 . + +package build + +import ( + "bufio" + "crypto/sha256" + "encoding/hex" + "fmt" + "io" + "io/ioutil" + "log" + "net/http" + "os" + "path/filepath" + "strings" +) + +// ChecksumDB keeps file checksums. +type ChecksumDB struct { + allChecksums []string +} + +// MustLoadChecksums loads a file containing checksums. +func MustLoadChecksums(file string) *ChecksumDB { + content, err := ioutil.ReadFile(file) + if err != nil { + log.Fatal("can't load checksum file: " + err.Error()) + } + return &ChecksumDB{strings.Split(string(content), "\n")} +} + +// Verify checks whether the given file is valid according to the checksum database. +func (db *ChecksumDB) Verify(path string) error { + fd, err := os.Open(path) + if err != nil { + return err + } + defer fd.Close() + + h := sha256.New() + if _, err := io.Copy(h, bufio.NewReader(fd)); err != nil { + return err + } + fileHash := hex.EncodeToString(h.Sum(nil)) + if !db.findHash(filepath.Base(path), fileHash) { + return fmt.Errorf("invalid file hash %s", fileHash) + } + return nil +} + +func (db *ChecksumDB) findHash(basename, hash string) bool { + want := hash + " " + basename + for _, line := range db.allChecksums { + if strings.TrimSpace(line) == want { + return true + } + } + return false +} + +// DownloadFile downloads a file and verifies its checksum. +func (db *ChecksumDB) DownloadFile(url, dstPath string) error { + if err := db.Verify(dstPath); err == nil { + fmt.Printf("%s is up-to-date\n", dstPath) + return nil + } + fmt.Printf("%s is stale\n", dstPath) + fmt.Printf("downloading from %s\n", url) + + resp, err := http.Get(url) + if err != nil { + return fmt.Errorf("download error: %v", err) + } else if resp.StatusCode != http.StatusOK { + return fmt.Errorf("download error: status %d", resp.StatusCode) + } + defer resp.Body.Close() + if err := os.MkdirAll(filepath.Dir(dstPath), 0755); err != nil { + return err + } + fd, err := os.OpenFile(dstPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644) + if err != nil { + return err + } + dst := newDownloadWriter(fd, resp.ContentLength) + _, err = io.Copy(dst, resp.Body) + dst.Close() + if err != nil { + return err + } + + return db.Verify(dstPath) +} + +type downloadWriter struct { + file *os.File + dstBuf *bufio.Writer + size int64 + written int64 + lastpct int64 +} + +func newDownloadWriter(dst *os.File, size int64) *downloadWriter { + return &downloadWriter{ + file: dst, + dstBuf: bufio.NewWriter(dst), + size: size, + } +} + +func (w *downloadWriter) Write(buf []byte) (int, error) { + n, err := w.dstBuf.Write(buf) + + // Report progress. + w.written += int64(n) + pct := w.written * 10 / w.size * 10 + if pct != w.lastpct { + if w.lastpct != 0 { + fmt.Print("...") + } + fmt.Print(pct, "%") + w.lastpct = pct + } + return n, err +} + +func (w *downloadWriter) Close() error { + if w.lastpct > 0 { + fmt.Println() // Finish the progress line. + } + flushErr := w.dstBuf.Flush() + closeErr := w.file.Close() + if flushErr != nil { + return flushErr + } + return closeErr +} diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index 8897f06d84..95d497faf0 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -23,7 +23,7 @@ var Modules = map[string]string{ "chequebook": Chequebook_JS, "clique": Clique_JS, "ethash": Ethash_JS, - "XDPoS": XDPoS_JS, + "XDPoS": XDPoS_JS, "debug": Debug_JS, "eth": Eth_JS, "miner": Miner_JS, diff --git a/light/lightchain.go b/light/lightchain.go index c9143c05fa..cb67da6213 100644 --- a/light/lightchain.go +++ b/light/lightchain.go @@ -35,7 +35,7 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" - "github.com/hashicorp/golang-lru" + lru "github.com/hashicorp/golang-lru" ) var ( diff --git a/miner/worker_test.go b/miner/worker_test.go index e0f5a3e38e..fa47de7073 100644 --- a/miner/worker_test.go +++ b/miner/worker_test.go @@ -126,9 +126,9 @@ func newTestWorkerBackend(t *testing.T, chainConfig *params.ChainConfig, engine } func (b *testWorkerBackend) AccountManager() *accounts.Manager { return accounts.NewManager() } -func (b *testWorkerBackend) BlockChain() *core.BlockChain { return b.chain } -func (b *testWorkerBackend) ChainDb() ethdb.Database { return b.db } -func (b *testWorkerBackend) TxPool() *core.TxPool { return b.txPool } +func (b *testWorkerBackend) BlockChain() *core.BlockChain { return b.chain } +func (b *testWorkerBackend) ChainDb() ethdb.Database { return b.db } +func (b *testWorkerBackend) TxPool() *core.TxPool { return b.txPool } func (b *testWorkerBackend) PostChainEvents(events []interface{}) { b.chain.PostChainEvents(events, nil) } diff --git a/p2p/nat/nat.go b/p2p/nat/nat.go index 8fad921c48..504b7b074a 100644 --- a/p2p/nat/nat.go +++ b/p2p/nat/nat.go @@ -26,7 +26,7 @@ import ( "time" "github.com/ethereum/go-ethereum/log" - "github.com/jackpal/go-nat-pmp" + natpmp "github.com/jackpal/go-nat-pmp" ) // An implementation of nat.Interface can map local ports to ports diff --git a/p2p/nat/natpmp.go b/p2p/nat/natpmp.go index 8ba9714728..7f85543f8e 100644 --- a/p2p/nat/natpmp.go +++ b/p2p/nat/natpmp.go @@ -22,7 +22,7 @@ import ( "strings" "time" - "github.com/jackpal/go-nat-pmp" + natpmp "github.com/jackpal/go-nat-pmp" ) // natPMPClient adapts the NAT-PMP protocol implementation so it conforms to diff --git a/params/version.go b/params/version.go index d62b754ade..9f8fd0dc16 100644 --- a/params/version.go +++ b/params/version.go @@ -21,9 +21,9 @@ import ( ) const ( - VersionMajor = 1 // Major version component of the current release - VersionMinor = 1 // Minor version component of the current release - VersionPatch = 1827 // Patch version component of the current release + VersionMajor = 1 // Major version component of the current release + VersionMinor = 1 // Minor version component of the current release + VersionPatch = 1827 // Patch version component of the current release VersionMeta = "unstable" // Version metadata to append to the version string ) diff --git a/trie/database.go b/trie/database.go index 2bfe34ec7d..a535488f26 100644 --- a/trie/database.go +++ b/trie/database.go @@ -132,9 +132,11 @@ type rawShortNode struct { Val Node } -func (n rawShortNode) canUnload(uint16, uint16) bool { panic("this should never end up in a live trie") } -func (n rawShortNode) Cache() (HashNode, bool) { panic("this should never end up in a live trie") } -func (n rawShortNode) fstring(ind string) string { panic("this should never end up in a live trie") } +func (n rawShortNode) canUnload(uint16, uint16) bool { + panic("this should never end up in a live trie") +} +func (n rawShortNode) Cache() (HashNode, bool) { panic("this should never end up in a live trie") } +func (n rawShortNode) fstring(ind string) string { panic("this should never end up in a live trie") } // cachedNode is all the information we know about a single cached node in the // memory database write layer.