mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 10:50:44 +00:00
add linting as the first CI task
This commit is contained in:
parent
916b16de71
commit
0fdab2027c
39 changed files with 671 additions and 90 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -48,3 +48,5 @@ profile.cov
|
||||||
/dashboard/assets/package-lock.json
|
/dashboard/assets/package-lock.json
|
||||||
|
|
||||||
**/yarn-error.log
|
**/yarn-error.log
|
||||||
|
|
||||||
|
/build/cache/
|
||||||
51
.golangci.yml
Normal file
51
.golangci.yml
Normal file
|
|
@ -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
|
||||||
36
.travis.yml
Normal file
36
.travis.yml
Normal file
|
|
@ -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
|
||||||
33
build/checksums.txt
Normal file
33
build/checksums.txt
Normal file
|
|
@ -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
|
||||||
47
build/ci.go
47
build/ci.go
|
|
@ -239,39 +239,40 @@ func doTest(cmdline []string) {
|
||||||
build.MustRun(gotest)
|
build.MustRun(gotest)
|
||||||
}
|
}
|
||||||
|
|
||||||
// runs gometalinter on requested packages
|
// doLint runs golangci-lint on requested packages.
|
||||||
func doLint(cmdline []string) {
|
func doLint(cmdline []string) {
|
||||||
|
var (
|
||||||
|
cachedir = flag.String("cachedir", "./build/cache", "directory for caching golangci-lint binary.")
|
||||||
|
)
|
||||||
flag.CommandLine.Parse(cmdline)
|
flag.CommandLine.Parse(cmdline)
|
||||||
|
|
||||||
packages := []string{"./..."}
|
packages := []string{"./..."}
|
||||||
if len(flag.CommandLine.Args()) > 0 {
|
if len(flag.CommandLine.Args()) > 0 {
|
||||||
packages = flag.CommandLine.Args()
|
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
|
linter := downloadLinter(*cachedir)
|
||||||
configs := []string{
|
lflags := []string{"run", "--config", ".golangci.yml"}
|
||||||
"--vendor",
|
build.MustRunCommand(linter, append(lflags, packages...)...)
|
||||||
"--tests",
|
fmt.Println("You have achieved perfection.")
|
||||||
"--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...)...)
|
|
||||||
|
|
||||||
// Run slow linters one by one
|
}
|
||||||
for _, linter := range []string{"unconvert", "gosimple"} {
|
|
||||||
configs = []string{"--vendor", "--tests", "--deadline=10m", "--disable-all", "--enable=" + linter}
|
// downloadLinter downloads and unpacks golangci-lint.
|
||||||
build.MustRunCommand(filepath.Join(GOBIN, "gometalinter.v2"), append(configs, packages...)...)
|
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
|
// Cross compilation
|
||||||
|
|
|
||||||
|
|
@ -216,7 +216,7 @@ var AppHelpFlagGroups = []flagGroup{
|
||||||
// },
|
// },
|
||||||
//},
|
//},
|
||||||
{
|
{
|
||||||
Name: "LOGGING AND DEBUGGING",
|
Name: "LOGGING AND DEBUGGING",
|
||||||
Flags: append([]cli.Flag{
|
Flags: append([]cli.Flag{
|
||||||
//utils.FakePoWFlag,
|
//utils.FakePoWFlag,
|
||||||
//utils.NoCompactionFlag,
|
//utils.NoCompactionFlag,
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"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"
|
||||||
"github.com/syndtr/goleveldb/leveldb/util"
|
"github.com/syndtr/goleveldb/leveldb/util"
|
||||||
)
|
)
|
||||||
|
|
@ -56,11 +56,11 @@ func main() {
|
||||||
head := rawdb.ReadHeadBlockHash(lddb)
|
head := rawdb.ReadHeadBlockHash(lddb)
|
||||||
headNumber := rawdb.ReadHeaderNumber(lddb, head)
|
headNumber := rawdb.ReadHeaderNumber(lddb, head)
|
||||||
if headNumber == nil {
|
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)
|
currentHeader := rawdb.ReadHeader(lddb, head, *headNumber)
|
||||||
if currentHeader == nil {
|
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)
|
tridb := trie.NewDatabase(lddb)
|
||||||
catchEventInterupt(lddb.LDB())
|
catchEventInterupt(lddb.LDB())
|
||||||
|
|
|
||||||
|
|
@ -304,13 +304,13 @@ func (w *wizard) makeGenesis() {
|
||||||
contractBackend.ForEachStorageAt(ctx, multiSignWalletTeamAddr, nil, f)
|
contractBackend.ForEachStorageAt(ctx, multiSignWalletTeamAddr, nil, f)
|
||||||
// Team balance.
|
// Team balance.
|
||||||
balance := big.NewInt(0) // 20 billion
|
balance := big.NewInt(0) // 20 billion
|
||||||
balance.Add(balance, big.NewInt(30*1000*1000))
|
balance.Add(balance, big.NewInt(30*1000*1000))
|
||||||
balance.Mul(balance, big.NewInt(1000000000000000000))
|
balance.Mul(balance, big.NewInt(1000000000000000000))
|
||||||
subBalance := big.NewInt(0) // i * 50k
|
subBalance := big.NewInt(0) // i * 50k
|
||||||
subBalance.Add(subBalance, big.NewInt(int64(len(signers))*10*1000*1000))
|
subBalance.Add(subBalance, big.NewInt(int64(len(signers))*10*1000*1000))
|
||||||
subBalance.Mul(subBalance, big.NewInt(1000000000000000000))
|
subBalance.Mul(subBalance, big.NewInt(1000000000000000000))
|
||||||
balance.Sub(balance, subBalance) // 12m - i * 50k
|
balance.Sub(balance, subBalance) // 12m - i * 50k
|
||||||
genesis.Alloc[common.HexToAddress(common.TeamAddr)] = core.GenesisAccount{
|
genesis.Alloc[common.HexToAddress(common.TeamAddr)] = core.GenesisAccount{
|
||||||
Balance: balance,
|
Balance: balance,
|
||||||
Code: code,
|
Code: code,
|
||||||
Storage: storage,
|
Storage: storage,
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import (
|
||||||
gorand "math/rand"
|
gorand "math/rand"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
//"runtime"
|
//"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
//"runtime"
|
//"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,8 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/fdlimit"
|
"github.com/ethereum/go-ethereum/common/fdlimit"
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"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/XDPoS"
|
||||||
|
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
|
|
|
||||||
|
|
@ -296,7 +296,7 @@ func checkText(input []byte, wantPrefix bool) ([]byte, error) {
|
||||||
if bytesHaveXDCPrefix(input) {
|
if bytesHaveXDCPrefix(input) {
|
||||||
input = input[3:]
|
input = input[3:]
|
||||||
} else if bytesHave0xPrefix(input) {
|
} else if bytesHave0xPrefix(input) {
|
||||||
input = input[2:]
|
input = input[2:]
|
||||||
} else if wantPrefix {
|
} else if wantPrefix {
|
||||||
return nil, ErrMissingPrefix
|
return nil, ErrMissingPrefix
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ import (
|
||||||
// Lengths of hashes and addresses in bytes.
|
// Lengths of hashes and addresses in bytes.
|
||||||
const (
|
const (
|
||||||
// HashLength is the expected length of the hash
|
// HashLength is the expected length of the hash
|
||||||
HashLength = 32
|
HashLength = 32
|
||||||
// AddressLength is the expected length of the address
|
// AddressLength is the expected length of the address
|
||||||
AddressLength = 20
|
AddressLength = 20
|
||||||
MasternodeVotingSMC = "xdc0000000000000000000000000000000000000088"
|
MasternodeVotingSMC = "xdc0000000000000000000000000000000000000088"
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/hashicorp/golang-lru"
|
lru "github.com/hashicorp/golang-lru"
|
||||||
"golang.org/x/crypto/sha3"
|
"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.
|
// Ethereum testnet following the Ropsten attacks.
|
||||||
type XDPoS struct {
|
type XDPoS struct {
|
||||||
config *params.XDPoSConfig // Consensus engine configuration parameters
|
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
|
recents *lru.ARCCache // Snapshots for recent block to speed up reorgs
|
||||||
signatures *lru.ARCCache // Signatures of recent blocks to speed up mining
|
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
|
// 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() {
|
if int64(header.Time) < time.Now().Unix() {
|
||||||
header.Time = uint64(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
|
// Seal implements consensus.Engine, attempting to create a sealed block using
|
||||||
// the local signing credentials.
|
// 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()
|
header := block.Header()
|
||||||
|
|
||||||
// Sealing the genesis block is not supported
|
// Sealing the genesis block is not supported
|
||||||
|
|
|
||||||
|
|
@ -76,11 +76,11 @@ func TestCompareSignersLists(t *testing.T) {
|
||||||
t.Error("Failed with empty list")
|
t.Error("Failed with empty list")
|
||||||
}
|
}
|
||||||
if !compareSignersLists([]common.Address{common.BytesToAddress([]byte("cccccccccccccccccccccccccccccccccccccccc"))},
|
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")
|
t.Error("Failed with list has only one signer")
|
||||||
}
|
}
|
||||||
if compareSignersLists([]common.Address{common.BytesToAddress([]byte("aaaaaaaaaaaaaaaa"))},
|
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")
|
t.Error("Failed with list has only one signer")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ import (
|
||||||
// mechanisms of the proof-of-authority scheme.
|
// mechanisms of the proof-of-authority scheme.
|
||||||
type API struct {
|
type API struct {
|
||||||
chain consensus.ChainReader
|
chain consensus.ChainReader
|
||||||
XDPoS *XDPoS
|
XDPoS *XDPoS
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSnapshot retrieves the state snapshot at a given block.
|
// GetSnapshot retrieves the state snapshot at a given block.
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,11 @@
|
||||||
package blocksigner
|
package blocksigner
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/contracts/blocksigner/contract"
|
"github.com/ethereum/go-ethereum/contracts/blocksigner/contract"
|
||||||
"math/big"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type BlockSigner struct {
|
type BlockSigner struct {
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,13 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"math/rand"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"math/rand"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,11 @@
|
||||||
package multisigwallet
|
package multisigwallet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/contracts/multisigwallet/contract"
|
"github.com/ethereum/go-ethereum/contracts/multisigwallet/contract"
|
||||||
"math/big"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type MultiSigWallet struct {
|
type MultiSigWallet struct {
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,11 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
|
"math/big"
|
||||||
|
"math/rand"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
|
@ -27,10 +32,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"math/big"
|
|
||||||
"math/rand"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/hashicorp/golang-lru"
|
lru "github.com/hashicorp/golang-lru"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,9 @@
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"runtime"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
"github.com/ethereum/go-ethereum/consensus/misc"
|
"github.com/ethereum/go-ethereum/consensus/misc"
|
||||||
|
|
@ -26,10 +29,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
import (
|
|
||||||
"runtime"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
// StateProcessor is a basic Processor, which takes care of transitioning
|
// StateProcessor is a basic Processor, which takes care of transitioning
|
||||||
// state from one point to another.
|
// state from one point to another.
|
||||||
|
|
|
||||||
|
|
@ -849,8 +849,10 @@ func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) {
|
||||||
//
|
//
|
||||||
// This logic should not hold for local transactions, unless the local tracking
|
// This logic should not hold for local transactions, unless the local tracking
|
||||||
// mechanism is disabled.
|
// mechanism is disabled.
|
||||||
func TestTransactionQueueTimeLimiting(t *testing.T) { testTransactionQueueTimeLimiting(t, false) }
|
func TestTransactionQueueTimeLimiting(t *testing.T) { testTransactionQueueTimeLimiting(t, false) }
|
||||||
func TestTransactionQueueTimeLimitingNoLocals(t *testing.T) { testTransactionQueueTimeLimiting(t, true) }
|
func TestTransactionQueueTimeLimitingNoLocals(t *testing.T) {
|
||||||
|
testTransactionQueueTimeLimiting(t, true)
|
||||||
|
}
|
||||||
|
|
||||||
func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
|
func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
|
||||||
// Reduce the eviction interval to a testable amount
|
// 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
|
// Tests that the transaction limits are enforced the same way irrelevant whether
|
||||||
// the transactions are added one by one or in batches.
|
// the transactions are added one by one or in batches.
|
||||||
func TestTransactionQueueLimitingEquivalency(t *testing.T) { testTransactionLimitingEquivalency(t, 1) }
|
func TestTransactionQueueLimitingEquivalency(t *testing.T) { testTransactionLimitingEquivalency(t, 1) }
|
||||||
func TestTransactionPendingLimitingEquivalency(t *testing.T) { testTransactionLimitingEquivalency(t, 0) }
|
func TestTransactionPendingLimitingEquivalency(t *testing.T) {
|
||||||
|
testTransactionLimitingEquivalency(t, 0)
|
||||||
|
}
|
||||||
|
|
||||||
func testTransactionLimitingEquivalency(t *testing.T, origin uint64) {
|
func testTransactionLimitingEquivalency(t *testing.T, origin uint64) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,10 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"reflect"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// from bcValidBlockTest.json, "SimpleTx"
|
// from bcValidBlockTest.json, "SimpleTx"
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
// Package bn256 implements the Optimal Ate pairing over a 256-bit Barreto-Naehrig curve.
|
// Package bn256 implements the Optimal Ate pairing over a 256-bit Barreto-Naehrig curve.
|
||||||
package bn256
|
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
|
// 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.
|
// output of an operation, but cannot be used as an input.
|
||||||
|
|
|
||||||
|
|
@ -20,22 +20,24 @@ package eth
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"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"
|
"math/big"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"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"
|
"bytes"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"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/XDPoS"
|
||||||
|
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||||
"github.com/ethereum/go-ethereum/contracts"
|
"github.com/ethereum/go-ethereum/contracts"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/bloombits"
|
"github.com/ethereum/go-ethereum/core/bloombits"
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
package eth
|
package eth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/ethereum/go-ethereum/params"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRewardInflation(t *testing.T) {
|
func TestRewardInflation(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -428,12 +428,14 @@ func assertOwnForkedChain(t *testing.T, tester *downloadTester, common int, leng
|
||||||
// Tests that simple synchronization against a canonical chain works correctly.
|
// Tests that simple synchronization against a canonical chain works correctly.
|
||||||
// In this test common ancestor lookup should be short circuited and not require
|
// In this test common ancestor lookup should be short circuited and not require
|
||||||
// binary searching.
|
// binary searching.
|
||||||
func TestCanonicalSynchronisation62(t *testing.T) { testCanonicalSynchronisation(t, 62, FullSync) }
|
func TestCanonicalSynchronisation62(t *testing.T) { testCanonicalSynchronisation(t, 62, FullSync) }
|
||||||
func TestCanonicalSynchronisation63Full(t *testing.T) { testCanonicalSynchronisation(t, 63, FullSync) }
|
func TestCanonicalSynchronisation63Full(t *testing.T) { testCanonicalSynchronisation(t, 63, FullSync) }
|
||||||
func TestCanonicalSynchronisation63Fast(t *testing.T) { testCanonicalSynchronisation(t, 63, FastSync) }
|
func TestCanonicalSynchronisation63Fast(t *testing.T) { testCanonicalSynchronisation(t, 63, FastSync) }
|
||||||
func TestCanonicalSynchronisation64Full(t *testing.T) { testCanonicalSynchronisation(t, 64, FullSync) }
|
func TestCanonicalSynchronisation64Full(t *testing.T) { testCanonicalSynchronisation(t, 64, FullSync) }
|
||||||
func TestCanonicalSynchronisation64Fast(t *testing.T) { testCanonicalSynchronisation(t, 64, FastSync) }
|
func TestCanonicalSynchronisation64Fast(t *testing.T) { testCanonicalSynchronisation(t, 64, FastSync) }
|
||||||
func TestCanonicalSynchronisation64Light(t *testing.T) { testCanonicalSynchronisation(t, 64, LightSync) }
|
func TestCanonicalSynchronisation64Light(t *testing.T) {
|
||||||
|
testCanonicalSynchronisation(t, 64, LightSync)
|
||||||
|
}
|
||||||
|
|
||||||
func testCanonicalSynchronisation(t *testing.T, protocol int, mode SyncMode) {
|
func testCanonicalSynchronisation(t *testing.T, protocol int, mode SyncMode) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,11 @@ package fetcher
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/hashicorp/golang-lru"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
lru "github.com/hashicorp/golang-lru"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/prque"
|
"github.com/ethereum/go-ethereum/common/prque"
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,14 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/hashicorp/golang-lru"
|
|
||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
lru "github.com/hashicorp/golang-lru"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
|
|
@ -794,7 +795,7 @@ func (pm *ProtocolManager) minedBroadcastLoop() {
|
||||||
// automatically stops if unsubscribe
|
// automatically stops if unsubscribe
|
||||||
for obj := range pm.minedBlockSub.Chan() {
|
for obj := range pm.minedBlockSub.Chan() {
|
||||||
if ev, ok := obj.Data.(core.NewMinedBlockEvent); ok {
|
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
|
//pm.BroadcastBlock(ev.Block, false) // Only then announce to the rest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
288
internal/build/archive.go
Normal file
288
internal/build/archive.go
Normal file
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
151
internal/build/download.go
Normal file
151
internal/build/download.go
Normal file
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
@ -23,7 +23,7 @@ var Modules = map[string]string{
|
||||||
"chequebook": Chequebook_JS,
|
"chequebook": Chequebook_JS,
|
||||||
"clique": Clique_JS,
|
"clique": Clique_JS,
|
||||||
"ethash": Ethash_JS,
|
"ethash": Ethash_JS,
|
||||||
"XDPoS": XDPoS_JS,
|
"XDPoS": XDPoS_JS,
|
||||||
"debug": Debug_JS,
|
"debug": Debug_JS,
|
||||||
"eth": Eth_JS,
|
"eth": Eth_JS,
|
||||||
"miner": Miner_JS,
|
"miner": Miner_JS,
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/hashicorp/golang-lru"
|
lru "github.com/hashicorp/golang-lru"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
||||||
|
|
@ -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) AccountManager() *accounts.Manager { return accounts.NewManager() }
|
||||||
func (b *testWorkerBackend) BlockChain() *core.BlockChain { return b.chain }
|
func (b *testWorkerBackend) BlockChain() *core.BlockChain { return b.chain }
|
||||||
func (b *testWorkerBackend) ChainDb() ethdb.Database { return b.db }
|
func (b *testWorkerBackend) ChainDb() ethdb.Database { return b.db }
|
||||||
func (b *testWorkerBackend) TxPool() *core.TxPool { return b.txPool }
|
func (b *testWorkerBackend) TxPool() *core.TxPool { return b.txPool }
|
||||||
func (b *testWorkerBackend) PostChainEvents(events []interface{}) {
|
func (b *testWorkerBackend) PostChainEvents(events []interface{}) {
|
||||||
b.chain.PostChainEvents(events, nil)
|
b.chain.PostChainEvents(events, nil)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"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
|
// An implementation of nat.Interface can map local ports to ports
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"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
|
// natPMPClient adapts the NAT-PMP protocol implementation so it conforms to
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
VersionMajor = 1 // Major version component of the current release
|
VersionMajor = 1 // Major version component of the current release
|
||||||
VersionMinor = 1 // Minor version component of the current release
|
VersionMinor = 1 // Minor version component of the current release
|
||||||
VersionPatch = 1827 // Patch 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
|
VersionMeta = "unstable" // Version metadata to append to the version string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -132,9 +132,11 @@ type rawShortNode struct {
|
||||||
Val Node
|
Val Node
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n rawShortNode) canUnload(uint16, uint16) bool { panic("this should never end up in a live trie") }
|
func (n rawShortNode) canUnload(uint16, uint16) bool {
|
||||||
func (n rawShortNode) Cache() (HashNode, bool) { panic("this should never end up in a live trie") }
|
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) 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
|
// cachedNode is all the information we know about a single cached node in the
|
||||||
// memory database write layer.
|
// memory database write layer.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue