mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
Merge branch 'master' into order-event
This commit is contained in:
commit
46fe15f51f
1608 changed files with 1270 additions and 813932 deletions
|
|
@ -19,6 +19,8 @@ jobs:
|
|||
os: linux
|
||||
dist: xenial
|
||||
go: 1.11.x
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
script:
|
||||
- go run build/ci.go install
|
||||
- go run build/ci.go test -coverage $TEST_PACKAGES
|
||||
|
|
@ -27,6 +29,8 @@ jobs:
|
|||
os: linux
|
||||
dist: xenial
|
||||
go: 1.12.x
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
script:
|
||||
- go run build/ci.go install
|
||||
- go run build/ci.go test -coverage $TEST_PACKAGES
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -36,7 +36,7 @@ lint: ## Run linters.
|
|||
build/env.sh go run build/ci.go lint
|
||||
|
||||
clean:
|
||||
./build/clean_go_build_cache.sh
|
||||
go clean -cache
|
||||
rm -fr build/_workspace/pkg/ $(GOBIN)/*
|
||||
|
||||
# The devtools target installs tools required for 'go generate'.
|
||||
|
|
|
|||
|
|
@ -927,7 +927,7 @@ func TestABI_MethodById(t *testing.T) {
|
|||
}
|
||||
b := fmt.Sprintf("%v", m2)
|
||||
if a != b {
|
||||
t.Errorf("Method %v (id %v) not 'findable' by id in ABI", name, common.ToHex(m.ID()))
|
||||
t.Errorf("Method %v (id %x) not 'findable' by id in ABI", name, m.ID())
|
||||
}
|
||||
}
|
||||
// Also test empty
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ func TestSimulatedBackend(t *testing.T) {
|
|||
}
|
||||
|
||||
sim.Commit()
|
||||
tx, isPending, err = sim.TransactionByHash(context.Background(), txHash)
|
||||
_, isPending, err = sim.TransactionByHash(context.Background(), txHash)
|
||||
if err != nil {
|
||||
t.Fatalf("error getting transaction with hash: %v", txHash.String())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,12 +48,16 @@ const (
|
|||
// enforces compile time type safety and naming convention opposed to having to
|
||||
// manually maintain hard coded strings that break on runtime.
|
||||
func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]string, pkg string, lang Lang, libs map[string]string, aliases map[string]string) (string, error) {
|
||||
// Process each individual contract requested binding
|
||||
contracts := make(map[string]*tmplContract)
|
||||
var (
|
||||
// contracts is the map of each individual contract requested binding
|
||||
contracts = make(map[string]*tmplContract)
|
||||
|
||||
// Map used to flag each encountered library as such
|
||||
isLib := make(map[string]struct{})
|
||||
// structs is the map of all reclared structs shared by passed contracts.
|
||||
structs = make(map[string]*tmplStruct)
|
||||
|
||||
// isLib is the map used to flag each encountered library as such
|
||||
isLib = make(map[string]struct{})
|
||||
)
|
||||
for i := 0; i < len(types); i++ {
|
||||
// Parse the actual ABI to generate the binding for
|
||||
evmABI, err := abi.JSON(strings.NewReader(abis[i]))
|
||||
|
|
@ -73,7 +77,6 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]
|
|||
calls = make(map[string]*tmplMethod)
|
||||
transacts = make(map[string]*tmplMethod)
|
||||
events = make(map[string]*tmplEvent)
|
||||
structs = make(map[string]*tmplStruct)
|
||||
|
||||
// identifiers are used to detect duplicated identifier of function
|
||||
// and event. For all calls, transacts and events, abigen will generate
|
||||
|
|
@ -168,7 +171,6 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]
|
|||
Transacts: transacts,
|
||||
Events: events,
|
||||
Libraries: make(map[string]string),
|
||||
Structs: structs,
|
||||
}
|
||||
// Function 4-byte signatures are stored in the same sequence
|
||||
// as types, if available.
|
||||
|
|
@ -200,6 +202,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]
|
|||
Package: pkg,
|
||||
Contracts: contracts,
|
||||
Libraries: libs,
|
||||
Structs: structs,
|
||||
}
|
||||
buffer := new(bytes.Buffer)
|
||||
|
||||
|
|
|
|||
|
|
@ -1448,6 +1448,88 @@ var bindTests = []struct {
|
|||
map[string]string{"_myVar": "pubVar"}, // alias MyVar to PubVar
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"MultiContracts",
|
||||
`
|
||||
pragma solidity ^0.5.11;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
library ExternalLib {
|
||||
struct SharedStruct{
|
||||
uint256 f1;
|
||||
bytes32 f2;
|
||||
}
|
||||
}
|
||||
|
||||
contract ContractOne {
|
||||
function foo(ExternalLib.SharedStruct memory s) pure public {
|
||||
// Do stuff
|
||||
}
|
||||
}
|
||||
|
||||
contract ContractTwo {
|
||||
function bar(ExternalLib.SharedStruct memory s) pure public {
|
||||
// Do stuff
|
||||
}
|
||||
}
|
||||
`,
|
||||
[]string{
|
||||
`60806040523480156100115760006000fd5b50610017565b6101b5806100266000396000f3fe60806040523480156100115760006000fd5b50600436106100305760003560e01c80639d8a8ba81461003657610030565b60006000fd5b610050600480360361004b91908101906100d1565b610052565b005b5b5056610171565b6000813590506100698161013d565b92915050565b6000604082840312156100825760006000fd5b61008c60406100fb565b9050600061009c848285016100bc565b60008301525060206100b08482850161005a565b60208301525092915050565b6000813590506100cb81610157565b92915050565b6000604082840312156100e45760006000fd5b60006100f28482850161006f565b91505092915050565b6000604051905081810181811067ffffffffffffffff8211171561011f5760006000fd5b8060405250919050565b6000819050919050565b6000819050919050565b61014681610129565b811415156101545760006000fd5b50565b61016081610133565b8114151561016e5760006000fd5b50565bfea365627a7a72315820749274eb7f6c01010d5322af4e1668b0a154409eb7968bd6cae5524c7ed669bb6c6578706572696d656e74616cf564736f6c634300050c0040`,
|
||||
`60806040523480156100115760006000fd5b50610017565b6101b5806100266000396000f3fe60806040523480156100115760006000fd5b50600436106100305760003560e01c8063db8ba08c1461003657610030565b60006000fd5b610050600480360361004b91908101906100d1565b610052565b005b5b5056610171565b6000813590506100698161013d565b92915050565b6000604082840312156100825760006000fd5b61008c60406100fb565b9050600061009c848285016100bc565b60008301525060206100b08482850161005a565b60208301525092915050565b6000813590506100cb81610157565b92915050565b6000604082840312156100e45760006000fd5b60006100f28482850161006f565b91505092915050565b6000604051905081810181811067ffffffffffffffff8211171561011f5760006000fd5b8060405250919050565b6000819050919050565b6000819050919050565b61014681610129565b811415156101545760006000fd5b50565b61016081610133565b8114151561016e5760006000fd5b50565bfea365627a7a723158209bc28ee7ea97c131a13330d77ec73b4493b5c59c648352da81dd288b021192596c6578706572696d656e74616cf564736f6c634300050c0040`,
|
||||
`606c6026600b82828239805160001a6073141515601857fe5b30600052607381538281f350fe73000000000000000000000000000000000000000030146080604052600436106023575b60006000fdfea365627a7a72315820518f0110144f5b3de95697d05e456a064656890d08e6f9cff47f3be710cc46a36c6578706572696d656e74616cf564736f6c634300050c0040`,
|
||||
},
|
||||
[]string{
|
||||
`[{"constant":true,"inputs":[{"components":[{"internalType":"uint256","name":"f1","type":"uint256"},{"internalType":"bytes32","name":"f2","type":"bytes32"}],"internalType":"struct ExternalLib.SharedStruct","name":"s","type":"tuple"}],"name":"foo","outputs":[],"payable":false,"stateMutability":"pure","type":"function"}]`,
|
||||
`[{"constant":true,"inputs":[{"components":[{"internalType":"uint256","name":"f1","type":"uint256"},{"internalType":"bytes32","name":"f2","type":"bytes32"}],"internalType":"struct ExternalLib.SharedStruct","name":"s","type":"tuple"}],"name":"bar","outputs":[],"payable":false,"stateMutability":"pure","type":"function"}]`,
|
||||
`[]`,
|
||||
},
|
||||
`
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
`,
|
||||
`
|
||||
key, _ := crypto.GenerateKey()
|
||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||
|
||||
// Deploy registrar contract
|
||||
sim := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000)
|
||||
defer sim.Close()
|
||||
|
||||
transactOpts := bind.NewKeyedTransactor(key)
|
||||
_, _, c1, err := DeployContractOne(transactOpts, sim)
|
||||
if err != nil {
|
||||
t.Fatal("Failed to deploy contract")
|
||||
}
|
||||
sim.Commit()
|
||||
err = c1.Foo(nil, ExternalLibSharedStruct{
|
||||
F1: big.NewInt(100),
|
||||
F2: [32]byte{0x01, 0x02, 0x03},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal("Failed to invoke function")
|
||||
}
|
||||
_, _, c2, err := DeployContractTwo(transactOpts, sim)
|
||||
if err != nil {
|
||||
t.Fatal("Failed to deploy contract")
|
||||
}
|
||||
sim.Commit()
|
||||
err = c2.Bar(nil, ExternalLibSharedStruct{
|
||||
F1: big.NewInt(100),
|
||||
F2: [32]byte{0x01, 0x02, 0x03},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal("Failed to invoke function")
|
||||
}
|
||||
`,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
[]string{"ContractOne", "ContractTwo", "ExternalLib"},
|
||||
},
|
||||
}
|
||||
|
||||
// Tests that packages generated by the binder can be successfully compiled and
|
||||
|
|
@ -1502,6 +1584,18 @@ func TestGolangBindings(t *testing.T) {
|
|||
t.Fatalf("test %d: failed to write tests: %v", i, err)
|
||||
}
|
||||
}
|
||||
// Convert the package to go modules and use the current source for go-ethereum
|
||||
moder := exec.Command(gocmd, "mod", "init", "bindtest")
|
||||
moder.Dir = pkg
|
||||
if out, err := moder.CombinedOutput(); err != nil {
|
||||
t.Fatalf("failed to convert binding test to modules: %v\n%s", err, out)
|
||||
}
|
||||
pwd, _ := os.Getwd()
|
||||
replacer := exec.Command(gocmd, "mod", "edit", "-replace", "github.com/ethereum/go-ethereum="+filepath.Join(pwd, "..", "..", "..")) // Repo root
|
||||
replacer.Dir = pkg
|
||||
if out, err := replacer.CombinedOutput(); err != nil {
|
||||
t.Fatalf("failed to replace binding test dependency to current source tree: %v\n%s", err, out)
|
||||
}
|
||||
// Test the entire package and report any failures
|
||||
cmd := exec.Command(gocmd, "test", "-v", "-count", "1")
|
||||
cmd.Dir = pkg
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ type tmplData struct {
|
|||
Package string // Name of the package to place the generated file in
|
||||
Contracts map[string]*tmplContract // List of contracts to generate into this file
|
||||
Libraries map[string]string // Map the bytecode's link pattern to the library name
|
||||
Structs map[string]*tmplStruct // Contract struct type definitions
|
||||
}
|
||||
|
||||
// tmplContract contains the data needed to generate an individual contract binding.
|
||||
|
|
@ -36,8 +37,7 @@ type tmplContract struct {
|
|||
Transacts map[string]*tmplMethod // Contract calls that write state data
|
||||
Events map[string]*tmplEvent // Contract events accessors
|
||||
Libraries map[string]string // Same as tmplData, but filtered to only keep what the contract needs
|
||||
Structs map[string]*tmplStruct // Contract struct type definitions
|
||||
Library bool
|
||||
Library bool // Indicator whether the contract is a library
|
||||
}
|
||||
|
||||
// tmplMethod is a wrapper around an abi.Method that contains a few preprocessed
|
||||
|
|
@ -108,8 +108,16 @@ var (
|
|||
_ = event.NewSubscription
|
||||
)
|
||||
|
||||
{{$structs := .Structs}}
|
||||
{{range $structs}}
|
||||
// {{.Name}} is an auto generated low-level Go binding around an user-defined struct.
|
||||
type {{.Name}} struct {
|
||||
{{range $field := .Fields}}
|
||||
{{$field.Name}} {{$field.Type}}{{end}}
|
||||
}
|
||||
{{end}}
|
||||
|
||||
{{range $contract := .Contracts}}
|
||||
{{$structs := $contract.Structs}}
|
||||
// {{.Type}}ABI is the input ABI used to generate the binding from.
|
||||
const {{.Type}}ABI = "{{.InputABI}}"
|
||||
|
||||
|
|
@ -285,14 +293,6 @@ var (
|
|||
return _{{$contract.Type}}.Contract.contract.Transact(opts, method, params...)
|
||||
}
|
||||
|
||||
{{range .Structs}}
|
||||
// {{.Name}} is an auto generated low-level Go binding around an user-defined struct.
|
||||
type {{.Name}} struct {
|
||||
{{range $field := .Fields}}
|
||||
{{$field.Name}} {{$field.Type}}{{end}}
|
||||
}
|
||||
{{end}}
|
||||
|
||||
{{range .Calls}}
|
||||
// {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}.
|
||||
//
|
||||
|
|
@ -507,8 +507,8 @@ package {{.Package}};
|
|||
import org.ethereum.geth.*;
|
||||
import java.util.*;
|
||||
|
||||
{{$structs := .Structs}}
|
||||
{{range $contract := .Contracts}}
|
||||
{{$structs := $contract.Structs}}
|
||||
{{if not .Library}}public {{end}}class {{.Type}} {
|
||||
// ABI is the input ABI used to generate the binding from.
|
||||
public final static String ABI = "{{.InputABI}}";
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ func TestEventTupleUnpack(t *testing.T) {
|
|||
type EventTransferWithTag struct {
|
||||
// this is valid because `value` is not exportable,
|
||||
// so value is only unmarshalled into `Value1`.
|
||||
value *big.Int
|
||||
value *big.Int //lint:ignore U1000 unused field is part of test
|
||||
Value1 *big.Int `abi:"value"`
|
||||
}
|
||||
|
||||
|
|
@ -354,40 +354,6 @@ func unpackTestEventData(dest interface{}, hexData string, jsonEvent []byte, ass
|
|||
return a.Unpack(dest, "e", data)
|
||||
}
|
||||
|
||||
/*
|
||||
Taken from
|
||||
https://github.com/ethereum/go-ethereum/pull/15568
|
||||
*/
|
||||
|
||||
type testResult struct {
|
||||
Values [2]*big.Int
|
||||
Value1 *big.Int
|
||||
Value2 *big.Int
|
||||
}
|
||||
|
||||
type testCase struct {
|
||||
definition string
|
||||
want testResult
|
||||
}
|
||||
|
||||
func (tc testCase) encoded(intType, arrayType Type) []byte {
|
||||
var b bytes.Buffer
|
||||
if tc.want.Value1 != nil {
|
||||
val, _ := intType.pack(reflect.ValueOf(tc.want.Value1))
|
||||
b.Write(val)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(tc.want.Values, [2]*big.Int{nil, nil}) {
|
||||
val, _ := arrayType.pack(reflect.ValueOf(tc.want.Values))
|
||||
b.Write(val)
|
||||
}
|
||||
if tc.want.Value2 != nil {
|
||||
val, _ := intType.pack(reflect.ValueOf(tc.want.Value2))
|
||||
b.Write(val)
|
||||
}
|
||||
return b.Bytes()
|
||||
}
|
||||
|
||||
// TestEventUnpackIndexed verifies that indexed field will be skipped by event decoder.
|
||||
func TestEventUnpackIndexed(t *testing.T) {
|
||||
definition := `[{"name": "test", "type": "event", "inputs": [{"indexed": true, "name":"value1", "type":"uint8"},{"indexed": false, "name":"value2", "type":"uint8"}]}]`
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ func (ks keyStorePassphrase) StoreKey(filename string, key *Key, auth string) er
|
|||
"Please file a ticket at:\n\n" +
|
||||
"https://github.com/ethereum/go-ethereum/issues." +
|
||||
"The error was : %s"
|
||||
//lint:ignore ST1005 This is a message for the user
|
||||
return fmt.Errorf(msg, tmpName, err)
|
||||
}
|
||||
}
|
||||
|
|
@ -237,7 +238,7 @@ func DecryptKey(keyjson []byte, auth string) (*Key, error) {
|
|||
|
||||
func DecryptDataV3(cryptoJson CryptoJSON, auth string) ([]byte, error) {
|
||||
if cryptoJson.Cipher != "aes-128-ctr" {
|
||||
return nil, fmt.Errorf("Cipher not supported: %v", cryptoJson.Cipher)
|
||||
return nil, fmt.Errorf("cipher not supported: %v", cryptoJson.Cipher)
|
||||
}
|
||||
mac, err := hex.DecodeString(cryptoJson.MAC)
|
||||
if err != nil {
|
||||
|
|
@ -273,7 +274,7 @@ func DecryptDataV3(cryptoJson CryptoJSON, auth string) ([]byte, error) {
|
|||
|
||||
func decryptKeyV3(keyProtected *encryptedKeyJSONV3, auth string) (keyBytes []byte, keyId []byte, err error) {
|
||||
if keyProtected.Version != version {
|
||||
return nil, nil, fmt.Errorf("Version not supported: %v", keyProtected.Version)
|
||||
return nil, nil, fmt.Errorf("version not supported: %v", keyProtected.Version)
|
||||
}
|
||||
keyId = uuid.Parse(keyProtected.Id)
|
||||
plainText, err := DecryptDataV3(keyProtected.Crypto, auth)
|
||||
|
|
@ -335,13 +336,13 @@ func getKDFKey(cryptoJSON CryptoJSON, auth string) ([]byte, error) {
|
|||
c := ensureInt(cryptoJSON.KDFParams["c"])
|
||||
prf := cryptoJSON.KDFParams["prf"].(string)
|
||||
if prf != "hmac-sha256" {
|
||||
return nil, fmt.Errorf("Unsupported PBKDF2 PRF: %s", prf)
|
||||
return nil, fmt.Errorf("unsupported PBKDF2 PRF: %s", prf)
|
||||
}
|
||||
key := pbkdf2.Key(authArray, salt, c, dkLen, sha256.New)
|
||||
return key, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("Unsupported KDF: %s", cryptoJSON.KDF)
|
||||
return nil, fmt.Errorf("unsupported KDF: %s", cryptoJSON.KDF)
|
||||
}
|
||||
|
||||
// TODO: can we do without this when unmarshalling dynamic JSON?
|
||||
|
|
|
|||
41
build/ci.go
41
build/ci.go
|
|
@ -58,6 +58,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cespare/cp"
|
||||
"github.com/ethereum/go-ethereum/internal/build"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
|
@ -500,6 +501,15 @@ func doDebianSource(cmdline []string) {
|
|||
// Download and verify the Go source package.
|
||||
gobundle := downloadGoSources(*goversion, *cachedir)
|
||||
|
||||
// Download all the dependencies needed to build the sources and run the ci script
|
||||
srcdepfetch := goTool("install", "-n", "./...")
|
||||
srcdepfetch.Env = append(os.Environ(), "GOPATH="+filepath.Join(*workdir, "modgopath"))
|
||||
build.MustRun(srcdepfetch)
|
||||
|
||||
cidepfetch := goTool("run", "./build/ci.go")
|
||||
cidepfetch.Env = append(os.Environ(), "GOPATH="+filepath.Join(*workdir, "modgopath"))
|
||||
cidepfetch.Run() // Command fails, don't care, we only need the deps to start it
|
||||
|
||||
// Create Debian packages and upload them.
|
||||
for _, pkg := range debPackages {
|
||||
for distro, goboot := range debDistroGoBoots {
|
||||
|
|
@ -507,16 +517,20 @@ func doDebianSource(cmdline []string) {
|
|||
meta := newDebMetadata(distro, goboot, *signer, env, now, pkg.Name, pkg.Version, pkg.Executables)
|
||||
pkgdir := stageDebianSource(*workdir, meta)
|
||||
|
||||
// Add Go source code.
|
||||
// Add Go source code
|
||||
if err := build.ExtractTarballArchive(gobundle, pkgdir); err != nil {
|
||||
log.Fatalf("Failed to extract Go sources: %v", err)
|
||||
}
|
||||
if err := os.Rename(filepath.Join(pkgdir, "go"), filepath.Join(pkgdir, ".go")); err != nil {
|
||||
log.Fatalf("Failed to rename Go source folder: %v", err)
|
||||
}
|
||||
|
||||
// Add all dependency modules in compressed form
|
||||
os.MkdirAll(filepath.Join(pkgdir, ".mod", "cache"), 0755)
|
||||
if err := cp.CopyAll(filepath.Join(pkgdir, ".mod", "cache", "download"), filepath.Join(*workdir, "modgopath", "pkg", "mod", "cache", "download")); err != nil {
|
||||
log.Fatalf("Failed to copy Go module dependencies: %v", err)
|
||||
}
|
||||
// Run the packaging and upload to the PPA
|
||||
debuild := exec.Command("debuild", "-S", "-sa", "-us", "-uc", "-d", "-Zxz")
|
||||
debuild := exec.Command("debuild", "-S", "-sa", "-us", "-uc", "-d", "-Zxz", "-nc")
|
||||
debuild.Dir = pkgdir
|
||||
build.MustRun(debuild)
|
||||
|
||||
|
|
@ -780,9 +794,12 @@ func doWindowsInstaller(cmdline []string) {
|
|||
build.Render("build/nsis.uninstall.nsh", filepath.Join(*workdir, "uninstall.nsh"), 0644, allTools)
|
||||
build.Render("build/nsis.pathupdate.nsh", filepath.Join(*workdir, "PathUpdate.nsh"), 0644, nil)
|
||||
build.Render("build/nsis.envvarupdate.nsh", filepath.Join(*workdir, "EnvVarUpdate.nsh"), 0644, nil)
|
||||
build.CopyFile(filepath.Join(*workdir, "SimpleFC.dll"), "build/nsis.simplefc.dll", 0755)
|
||||
build.CopyFile(filepath.Join(*workdir, "COPYING"), "COPYING", 0755)
|
||||
|
||||
if err := cp.CopyFile(filepath.Join(*workdir, "SimpleFC.dll"), "build/nsis.simplefc.dll"); err != nil {
|
||||
log.Fatal("Failed to copy SimpleFC.dll: %v", err)
|
||||
}
|
||||
if err := cp.CopyFile(filepath.Join(*workdir, "COPYING"), "COPYING"); err != nil {
|
||||
log.Fatal("Failed to copy copyright note: %v", err)
|
||||
}
|
||||
// Build the installer. This assumes that all the needed files have been previously
|
||||
// built (don't mix building and packaging to keep cross compilation complexity to a
|
||||
// minimum).
|
||||
|
|
@ -799,7 +816,6 @@ func doWindowsInstaller(cmdline []string) {
|
|||
"/DARCH="+*arch,
|
||||
filepath.Join(*workdir, "geth.nsi"),
|
||||
)
|
||||
|
||||
// Sign and publish installer.
|
||||
if err := archiveUpload(installer, *upload, *signer); err != nil {
|
||||
log.Fatal(err)
|
||||
|
|
@ -1060,16 +1076,11 @@ func doXgo(cmdline []string) {
|
|||
|
||||
func xgoTool(args []string) *exec.Cmd {
|
||||
cmd := exec.Command(filepath.Join(GOBIN, "xgo"), args...)
|
||||
cmd.Env = []string{
|
||||
cmd.Env = os.Environ()
|
||||
cmd.Env = append(cmd.Env, []string{
|
||||
"GOPATH=" + build.GOPATH(),
|
||||
"GOBIN=" + GOBIN,
|
||||
}
|
||||
for _, e := range os.Environ() {
|
||||
if strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "GOBIN=") {
|
||||
continue
|
||||
}
|
||||
cmd.Env = append(cmd.Env, e)
|
||||
}
|
||||
}...)
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Cleaning the Go cache only makes sense if we actually have Go installed... or
|
||||
# if Go is actually callable. This does not hold true during deb packaging, so
|
||||
# we need an explicit check to avoid build failures.
|
||||
if ! command -v go > /dev/null; then
|
||||
exit
|
||||
fi
|
||||
|
||||
version_gt() {
|
||||
test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"
|
||||
}
|
||||
|
||||
golang_version=$(go version |cut -d' ' -f3 |sed 's/go//')
|
||||
|
||||
# Clean go build cache when go version is greater than or equal to 1.10
|
||||
if !(version_gt 1.10 $golang_version); then
|
||||
go clean -cache
|
||||
fi
|
||||
|
|
@ -4,13 +4,25 @@
|
|||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
# Launchpad rejects Go's access to $HOME/.cache, use custom folder
|
||||
# Launchpad rejects Go's access to $HOME, use custom folders
|
||||
export GOCACHE=/tmp/go-build
|
||||
export GOROOT_BOOTSTRAP={{.GoBootPath}}
|
||||
|
||||
override_dh_auto_clean:
|
||||
# Don't try to be smart Launchpad, we know our build rules better than you
|
||||
|
||||
override_dh_auto_build:
|
||||
(cd .go/src && ./make.bash)
|
||||
build/env.sh .go/bin/go run build/ci.go install -git-commit={{.Env.Commit}} -git-branch={{.Env.Branch}} -git-tag={{.Env.Tag}} -buildnum={{.Env.Buildnum}} -pull-request={{.Env.IsPullRequest}}
|
||||
# We can't download a fresh Go within Launchpad, so we're shipping and building
|
||||
# one on the fly. However, we can't build it inside the go-ethereum folder as
|
||||
# bootstrapping clashes with go modules, so build in a sibling folder.
|
||||
(mv .go ../ && cd ../.go/src && ./make.bash)
|
||||
|
||||
# We can't download external go modules within Launchpad, so we're shipping the
|
||||
# entire dependency source cache with go-ethereum.
|
||||
(mkdir -p build/_workspace/pkg/mod && mv .mod/* build/_workspace/pkg/mod)
|
||||
|
||||
# A fresh Go was built, all dependency downloads faked, hope build works now
|
||||
build/env.sh ../.go/bin/go run build/ci.go install -git-commit={{.Env.Commit}} -git-branch={{.Env.Branch}} -git-tag={{.Env.Tag}} -buildnum={{.Env.Buildnum}} -pull-request={{.Env.IsPullRequest}}
|
||||
|
||||
override_dh_auto_test:
|
||||
|
||||
|
|
|
|||
|
|
@ -32,19 +32,6 @@ import (
|
|||
"gopkg.in/urfave/cli.v1"
|
||||
)
|
||||
|
||||
const (
|
||||
commandHelperTemplate = `{{.Name}}{{if .Subcommands}} command{{end}}{{if .Flags}} [command options]{{end}} [arguments...]
|
||||
{{if .Description}}{{.Description}}
|
||||
{{end}}{{if .Subcommands}}
|
||||
SUBCOMMANDS:
|
||||
{{range .Subcommands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}
|
||||
{{end}}{{end}}{{if .Flags}}
|
||||
OPTIONS:
|
||||
{{range $.Flags}}{{"\t"}}{{.}}
|
||||
{{end}}
|
||||
{{end}}`
|
||||
)
|
||||
|
||||
var (
|
||||
// Git SHA1 commit hash of the release (set via linker flags)
|
||||
gitCommit = ""
|
||||
|
|
@ -128,7 +115,7 @@ func init() {
|
|||
aliasFlag,
|
||||
}
|
||||
app.Action = utils.MigrateFlags(abigen)
|
||||
cli.CommandHelpTemplate = commandHelperTemplate
|
||||
cli.CommandHelpTemplate = utils.OriginCommandHelpTemplate
|
||||
}
|
||||
|
||||
func abigen(c *cli.Context) error {
|
||||
|
|
|
|||
|
|
@ -28,19 +28,6 @@ import (
|
|||
"gopkg.in/urfave/cli.v1"
|
||||
)
|
||||
|
||||
const (
|
||||
commandHelperTemplate = `{{.Name}}{{if .Subcommands}} command{{end}}{{if .Flags}} [command options]{{end}} [arguments...]
|
||||
{{if .Description}}{{.Description}}
|
||||
{{end}}{{if .Subcommands}}
|
||||
SUBCOMMANDS:
|
||||
{{range .Subcommands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}
|
||||
{{end}}{{end}}{{if .Flags}}
|
||||
OPTIONS:
|
||||
{{range $.Flags}}{{"\t"}}{{.}}
|
||||
{{end}}
|
||||
{{end}}`
|
||||
)
|
||||
|
||||
var (
|
||||
// Git SHA1 commit hash of the release (set via linker flags)
|
||||
gitCommit = ""
|
||||
|
|
@ -61,7 +48,7 @@ func init() {
|
|||
oracleFlag,
|
||||
nodeURLFlag,
|
||||
}
|
||||
cli.CommandHelpTemplate = commandHelperTemplate
|
||||
cli.CommandHelpTemplate = utils.OriginCommandHelpTemplate
|
||||
}
|
||||
|
||||
// Commonly used command line flags.
|
||||
|
|
|
|||
|
|
@ -223,6 +223,7 @@ func init() {
|
|||
}
|
||||
app.Action = signer
|
||||
app.Commands = []cli.Command{initCommand, attestCommand, setCredentialCommand, delCredentialCommand, gendocCommand}
|
||||
cli.CommandHelpTemplate = utils.OriginCommandHelpTemplate
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ func init() {
|
|||
commandSignMessage,
|
||||
commandVerifyMessage,
|
||||
}
|
||||
cli.CommandHelpTemplate = utils.OriginCommandHelpTemplate
|
||||
}
|
||||
|
||||
// Commonly used command line flags.
|
||||
|
|
|
|||
|
|
@ -152,6 +152,7 @@ func init() {
|
|||
runCommand,
|
||||
stateTestCommand,
|
||||
}
|
||||
cli.CommandHelpTemplate = utils.OriginCommandHelpTemplate
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
|
|
|||
|
|
@ -117,7 +117,6 @@ func version(ctx *cli.Context) error {
|
|||
}
|
||||
fmt.Println("Architecture:", runtime.GOARCH)
|
||||
fmt.Println("Protocol Versions:", eth.ProtocolVersions)
|
||||
fmt.Println("Network Id:", eth.DefaultConfig.NetworkId)
|
||||
fmt.Println("Go Version:", runtime.Version())
|
||||
fmt.Println("Operating System:", runtime.GOOS)
|
||||
fmt.Printf("GOPATH=%s\n", os.Getenv("GOPATH"))
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"math"
|
||||
"math/big"
|
||||
|
|
@ -28,6 +27,7 @@ import (
|
|||
math2 "github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ type alethGenesisSpec struct {
|
|||
} `json:"params"`
|
||||
|
||||
Genesis struct {
|
||||
Nonce hexutil.Bytes `json:"nonce"`
|
||||
Nonce types.BlockNonce `json:"nonce"`
|
||||
Difficulty *hexutil.Big `json:"difficulty"`
|
||||
MixHash common.Hash `json:"mixHash"`
|
||||
Author common.Address `json:"author"`
|
||||
|
|
@ -146,9 +146,7 @@ func newAlethGenesisSpec(network string, genesis *core.Genesis) (*alethGenesisSp
|
|||
spec.Params.DurationLimit = (*math2.HexOrDecimal256)(params.DurationLimit)
|
||||
spec.Params.BlockReward = (*hexutil.Big)(ethash.FrontierBlockReward)
|
||||
|
||||
spec.Genesis.Nonce = (hexutil.Bytes)(make([]byte, 8))
|
||||
binary.LittleEndian.PutUint64(spec.Genesis.Nonce[:], genesis.Nonce)
|
||||
|
||||
spec.Genesis.Nonce = types.EncodeNonce(genesis.Nonce)
|
||||
spec.Genesis.MixHash = genesis.Mixhash
|
||||
spec.Genesis.Difficulty = (*hexutil.Big)(genesis.Difficulty)
|
||||
spec.Genesis.Author = genesis.Coinbase
|
||||
|
|
@ -278,7 +276,7 @@ type parityChainSpec struct {
|
|||
Genesis struct {
|
||||
Seal struct {
|
||||
Ethereum struct {
|
||||
Nonce hexutil.Bytes `json:"nonce"`
|
||||
Nonce types.BlockNonce `json:"nonce"`
|
||||
MixHash hexutil.Bytes `json:"mixHash"`
|
||||
} `json:"ethereum"`
|
||||
} `json:"seal"`
|
||||
|
|
@ -306,9 +304,8 @@ type parityChainSpecAccount struct {
|
|||
// parityChainSpecBuiltin is the precompiled contract definition.
|
||||
type parityChainSpecBuiltin struct {
|
||||
Name string `json:"name"` // Each builtin should has it own name
|
||||
Pricing *parityChainSpecPricing `json:"pricing"` // Each builtin should has it own price strategy
|
||||
Pricing interface{} `json:"pricing"` // Each builtin should has it own price strategy
|
||||
ActivateAt *hexutil.Big `json:"activate_at,omitempty"` // ActivateAt can't be omitted if empty, default means no fork
|
||||
EIP1108Transition *hexutil.Big `json:"eip1108_transition,omitempty"` // EIP1108Transition can't be omitted if empty, default means no fork
|
||||
}
|
||||
|
||||
// parityChainSpecPricing represents the different pricing models that builtin
|
||||
|
|
@ -316,8 +313,10 @@ type parityChainSpecBuiltin struct {
|
|||
type parityChainSpecPricing struct {
|
||||
Linear *parityChainSpecLinearPricing `json:"linear,omitempty"`
|
||||
ModExp *parityChainSpecModExpPricing `json:"modexp,omitempty"`
|
||||
AltBnPairing *parityChainSpecAltBnPairingPricing `json:"alt_bn128_pairing,omitempty"`
|
||||
AltBnConstOperation *parityChainSpecAltBnConstOperationPricing `json:"alt_bn128_const_operations,omitempty"`
|
||||
|
||||
// Before the https://github.com/paritytech/parity-ethereum/pull/11039,
|
||||
// Parity uses this format to config bn pairing price policy.
|
||||
AltBnPairing *parityChainSepcAltBnPairingPricing `json:"alt_bn128_pairing,omitempty"`
|
||||
|
||||
// Blake2F is the price per round of Blake2 compression
|
||||
Blake2F *parityChainSpecBlakePricing `json:"blake2_f,omitempty"`
|
||||
|
|
@ -332,22 +331,36 @@ type parityChainSpecModExpPricing struct {
|
|||
Divisor uint64 `json:"divisor"`
|
||||
}
|
||||
|
||||
// parityChainSpecAltBnConstOperationPricing defines the price
|
||||
// policy for bn const operation(used after istanbul)
|
||||
type parityChainSpecAltBnConstOperationPricing struct {
|
||||
Price uint64 `json:"price"`
|
||||
EIP1108TransitionPrice uint64 `json:"eip1108_transition_price,omitempty"` // Before Istanbul fork, this field is nil
|
||||
}
|
||||
|
||||
type parityChainSpecAltBnPairingPricing struct {
|
||||
// parityChainSepcAltBnPairingPricing defines the price policy
|
||||
// for bn pairing.
|
||||
type parityChainSepcAltBnPairingPricing struct {
|
||||
Base uint64 `json:"base"`
|
||||
Pair uint64 `json:"pair"`
|
||||
EIP1108TransitionBase uint64 `json:"eip1108_transition_base,omitempty"` // Before Istanbul fork, this field is nil
|
||||
EIP1108TransitionPair uint64 `json:"eip1108_transition_pair,omitempty"` // Before Istanbul fork, this field is nil
|
||||
}
|
||||
|
||||
// parityChainSpecBlakePricing defines the price policy for blake2 f
|
||||
// compression.
|
||||
type parityChainSpecBlakePricing struct {
|
||||
GasPerRound uint64 `json:"gas_per_round"`
|
||||
}
|
||||
|
||||
type parityChainSpecAlternativePrice struct {
|
||||
AltBnConstOperationPrice *parityChainSpecAltBnConstOperationPricing `json:"alt_bn128_const_operations,omitempty"`
|
||||
AltBnPairingPrice *parityChainSepcAltBnPairingPricing `json:"alt_bn128_pairing,omitempty"`
|
||||
}
|
||||
|
||||
// parityChainSpecVersionedPricing represents a single version price policy.
|
||||
type parityChainSpecVersionedPricing struct {
|
||||
Price *parityChainSpecAlternativePrice `json:"price,omitempty"`
|
||||
Info string `json:"info,omitempty"`
|
||||
}
|
||||
|
||||
// newParityChainSpec converts a go-ethereum genesis block into a Parity specific
|
||||
// chain specification format.
|
||||
func newParityChainSpec(network string, genesis *core.Genesis, bootnodes []string) (*parityChainSpec, error) {
|
||||
|
|
@ -411,10 +424,8 @@ func newParityChainSpec(network string, genesis *core.Genesis, bootnodes []strin
|
|||
// Disable this one
|
||||
spec.Params.EIP98Transition = math.MaxInt64
|
||||
|
||||
spec.Genesis.Seal.Ethereum.Nonce = (hexutil.Bytes)(make([]byte, 8))
|
||||
binary.LittleEndian.PutUint64(spec.Genesis.Seal.Ethereum.Nonce[:], genesis.Nonce)
|
||||
|
||||
spec.Genesis.Seal.Ethereum.MixHash = (hexutil.Bytes)(genesis.Mixhash[:])
|
||||
spec.Genesis.Seal.Ethereum.Nonce = types.EncodeNonce(genesis.Nonce)
|
||||
spec.Genesis.Seal.Ethereum.MixHash = (genesis.Mixhash[:])
|
||||
spec.Genesis.Difficulty = (*hexutil.Big)(genesis.Difficulty)
|
||||
spec.Genesis.Author = genesis.Coinbase
|
||||
spec.Genesis.Timestamp = (hexutil.Uint64)(genesis.Timestamp)
|
||||
|
|
@ -445,16 +456,32 @@ func newParityChainSpec(network string, genesis *core.Genesis, bootnodes []strin
|
|||
})
|
||||
if genesis.Config.ByzantiumBlock != nil {
|
||||
spec.setPrecompile(5, &parityChainSpecBuiltin{
|
||||
Name: "modexp", ActivateAt: (*hexutil.Big)(genesis.Config.ByzantiumBlock), Pricing: &parityChainSpecPricing{ModExp: &parityChainSpecModExpPricing{Divisor: 20}},
|
||||
Name: "modexp",
|
||||
ActivateAt: (*hexutil.Big)(genesis.Config.ByzantiumBlock),
|
||||
Pricing: &parityChainSpecPricing{
|
||||
ModExp: &parityChainSpecModExpPricing{Divisor: 20},
|
||||
},
|
||||
})
|
||||
spec.setPrecompile(6, &parityChainSpecBuiltin{
|
||||
Name: "alt_bn128_add", ActivateAt: (*hexutil.Big)(genesis.Config.ByzantiumBlock), Pricing: &parityChainSpecPricing{AltBnConstOperation: &parityChainSpecAltBnConstOperationPricing{Price: 500}},
|
||||
Name: "alt_bn128_add",
|
||||
ActivateAt: (*hexutil.Big)(genesis.Config.ByzantiumBlock),
|
||||
Pricing: &parityChainSpecPricing{
|
||||
Linear: &parityChainSpecLinearPricing{Base: 500, Word: 0},
|
||||
},
|
||||
})
|
||||
spec.setPrecompile(7, &parityChainSpecBuiltin{
|
||||
Name: "alt_bn128_mul", ActivateAt: (*hexutil.Big)(genesis.Config.ByzantiumBlock), Pricing: &parityChainSpecPricing{AltBnConstOperation: &parityChainSpecAltBnConstOperationPricing{Price: 40000}},
|
||||
Name: "alt_bn128_mul",
|
||||
ActivateAt: (*hexutil.Big)(genesis.Config.ByzantiumBlock),
|
||||
Pricing: &parityChainSpecPricing{
|
||||
Linear: &parityChainSpecLinearPricing{Base: 40000, Word: 0},
|
||||
},
|
||||
})
|
||||
spec.setPrecompile(8, &parityChainSpecBuiltin{
|
||||
Name: "alt_bn128_pairing", ActivateAt: (*hexutil.Big)(genesis.Config.ByzantiumBlock), Pricing: &parityChainSpecPricing{AltBnPairing: &parityChainSpecAltBnPairingPricing{Base: 100000, Pair: 80000}},
|
||||
Name: "alt_bn128_pairing",
|
||||
ActivateAt: (*hexutil.Big)(genesis.Config.ByzantiumBlock),
|
||||
Pricing: &parityChainSpecPricing{
|
||||
AltBnPairing: &parityChainSepcAltBnPairingPricing{Base: 100000, Pair: 80000},
|
||||
},
|
||||
})
|
||||
}
|
||||
if genesis.Config.IstanbulBlock != nil {
|
||||
|
|
@ -462,16 +489,59 @@ func newParityChainSpec(network string, genesis *core.Genesis, bootnodes []strin
|
|||
return nil, errors.New("invalid genesis, istanbul fork is enabled while byzantium is not")
|
||||
}
|
||||
spec.setPrecompile(6, &parityChainSpecBuiltin{
|
||||
Name: "alt_bn128_add", ActivateAt: (*hexutil.Big)(genesis.Config.ByzantiumBlock), EIP1108Transition: (*hexutil.Big)(genesis.Config.IstanbulBlock), Pricing: &parityChainSpecPricing{AltBnConstOperation: &parityChainSpecAltBnConstOperationPricing{Price: 500, EIP1108TransitionPrice: 150}},
|
||||
Name: "alt_bn128_add",
|
||||
ActivateAt: (*hexutil.Big)(genesis.Config.ByzantiumBlock),
|
||||
Pricing: map[*hexutil.Big]*parityChainSpecVersionedPricing{
|
||||
(*hexutil.Big)(big.NewInt(0)): {
|
||||
Price: &parityChainSpecAlternativePrice{
|
||||
AltBnConstOperationPrice: &parityChainSpecAltBnConstOperationPricing{Price: 500},
|
||||
},
|
||||
},
|
||||
(*hexutil.Big)(genesis.Config.IstanbulBlock): {
|
||||
Price: &parityChainSpecAlternativePrice{
|
||||
AltBnConstOperationPrice: &parityChainSpecAltBnConstOperationPricing{Price: 150},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
spec.setPrecompile(7, &parityChainSpecBuiltin{
|
||||
Name: "alt_bn128_mul", ActivateAt: (*hexutil.Big)(genesis.Config.ByzantiumBlock), EIP1108Transition: (*hexutil.Big)(genesis.Config.IstanbulBlock), Pricing: &parityChainSpecPricing{AltBnConstOperation: &parityChainSpecAltBnConstOperationPricing{Price: 40000, EIP1108TransitionPrice: 6000}},
|
||||
Name: "alt_bn128_mul",
|
||||
ActivateAt: (*hexutil.Big)(genesis.Config.ByzantiumBlock),
|
||||
Pricing: map[*hexutil.Big]*parityChainSpecVersionedPricing{
|
||||
(*hexutil.Big)(big.NewInt(0)): {
|
||||
Price: &parityChainSpecAlternativePrice{
|
||||
AltBnConstOperationPrice: &parityChainSpecAltBnConstOperationPricing{Price: 40000},
|
||||
},
|
||||
},
|
||||
(*hexutil.Big)(genesis.Config.IstanbulBlock): {
|
||||
Price: &parityChainSpecAlternativePrice{
|
||||
AltBnConstOperationPrice: &parityChainSpecAltBnConstOperationPricing{Price: 6000},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
spec.setPrecompile(8, &parityChainSpecBuiltin{
|
||||
Name: "alt_bn128_pairing", ActivateAt: (*hexutil.Big)(genesis.Config.ByzantiumBlock), EIP1108Transition: (*hexutil.Big)(genesis.Config.IstanbulBlock), Pricing: &parityChainSpecPricing{AltBnPairing: &parityChainSpecAltBnPairingPricing{Base: 100000, Pair: 80000, EIP1108TransitionBase: 45000, EIP1108TransitionPair: 34000}},
|
||||
Name: "alt_bn128_pairing",
|
||||
ActivateAt: (*hexutil.Big)(genesis.Config.ByzantiumBlock),
|
||||
Pricing: map[*hexutil.Big]*parityChainSpecVersionedPricing{
|
||||
(*hexutil.Big)(big.NewInt(0)): {
|
||||
Price: &parityChainSpecAlternativePrice{
|
||||
AltBnPairingPrice: &parityChainSepcAltBnPairingPricing{Base: 100000, Pair: 80000},
|
||||
},
|
||||
},
|
||||
(*hexutil.Big)(genesis.Config.IstanbulBlock): {
|
||||
Price: &parityChainSpecAlternativePrice{
|
||||
AltBnPairingPrice: &parityChainSepcAltBnPairingPricing{Base: 45000, Pair: 34000},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
spec.setPrecompile(9, &parityChainSpecBuiltin{
|
||||
Name: "blake2_f", ActivateAt: (*hexutil.Big)(genesis.Config.IstanbulBlock), Pricing: &parityChainSpecPricing{Blake2F: &parityChainSpecBlakePricing{GasPerRound: 1}},
|
||||
Name: "blake2_f",
|
||||
ActivateAt: (*hexutil.Big)(genesis.Config.IstanbulBlock),
|
||||
Pricing: &parityChainSpecPricing{
|
||||
Blake2F: &parityChainSpecBlakePricing{GasPerRound: 1},
|
||||
},
|
||||
})
|
||||
}
|
||||
return spec, nil
|
||||
|
|
@ -514,8 +584,6 @@ func (spec *parityChainSpec) setConstantinopleFix(num *big.Int) {
|
|||
}
|
||||
|
||||
func (spec *parityChainSpec) setIstanbul(num *big.Int) {
|
||||
// spec.Params.EIP152Transition = hexutil.Uint64(num.Uint64())
|
||||
// spec.Params.EIP1108Transition = hexutil.Uint64(num.Uint64())
|
||||
spec.Params.EIP1344Transition = hexutil.Uint64(num.Uint64())
|
||||
spec.Params.EIP1884Transition = hexutil.Uint64(num.Uint64())
|
||||
spec.Params.EIP2028Transition = hexutil.Uint64(num.Uint64())
|
||||
|
|
@ -525,7 +593,7 @@ func (spec *parityChainSpec) setIstanbul(num *big.Int) {
|
|||
// pyEthereumGenesisSpec represents the genesis specification format used by the
|
||||
// Python Ethereum implementation.
|
||||
type pyEthereumGenesisSpec struct {
|
||||
Nonce hexutil.Bytes `json:"nonce"`
|
||||
Nonce types.BlockNonce `json:"nonce"`
|
||||
Timestamp hexutil.Uint64 `json:"timestamp"`
|
||||
ExtraData hexutil.Bytes `json:"extraData"`
|
||||
GasLimit hexutil.Uint64 `json:"gasLimit"`
|
||||
|
|
@ -544,6 +612,7 @@ func newPyEthereumGenesisSpec(network string, genesis *core.Genesis) (*pyEthereu
|
|||
return nil, errors.New("unsupported consensus engine")
|
||||
}
|
||||
spec := &pyEthereumGenesisSpec{
|
||||
Nonce: types.EncodeNonce(genesis.Nonce),
|
||||
Timestamp: (hexutil.Uint64)(genesis.Timestamp),
|
||||
ExtraData: genesis.ExtraData,
|
||||
GasLimit: (hexutil.Uint64)(genesis.GasLimit),
|
||||
|
|
@ -553,8 +622,5 @@ func newPyEthereumGenesisSpec(network string, genesis *core.Genesis) (*pyEthereu
|
|||
Alloc: genesis.Alloc,
|
||||
ParentHash: genesis.ParentHash,
|
||||
}
|
||||
spec.Nonce = (hexutil.Bytes)(make([]byte, 8))
|
||||
binary.LittleEndian.PutUint64(spec.Nonce[:], genesis.Nonce)
|
||||
|
||||
return spec, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
|
|
@ -80,29 +81,15 @@ func TestParitySturebyConverter(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("failed creating chainspec: %v", err)
|
||||
}
|
||||
|
||||
enc, err := json.MarshalIndent(spec, "", " ")
|
||||
if err != nil {
|
||||
t.Fatalf("failed encoding chainspec: %v", err)
|
||||
}
|
||||
expBlob, err := ioutil.ReadFile("testdata/stureby_parity.json")
|
||||
if err != nil {
|
||||
t.Fatalf("could not read file: %v", err)
|
||||
}
|
||||
expspec := &parityChainSpec{}
|
||||
if err := json.Unmarshal(expBlob, expspec); err != nil {
|
||||
t.Fatalf("failed parsing genesis: %v", err)
|
||||
}
|
||||
expspec.Nodes = []string{}
|
||||
|
||||
if !reflect.DeepEqual(expspec, spec) {
|
||||
t.Errorf("chainspec mismatch")
|
||||
c := spew.ConfigState{
|
||||
DisablePointerAddresses: true,
|
||||
SortKeys: true,
|
||||
}
|
||||
exp := strings.Split(c.Sdump(expspec), "\n")
|
||||
got := strings.Split(c.Sdump(spec), "\n")
|
||||
for i := 0; i < len(exp) && i < len(got); i++ {
|
||||
if exp[i] != got[i] {
|
||||
t.Logf("got: %v\nexp: %v\n", exp[i], got[i])
|
||||
}
|
||||
}
|
||||
if !bytes.Equal(expBlob, enc) {
|
||||
t.Fatalf("chainspec mismatch")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ func dial(server string, pubkey []byte) (*sshClient, error) {
|
|||
fmt.Printf("SSH key fingerprint is %s [MD5]\n", ssh.FingerprintLegacyMD5(key))
|
||||
fmt.Printf("Are you sure you want to continue connecting (yes/no)? ")
|
||||
|
||||
for {
|
||||
text, err := bufio.NewReader(os.Stdin).ReadString('\n')
|
||||
switch {
|
||||
case err != nil:
|
||||
|
|
@ -136,8 +137,12 @@ func dial(server string, pubkey []byte) (*sshClient, error) {
|
|||
case strings.TrimSpace(text) == "yes":
|
||||
pubkey = key.Marshal()
|
||||
return nil
|
||||
case strings.TrimSpace(text) == "no":
|
||||
return errors.New("users says no")
|
||||
default:
|
||||
return fmt.Errorf("unknown auth choice: %v", text)
|
||||
fmt.Println("Please answer 'yes' or 'no'")
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
// If a public key exists for this SSH server, check that it matches
|
||||
|
|
|
|||
53
cmd/puppeth/testdata/stureby_parity.json
vendored
53
cmd/puppeth/testdata/stureby_parity.json
vendored
|
|
@ -131,13 +131,22 @@
|
|||
"builtin": {
|
||||
"name": "alt_bn128_add",
|
||||
"pricing": {
|
||||
"0x0": {
|
||||
"price": {
|
||||
"alt_bn128_const_operations": {
|
||||
"price": 500,
|
||||
"eip1108_transition_price": 150
|
||||
"price": 500
|
||||
}
|
||||
}
|
||||
},
|
||||
"activate_at": "0x7530",
|
||||
"eip1108_transition": "0xc350"
|
||||
"0xc350": {
|
||||
"price": {
|
||||
"alt_bn128_const_operations": {
|
||||
"price": 150
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"activate_at": "0x7530"
|
||||
}
|
||||
},
|
||||
"0000000000000000000000000000000000000007": {
|
||||
|
|
@ -145,13 +154,22 @@
|
|||
"builtin": {
|
||||
"name": "alt_bn128_mul",
|
||||
"pricing": {
|
||||
"0x0": {
|
||||
"price": {
|
||||
"alt_bn128_const_operations": {
|
||||
"price": 40000,
|
||||
"eip1108_transition_price": 6000
|
||||
"price": 40000
|
||||
}
|
||||
}
|
||||
},
|
||||
"activate_at": "0x7530",
|
||||
"eip1108_transition": "0xc350"
|
||||
"0xc350": {
|
||||
"price": {
|
||||
"alt_bn128_const_operations": {
|
||||
"price": 6000
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"activate_at": "0x7530"
|
||||
}
|
||||
},
|
||||
"0000000000000000000000000000000000000008": {
|
||||
|
|
@ -159,15 +177,24 @@
|
|||
"builtin": {
|
||||
"name": "alt_bn128_pairing",
|
||||
"pricing": {
|
||||
"0x0": {
|
||||
"price": {
|
||||
"alt_bn128_pairing": {
|
||||
"base": 100000,
|
||||
"pair": 80000,
|
||||
"eip1108_transition_base": 45000,
|
||||
"eip1108_transition_pair": 34000
|
||||
"pair": 80000
|
||||
}
|
||||
}
|
||||
},
|
||||
"activate_at": "0x7530",
|
||||
"eip1108_transition": "0xc350"
|
||||
"0xc350": {
|
||||
"price": {
|
||||
"alt_bn128_pairing": {
|
||||
"base": 45000,
|
||||
"pair": 34000
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"activate_at": "0x7530"
|
||||
}
|
||||
},
|
||||
"0000000000000000000000000000000000000009": {
|
||||
|
|
|
|||
|
|
@ -77,6 +77,17 @@ SUBCOMMANDS:
|
|||
{{range $categorized.Flags}}{{"\t"}}{{.}}
|
||||
{{end}}
|
||||
{{end}}{{end}}`
|
||||
|
||||
OriginCommandHelpTemplate = `{{.Name}}{{if .Subcommands}} command{{end}}{{if .Flags}} [command options]{{end}} [arguments...]
|
||||
{{if .Description}}{{.Description}}
|
||||
{{end}}{{if .Subcommands}}
|
||||
SUBCOMMANDS:
|
||||
{{range .Subcommands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}
|
||||
{{end}}{{end}}{{if .Flags}}
|
||||
OPTIONS:
|
||||
{{range $.Flags}}{{"\t"}}{{.}}
|
||||
{{end}}
|
||||
{{end}}`
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
|
|
|||
|
|
@ -19,41 +19,43 @@ package common
|
|||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
checker "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
type BytesSuite struct{}
|
||||
func TestCopyBytes(t *testing.T) {
|
||||
input := []byte{1, 2, 3, 4}
|
||||
|
||||
var _ = checker.Suite(&BytesSuite{})
|
||||
|
||||
func (s *BytesSuite) TestCopyBytes(c *checker.C) {
|
||||
data1 := []byte{1, 2, 3, 4}
|
||||
exp1 := []byte{1, 2, 3, 4}
|
||||
res1 := CopyBytes(data1)
|
||||
c.Assert(res1, checker.DeepEquals, exp1)
|
||||
v := CopyBytes(input)
|
||||
if !bytes.Equal(v, []byte{1, 2, 3, 4}) {
|
||||
t.Fatal("not equal after copy")
|
||||
}
|
||||
v[0] = 99
|
||||
if bytes.Equal(v, input) {
|
||||
t.Fatal("result is not a copy")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *BytesSuite) TestLeftPadBytes(c *checker.C) {
|
||||
val1 := []byte{1, 2, 3, 4}
|
||||
exp1 := []byte{0, 0, 0, 0, 1, 2, 3, 4}
|
||||
|
||||
res1 := LeftPadBytes(val1, 8)
|
||||
res2 := LeftPadBytes(val1, 2)
|
||||
|
||||
c.Assert(res1, checker.DeepEquals, exp1)
|
||||
c.Assert(res2, checker.DeepEquals, val1)
|
||||
}
|
||||
|
||||
func (s *BytesSuite) TestRightPadBytes(c *checker.C) {
|
||||
func TestLeftPadBytes(t *testing.T) {
|
||||
val := []byte{1, 2, 3, 4}
|
||||
exp := []byte{1, 2, 3, 4, 0, 0, 0, 0}
|
||||
padded := []byte{0, 0, 0, 0, 1, 2, 3, 4}
|
||||
|
||||
resstd := RightPadBytes(val, 8)
|
||||
resshrt := RightPadBytes(val, 2)
|
||||
if r := LeftPadBytes(val, 8); !bytes.Equal(r, padded) {
|
||||
t.Fatalf("LeftPadBytes(%v, 8) == %v", val, r)
|
||||
}
|
||||
if r := LeftPadBytes(val, 2); !bytes.Equal(r, val) {
|
||||
t.Fatalf("LeftPadBytes(%v, 2) == %v", val, r)
|
||||
}
|
||||
}
|
||||
|
||||
c.Assert(resstd, checker.DeepEquals, exp)
|
||||
c.Assert(resshrt, checker.DeepEquals, val)
|
||||
func TestRightPadBytes(t *testing.T) {
|
||||
val := []byte{1, 2, 3, 4}
|
||||
padded := []byte{1, 2, 3, 4, 0, 0, 0, 0}
|
||||
|
||||
if r := RightPadBytes(val, 8); !bytes.Equal(r, padded) {
|
||||
t.Fatalf("RightPadBytes(%v, 8) == %v", val, r)
|
||||
}
|
||||
if r := RightPadBytes(val, 2); !bytes.Equal(r, val) {
|
||||
t.Fatalf("RightPadBytes(%v, 2) == %v", val, r)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFromHex(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ func (b *Bytes) UnmarshalGraphQL(input interface{}) error {
|
|||
}
|
||||
*b = data
|
||||
default:
|
||||
err = fmt.Errorf("Unexpected type for Bytes: %v", input)
|
||||
err = fmt.Errorf("unexpected type %T for Bytes", input)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
@ -220,7 +220,7 @@ func (b *Big) UnmarshalGraphQL(input interface{}) error {
|
|||
num.SetInt64(int64(input))
|
||||
*b = Big(num)
|
||||
default:
|
||||
err = fmt.Errorf("Unexpected type for BigInt: %v", input)
|
||||
err = fmt.Errorf("unexpected type %T for BigInt", input)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
@ -284,7 +284,7 @@ func (b *Uint64) UnmarshalGraphQL(input interface{}) error {
|
|||
case int32:
|
||||
*b = Uint64(input)
|
||||
default:
|
||||
err = fmt.Errorf("Unexpected type for Long: %v", input)
|
||||
err = fmt.Errorf("unexpected type %T for Long", input)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
// Copyright 2014 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 common
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
checker "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) { checker.TestingT(t) }
|
||||
|
|
@ -20,6 +20,7 @@ import (
|
|||
"database/sql/driver"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
|
|
@ -142,7 +143,7 @@ func (h Hash) Value() (driver.Value, error) {
|
|||
}
|
||||
|
||||
// ImplementsGraphQLType returns true if Hash implements the specified GraphQL type.
|
||||
func (_ Hash) ImplementsGraphQLType(name string) bool { return name == "Bytes32" }
|
||||
func (Hash) ImplementsGraphQLType(name string) bool { return name == "Bytes32" }
|
||||
|
||||
// UnmarshalGraphQL unmarshals the provided GraphQL query data.
|
||||
func (h *Hash) UnmarshalGraphQL(input interface{}) error {
|
||||
|
|
@ -151,7 +152,7 @@ func (h *Hash) UnmarshalGraphQL(input interface{}) error {
|
|||
case string:
|
||||
err = h.UnmarshalText([]byte(input))
|
||||
default:
|
||||
err = fmt.Errorf("Unexpected type for Bytes32: %v", input)
|
||||
err = fmt.Errorf("unexpected type %T for Hash", input)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
@ -290,7 +291,7 @@ func (a *Address) UnmarshalGraphQL(input interface{}) error {
|
|||
case string:
|
||||
err = a.UnmarshalText([]byte(input))
|
||||
default:
|
||||
err = fmt.Errorf("Unexpected type for Address: %v", input)
|
||||
err = fmt.Errorf("unexpected type %T for Address", input)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
@ -323,7 +324,7 @@ func NewMixedcaseAddress(addr Address) MixedcaseAddress {
|
|||
// NewMixedcaseAddressFromString is mainly meant for unit-testing
|
||||
func NewMixedcaseAddressFromString(hexaddr string) (*MixedcaseAddress, error) {
|
||||
if !IsHexAddress(hexaddr) {
|
||||
return nil, fmt.Errorf("Invalid address")
|
||||
return nil, errors.New("invalid address")
|
||||
}
|
||||
a := FromHex(hexaddr)
|
||||
return &MixedcaseAddress{addr: BytesToAddress(a), original: hexaddr}, nil
|
||||
|
|
|
|||
|
|
@ -60,6 +60,14 @@ func TestLexer(t *testing.T) {
|
|||
input: "0123abc",
|
||||
tokens: []token{{typ: lineStart}, {typ: number, text: "0123"}, {typ: element, text: "abc"}, {typ: eof}},
|
||||
},
|
||||
{
|
||||
input: "@foo",
|
||||
tokens: []token{{typ: lineStart}, {typ: label, text: "foo"}, {typ: eof}},
|
||||
},
|
||||
{
|
||||
input: "@label123",
|
||||
tokens: []token{{typ: lineStart}, {typ: label, text: "label123"}, {typ: eof}},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ func lexComment(l *lexer) stateFn {
|
|||
// the lex text state function to advance the parsing
|
||||
// process.
|
||||
func lexLabel(l *lexer) stateFn {
|
||||
l.acceptRun(Alpha + "_")
|
||||
l.acceptRun(Alpha + "_" + Numbers)
|
||||
|
||||
l.emit(label)
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
"io"
|
||||
"math/big"
|
||||
mrand "math/rand"
|
||||
"sort"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
|
@ -855,8 +856,9 @@ func (bc *BlockChain) procFutureBlocks() {
|
|||
}
|
||||
}
|
||||
if len(blocks) > 0 {
|
||||
types.BlockBy(types.Number).Sort(blocks)
|
||||
|
||||
sort.Slice(blocks, func(i, j int) bool {
|
||||
return blocks[i].NumberU64() < blocks[j].NumberU64()
|
||||
})
|
||||
// Insert one by one as chain insertion needs contiguous ancestry between blocks
|
||||
for i := range blocks {
|
||||
bc.InsertChain(blocks[i : i+1])
|
||||
|
|
|
|||
|
|
@ -1292,14 +1292,17 @@ func TestCanonicalBlockRetrieval(t *testing.T) {
|
|||
continue // busy wait for canonical hash to be written
|
||||
}
|
||||
if ch != block.Hash() {
|
||||
t.Fatalf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex())
|
||||
t.Errorf("unknown canonical hash, want %s, got %s", block.Hash().Hex(), ch.Hex())
|
||||
return
|
||||
}
|
||||
fb := rawdb.ReadBlock(blockchain.db, ch, block.NumberU64())
|
||||
if fb == nil {
|
||||
t.Fatalf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex())
|
||||
t.Errorf("unable to retrieve block %d for canonical hash: %s", block.NumberU64(), ch.Hex())
|
||||
return
|
||||
}
|
||||
if fb.Hash() != block.Hash() {
|
||||
t.Fatalf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex())
|
||||
t.Errorf("invalid block hash for block %d, want %s, got %s", block.NumberU64(), block.Hash().Hex(), fb.Hash().Hex())
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
@ -1919,13 +1922,6 @@ func testInsertKnownChainData(t *testing.T, typ string) {
|
|||
inserter func(blocks []*types.Block, receipts []types.Receipts) error
|
||||
asserter func(t *testing.T, block *types.Block)
|
||||
)
|
||||
headers, headers2 := make([]*types.Header, 0, len(blocks)), make([]*types.Header, 0, len(blocks2))
|
||||
for _, block := range blocks {
|
||||
headers = append(headers, block.Header())
|
||||
}
|
||||
for _, block := range blocks2 {
|
||||
headers2 = append(headers2, block.Header())
|
||||
}
|
||||
if typ == "headers" {
|
||||
inserter = func(blocks []*types.Block, receipts []types.Receipts) error {
|
||||
headers := make([]*types.Header, 0, len(blocks))
|
||||
|
|
|
|||
|
|
@ -284,7 +284,6 @@ func makeBlockChain(parent *types.Block, n int, engine consensus.Engine, db ethd
|
|||
|
||||
type fakeChainReader struct {
|
||||
config *params.ChainConfig
|
||||
genesis *types.Block
|
||||
}
|
||||
|
||||
// Config returns the chain configuration.
|
||||
|
|
|
|||
|
|
@ -1,87 +0,0 @@
|
|||
// Copyright 2014 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 core
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
)
|
||||
|
||||
// Implement our EthTest Manager
|
||||
type TestManager struct {
|
||||
// stateManager *StateManager
|
||||
eventMux *event.TypeMux
|
||||
|
||||
db ethdb.Database
|
||||
txPool *TxPool
|
||||
blockChain *BlockChain
|
||||
Blocks []*types.Block
|
||||
}
|
||||
|
||||
func (tm *TestManager) IsListening() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (tm *TestManager) IsMining() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (tm *TestManager) PeerCount() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (tm *TestManager) Peers() *list.List {
|
||||
return list.New()
|
||||
}
|
||||
|
||||
func (tm *TestManager) BlockChain() *BlockChain {
|
||||
return tm.blockChain
|
||||
}
|
||||
|
||||
func (tm *TestManager) TxPool() *TxPool {
|
||||
return tm.txPool
|
||||
}
|
||||
|
||||
// func (tm *TestManager) StateManager() *StateManager {
|
||||
// return tm.stateManager
|
||||
// }
|
||||
|
||||
func (tm *TestManager) EventMux() *event.TypeMux {
|
||||
return tm.eventMux
|
||||
}
|
||||
|
||||
// func (tm *TestManager) KeyManager() *crypto.KeyManager {
|
||||
// return nil
|
||||
// }
|
||||
|
||||
func (tm *TestManager) Db() ethdb.Database {
|
||||
return tm.db
|
||||
}
|
||||
|
||||
func NewTestManager() *TestManager {
|
||||
testManager := &TestManager{}
|
||||
testManager.eventMux = new(event.TypeMux)
|
||||
testManager.db = rawdb.NewMemoryDatabase()
|
||||
// testManager.txPool = NewTxPool(testManager)
|
||||
// testManager.blockChain = NewBlockChain(testManager)
|
||||
// testManager.stateManager = NewStateManager(testManager)
|
||||
return testManager
|
||||
}
|
||||
|
|
@ -47,7 +47,9 @@ type Dump struct {
|
|||
}
|
||||
|
||||
// iterativeDump is a 'collector'-implementation which dump output line-by-line iteratively
|
||||
type iterativeDump json.Encoder
|
||||
type iterativeDump struct {
|
||||
*json.Encoder
|
||||
}
|
||||
|
||||
// Collector interface which the state trie calls during iteration
|
||||
type collector interface {
|
||||
|
|
@ -55,15 +57,15 @@ type collector interface {
|
|||
onAccount(common.Address, DumpAccount)
|
||||
}
|
||||
|
||||
func (self *Dump) onRoot(root common.Hash) {
|
||||
self.Root = fmt.Sprintf("%x", root)
|
||||
func (d *Dump) onRoot(root common.Hash) {
|
||||
d.Root = fmt.Sprintf("%x", root)
|
||||
}
|
||||
|
||||
func (self *Dump) onAccount(addr common.Address, account DumpAccount) {
|
||||
self.Accounts[addr] = account
|
||||
func (d *Dump) onAccount(addr common.Address, account DumpAccount) {
|
||||
d.Accounts[addr] = account
|
||||
}
|
||||
|
||||
func (self iterativeDump) onAccount(addr common.Address, account DumpAccount) {
|
||||
func (d iterativeDump) onAccount(addr common.Address, account DumpAccount) {
|
||||
dumpAccount := &DumpAccount{
|
||||
Balance: account.Balance,
|
||||
Nonce: account.Nonce,
|
||||
|
|
@ -77,25 +79,26 @@ func (self iterativeDump) onAccount(addr common.Address, account DumpAccount) {
|
|||
if addr != (common.Address{}) {
|
||||
dumpAccount.Address = &addr
|
||||
}
|
||||
(*json.Encoder)(&self).Encode(dumpAccount)
|
||||
d.Encode(dumpAccount)
|
||||
}
|
||||
func (self iterativeDump) onRoot(root common.Hash) {
|
||||
(*json.Encoder)(&self).Encode(struct {
|
||||
|
||||
func (d iterativeDump) onRoot(root common.Hash) {
|
||||
d.Encode(struct {
|
||||
Root common.Hash `json:"root"`
|
||||
}{root})
|
||||
}
|
||||
|
||||
func (self *StateDB) dump(c collector, excludeCode, excludeStorage, excludeMissingPreimages bool) {
|
||||
func (s *StateDB) dump(c collector, excludeCode, excludeStorage, excludeMissingPreimages bool) {
|
||||
emptyAddress := (common.Address{})
|
||||
missingPreimages := 0
|
||||
c.onRoot(self.trie.Hash())
|
||||
it := trie.NewIterator(self.trie.NodeIterator(nil))
|
||||
c.onRoot(s.trie.Hash())
|
||||
it := trie.NewIterator(s.trie.NodeIterator(nil))
|
||||
for it.Next() {
|
||||
var data Account
|
||||
if err := rlp.DecodeBytes(it.Value, &data); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
addr := common.BytesToAddress(self.trie.GetKey(it.Key))
|
||||
addr := common.BytesToAddress(s.trie.GetKey(it.Key))
|
||||
obj := newObject(nil, addr, data)
|
||||
account := DumpAccount{
|
||||
Balance: data.Balance.String(),
|
||||
|
|
@ -112,18 +115,18 @@ func (self *StateDB) dump(c collector, excludeCode, excludeStorage, excludeMissi
|
|||
account.SecureKey = it.Key
|
||||
}
|
||||
if !excludeCode {
|
||||
account.Code = common.Bytes2Hex(obj.Code(self.db))
|
||||
account.Code = common.Bytes2Hex(obj.Code(s.db))
|
||||
}
|
||||
if !excludeStorage {
|
||||
account.Storage = make(map[common.Hash]string)
|
||||
storageIt := trie.NewIterator(obj.getTrie(self.db).NodeIterator(nil))
|
||||
storageIt := trie.NewIterator(obj.getTrie(s.db).NodeIterator(nil))
|
||||
for storageIt.Next() {
|
||||
_, content, _, err := rlp.Split(storageIt.Value)
|
||||
if err != nil {
|
||||
log.Error("Failed to decode the value returned by iterator", "error", err)
|
||||
continue
|
||||
}
|
||||
account.Storage[common.BytesToHash(self.trie.GetKey(storageIt.Key))] = common.Bytes2Hex(content)
|
||||
account.Storage[common.BytesToHash(s.trie.GetKey(storageIt.Key))] = common.Bytes2Hex(content)
|
||||
}
|
||||
}
|
||||
c.onAccount(addr, account)
|
||||
|
|
@ -134,17 +137,17 @@ func (self *StateDB) dump(c collector, excludeCode, excludeStorage, excludeMissi
|
|||
}
|
||||
|
||||
// RawDump returns the entire state an a single large object
|
||||
func (self *StateDB) RawDump(excludeCode, excludeStorage, excludeMissingPreimages bool) Dump {
|
||||
func (s *StateDB) RawDump(excludeCode, excludeStorage, excludeMissingPreimages bool) Dump {
|
||||
dump := &Dump{
|
||||
Accounts: make(map[common.Address]DumpAccount),
|
||||
}
|
||||
self.dump(dump, excludeCode, excludeStorage, excludeMissingPreimages)
|
||||
s.dump(dump, excludeCode, excludeStorage, excludeMissingPreimages)
|
||||
return *dump
|
||||
}
|
||||
|
||||
// Dump returns a JSON string representing the entire state as a single json-object
|
||||
func (self *StateDB) Dump(excludeCode, excludeStorage, excludeMissingPreimages bool) []byte {
|
||||
dump := self.RawDump(excludeCode, excludeStorage, excludeMissingPreimages)
|
||||
func (s *StateDB) Dump(excludeCode, excludeStorage, excludeMissingPreimages bool) []byte {
|
||||
dump := s.RawDump(excludeCode, excludeStorage, excludeMissingPreimages)
|
||||
json, err := json.MarshalIndent(dump, "", " ")
|
||||
if err != nil {
|
||||
fmt.Println("dump err", err)
|
||||
|
|
@ -153,6 +156,6 @@ func (self *StateDB) Dump(excludeCode, excludeStorage, excludeMissingPreimages b
|
|||
}
|
||||
|
||||
// IterativeDump dumps out accounts as json-objects, delimited by linebreaks on stdout
|
||||
func (self *StateDB) IterativeDump(excludeCode, excludeStorage, excludeMissingPreimages bool, output *json.Encoder) {
|
||||
self.dump(iterativeDump(*output), excludeCode, excludeStorage, excludeMissingPreimages)
|
||||
func (s *StateDB) IterativeDump(excludeCode, excludeStorage, excludeMissingPreimages bool, output *json.Encoder) {
|
||||
s.dump(iterativeDump{output}, excludeCode, excludeStorage, excludeMissingPreimages)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,8 +128,6 @@ type (
|
|||
}
|
||||
touchChange struct {
|
||||
account *common.Address
|
||||
prev bool
|
||||
prevDirty bool
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
// Copyright 2014 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 state
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
checker "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) { checker.TestingT(t) }
|
||||
|
|
@ -25,19 +25,24 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
checker "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
type StateSuite struct {
|
||||
var toAddr = common.BytesToAddress
|
||||
|
||||
type stateTest struct {
|
||||
db ethdb.Database
|
||||
state *StateDB
|
||||
}
|
||||
|
||||
var _ = checker.Suite(&StateSuite{})
|
||||
func newStateTest() *stateTest {
|
||||
db := rawdb.NewMemoryDatabase()
|
||||
sdb, _ := New(common.Hash{}, NewDatabase(db))
|
||||
return &stateTest{db: db, state: sdb}
|
||||
}
|
||||
|
||||
var toAddr = common.BytesToAddress
|
||||
func TestDump(t *testing.T) {
|
||||
s := newStateTest()
|
||||
|
||||
func (s *StateSuite) TestDump(c *checker.C) {
|
||||
// generate a few entries
|
||||
obj1 := s.state.GetOrNewStateObject(toAddr([]byte{0x01}))
|
||||
obj1.AddBalance(big.NewInt(22))
|
||||
|
|
@ -78,16 +83,12 @@ func (s *StateSuite) TestDump(c *checker.C) {
|
|||
}
|
||||
}`
|
||||
if got != want {
|
||||
c.Errorf("dump mismatch:\ngot: %s\nwant: %s\n", got, want)
|
||||
t.Errorf("dump mismatch:\ngot: %s\nwant: %s\n", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *StateSuite) SetUpTest(c *checker.C) {
|
||||
s.db = rawdb.NewMemoryDatabase()
|
||||
s.state, _ = New(common.Hash{}, NewDatabase(s.db))
|
||||
}
|
||||
|
||||
func (s *StateSuite) TestNull(c *checker.C) {
|
||||
func TestNull(t *testing.T) {
|
||||
s := newStateTest()
|
||||
address := common.HexToAddress("0x823140710bf13990e4500136726d8b55")
|
||||
s.state.CreateAccount(address)
|
||||
//value := common.FromHex("0x823140710bf13990e4500136726d8b55")
|
||||
|
|
@ -97,18 +98,19 @@ func (s *StateSuite) TestNull(c *checker.C) {
|
|||
s.state.Commit(false)
|
||||
|
||||
if value := s.state.GetState(address, common.Hash{}); value != (common.Hash{}) {
|
||||
c.Errorf("expected empty current value, got %x", value)
|
||||
t.Errorf("expected empty current value, got %x", value)
|
||||
}
|
||||
if value := s.state.GetCommittedState(address, common.Hash{}); value != (common.Hash{}) {
|
||||
c.Errorf("expected empty committed value, got %x", value)
|
||||
t.Errorf("expected empty committed value, got %x", value)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *StateSuite) TestSnapshot(c *checker.C) {
|
||||
func TestSnapshot(t *testing.T) {
|
||||
stateobjaddr := toAddr([]byte("aa"))
|
||||
var storageaddr common.Hash
|
||||
data1 := common.BytesToHash([]byte{42})
|
||||
data2 := common.BytesToHash([]byte{43})
|
||||
s := newStateTest()
|
||||
|
||||
// snapshot the genesis state
|
||||
genesis := s.state.Snapshot()
|
||||
|
|
@ -121,21 +123,28 @@ func (s *StateSuite) TestSnapshot(c *checker.C) {
|
|||
s.state.SetState(stateobjaddr, storageaddr, data2)
|
||||
s.state.RevertToSnapshot(snapshot)
|
||||
|
||||
c.Assert(s.state.GetState(stateobjaddr, storageaddr), checker.DeepEquals, data1)
|
||||
c.Assert(s.state.GetCommittedState(stateobjaddr, storageaddr), checker.DeepEquals, common.Hash{})
|
||||
if v := s.state.GetState(stateobjaddr, storageaddr); v != data1 {
|
||||
t.Errorf("wrong storage value %v, want %v", v, data1)
|
||||
}
|
||||
if v := s.state.GetCommittedState(stateobjaddr, storageaddr); v != (common.Hash{}) {
|
||||
t.Errorf("wrong committed storage value %v, want %v", v, common.Hash{})
|
||||
}
|
||||
|
||||
// revert up to the genesis state and ensure correct content
|
||||
s.state.RevertToSnapshot(genesis)
|
||||
c.Assert(s.state.GetState(stateobjaddr, storageaddr), checker.DeepEquals, common.Hash{})
|
||||
c.Assert(s.state.GetCommittedState(stateobjaddr, storageaddr), checker.DeepEquals, common.Hash{})
|
||||
if v := s.state.GetState(stateobjaddr, storageaddr); v != (common.Hash{}) {
|
||||
t.Errorf("wrong storage value %v, want %v", v, common.Hash{})
|
||||
}
|
||||
if v := s.state.GetCommittedState(stateobjaddr, storageaddr); v != (common.Hash{}) {
|
||||
t.Errorf("wrong committed storage value %v, want %v", v, common.Hash{})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *StateSuite) TestSnapshotEmpty(c *checker.C) {
|
||||
func TestSnapshotEmpty(t *testing.T) {
|
||||
s := newStateTest()
|
||||
s.state.RevertToSnapshot(s.state.Snapshot())
|
||||
}
|
||||
|
||||
// use testing instead of checker because checker does not support
|
||||
// printing/logging in tests (-check.vv does not work)
|
||||
func TestSnapshot2(t *testing.T) {
|
||||
state, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()))
|
||||
|
||||
|
|
|
|||
|
|
@ -124,115 +124,115 @@ func New(root common.Hash, db Database) (*StateDB, error) {
|
|||
}
|
||||
|
||||
// setError remembers the first non-nil error it is called with.
|
||||
func (self *StateDB) setError(err error) {
|
||||
if self.dbErr == nil {
|
||||
self.dbErr = err
|
||||
func (s *StateDB) setError(err error) {
|
||||
if s.dbErr == nil {
|
||||
s.dbErr = err
|
||||
}
|
||||
}
|
||||
|
||||
func (self *StateDB) Error() error {
|
||||
return self.dbErr
|
||||
func (s *StateDB) Error() error {
|
||||
return s.dbErr
|
||||
}
|
||||
|
||||
// Reset clears out all ephemeral state objects from the state db, but keeps
|
||||
// the underlying state trie to avoid reloading data for the next operations.
|
||||
func (self *StateDB) Reset(root common.Hash) error {
|
||||
tr, err := self.db.OpenTrie(root)
|
||||
func (s *StateDB) Reset(root common.Hash) error {
|
||||
tr, err := s.db.OpenTrie(root)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
self.trie = tr
|
||||
self.stateObjects = make(map[common.Address]*stateObject)
|
||||
self.stateObjectsPending = make(map[common.Address]struct{})
|
||||
self.stateObjectsDirty = make(map[common.Address]struct{})
|
||||
self.thash = common.Hash{}
|
||||
self.bhash = common.Hash{}
|
||||
self.txIndex = 0
|
||||
self.logs = make(map[common.Hash][]*types.Log)
|
||||
self.logSize = 0
|
||||
self.preimages = make(map[common.Hash][]byte)
|
||||
self.clearJournalAndRefund()
|
||||
s.trie = tr
|
||||
s.stateObjects = make(map[common.Address]*stateObject)
|
||||
s.stateObjectsPending = make(map[common.Address]struct{})
|
||||
s.stateObjectsDirty = make(map[common.Address]struct{})
|
||||
s.thash = common.Hash{}
|
||||
s.bhash = common.Hash{}
|
||||
s.txIndex = 0
|
||||
s.logs = make(map[common.Hash][]*types.Log)
|
||||
s.logSize = 0
|
||||
s.preimages = make(map[common.Hash][]byte)
|
||||
s.clearJournalAndRefund()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *StateDB) AddLog(log *types.Log) {
|
||||
self.journal.append(addLogChange{txhash: self.thash})
|
||||
func (s *StateDB) AddLog(log *types.Log) {
|
||||
s.journal.append(addLogChange{txhash: s.thash})
|
||||
|
||||
log.TxHash = self.thash
|
||||
log.BlockHash = self.bhash
|
||||
log.TxIndex = uint(self.txIndex)
|
||||
log.Index = self.logSize
|
||||
self.logs[self.thash] = append(self.logs[self.thash], log)
|
||||
self.logSize++
|
||||
log.TxHash = s.thash
|
||||
log.BlockHash = s.bhash
|
||||
log.TxIndex = uint(s.txIndex)
|
||||
log.Index = s.logSize
|
||||
s.logs[s.thash] = append(s.logs[s.thash], log)
|
||||
s.logSize++
|
||||
}
|
||||
|
||||
func (self *StateDB) GetLogs(hash common.Hash) []*types.Log {
|
||||
return self.logs[hash]
|
||||
func (s *StateDB) GetLogs(hash common.Hash) []*types.Log {
|
||||
return s.logs[hash]
|
||||
}
|
||||
|
||||
func (self *StateDB) Logs() []*types.Log {
|
||||
func (s *StateDB) Logs() []*types.Log {
|
||||
var logs []*types.Log
|
||||
for _, lgs := range self.logs {
|
||||
for _, lgs := range s.logs {
|
||||
logs = append(logs, lgs...)
|
||||
}
|
||||
return logs
|
||||
}
|
||||
|
||||
// AddPreimage records a SHA3 preimage seen by the VM.
|
||||
func (self *StateDB) AddPreimage(hash common.Hash, preimage []byte) {
|
||||
if _, ok := self.preimages[hash]; !ok {
|
||||
self.journal.append(addPreimageChange{hash: hash})
|
||||
func (s *StateDB) AddPreimage(hash common.Hash, preimage []byte) {
|
||||
if _, ok := s.preimages[hash]; !ok {
|
||||
s.journal.append(addPreimageChange{hash: hash})
|
||||
pi := make([]byte, len(preimage))
|
||||
copy(pi, preimage)
|
||||
self.preimages[hash] = pi
|
||||
s.preimages[hash] = pi
|
||||
}
|
||||
}
|
||||
|
||||
// Preimages returns a list of SHA3 preimages that have been submitted.
|
||||
func (self *StateDB) Preimages() map[common.Hash][]byte {
|
||||
return self.preimages
|
||||
func (s *StateDB) Preimages() map[common.Hash][]byte {
|
||||
return s.preimages
|
||||
}
|
||||
|
||||
// AddRefund adds gas to the refund counter
|
||||
func (self *StateDB) AddRefund(gas uint64) {
|
||||
self.journal.append(refundChange{prev: self.refund})
|
||||
self.refund += gas
|
||||
func (s *StateDB) AddRefund(gas uint64) {
|
||||
s.journal.append(refundChange{prev: s.refund})
|
||||
s.refund += gas
|
||||
}
|
||||
|
||||
// SubRefund removes gas from the refund counter.
|
||||
// This method will panic if the refund counter goes below zero
|
||||
func (self *StateDB) SubRefund(gas uint64) {
|
||||
self.journal.append(refundChange{prev: self.refund})
|
||||
if gas > self.refund {
|
||||
func (s *StateDB) SubRefund(gas uint64) {
|
||||
s.journal.append(refundChange{prev: s.refund})
|
||||
if gas > s.refund {
|
||||
panic("Refund counter below zero")
|
||||
}
|
||||
self.refund -= gas
|
||||
s.refund -= gas
|
||||
}
|
||||
|
||||
// Exist reports whether the given account address exists in the state.
|
||||
// Notably this also returns true for suicided accounts.
|
||||
func (self *StateDB) Exist(addr common.Address) bool {
|
||||
return self.getStateObject(addr) != nil
|
||||
func (s *StateDB) Exist(addr common.Address) bool {
|
||||
return s.getStateObject(addr) != nil
|
||||
}
|
||||
|
||||
// Empty returns whether the state object is either non-existent
|
||||
// or empty according to the EIP161 specification (balance = nonce = code = 0)
|
||||
func (self *StateDB) Empty(addr common.Address) bool {
|
||||
so := self.getStateObject(addr)
|
||||
func (s *StateDB) Empty(addr common.Address) bool {
|
||||
so := s.getStateObject(addr)
|
||||
return so == nil || so.empty()
|
||||
}
|
||||
|
||||
// Retrieve the balance from the given address or 0 if object not found
|
||||
func (self *StateDB) GetBalance(addr common.Address) *big.Int {
|
||||
stateObject := self.getStateObject(addr)
|
||||
func (s *StateDB) GetBalance(addr common.Address) *big.Int {
|
||||
stateObject := s.getStateObject(addr)
|
||||
if stateObject != nil {
|
||||
return stateObject.Balance()
|
||||
}
|
||||
return common.Big0
|
||||
}
|
||||
|
||||
func (self *StateDB) GetNonce(addr common.Address) uint64 {
|
||||
stateObject := self.getStateObject(addr)
|
||||
func (s *StateDB) GetNonce(addr common.Address) uint64 {
|
||||
stateObject := s.getStateObject(addr)
|
||||
if stateObject != nil {
|
||||
return stateObject.Nonce()
|
||||
}
|
||||
|
|
@ -241,40 +241,40 @@ func (self *StateDB) GetNonce(addr common.Address) uint64 {
|
|||
}
|
||||
|
||||
// TxIndex returns the current transaction index set by Prepare.
|
||||
func (self *StateDB) TxIndex() int {
|
||||
return self.txIndex
|
||||
func (s *StateDB) TxIndex() int {
|
||||
return s.txIndex
|
||||
}
|
||||
|
||||
// BlockHash returns the current block hash set by Prepare.
|
||||
func (self *StateDB) BlockHash() common.Hash {
|
||||
return self.bhash
|
||||
func (s *StateDB) BlockHash() common.Hash {
|
||||
return s.bhash
|
||||
}
|
||||
|
||||
func (self *StateDB) GetCode(addr common.Address) []byte {
|
||||
stateObject := self.getStateObject(addr)
|
||||
func (s *StateDB) GetCode(addr common.Address) []byte {
|
||||
stateObject := s.getStateObject(addr)
|
||||
if stateObject != nil {
|
||||
return stateObject.Code(self.db)
|
||||
return stateObject.Code(s.db)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *StateDB) GetCodeSize(addr common.Address) int {
|
||||
stateObject := self.getStateObject(addr)
|
||||
func (s *StateDB) GetCodeSize(addr common.Address) int {
|
||||
stateObject := s.getStateObject(addr)
|
||||
if stateObject == nil {
|
||||
return 0
|
||||
}
|
||||
if stateObject.code != nil {
|
||||
return len(stateObject.code)
|
||||
}
|
||||
size, err := self.db.ContractCodeSize(stateObject.addrHash, common.BytesToHash(stateObject.CodeHash()))
|
||||
size, err := s.db.ContractCodeSize(stateObject.addrHash, common.BytesToHash(stateObject.CodeHash()))
|
||||
if err != nil {
|
||||
self.setError(err)
|
||||
s.setError(err)
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
func (self *StateDB) GetCodeHash(addr common.Address) common.Hash {
|
||||
stateObject := self.getStateObject(addr)
|
||||
func (s *StateDB) GetCodeHash(addr common.Address) common.Hash {
|
||||
stateObject := s.getStateObject(addr)
|
||||
if stateObject == nil {
|
||||
return common.Hash{}
|
||||
}
|
||||
|
|
@ -282,25 +282,25 @@ func (self *StateDB) GetCodeHash(addr common.Address) common.Hash {
|
|||
}
|
||||
|
||||
// GetState retrieves a value from the given account's storage trie.
|
||||
func (self *StateDB) GetState(addr common.Address, hash common.Hash) common.Hash {
|
||||
stateObject := self.getStateObject(addr)
|
||||
func (s *StateDB) GetState(addr common.Address, hash common.Hash) common.Hash {
|
||||
stateObject := s.getStateObject(addr)
|
||||
if stateObject != nil {
|
||||
return stateObject.GetState(self.db, hash)
|
||||
return stateObject.GetState(s.db, hash)
|
||||
}
|
||||
return common.Hash{}
|
||||
}
|
||||
|
||||
// GetProof returns the MerkleProof for a given Account
|
||||
func (self *StateDB) GetProof(a common.Address) ([][]byte, error) {
|
||||
func (s *StateDB) GetProof(a common.Address) ([][]byte, error) {
|
||||
var proof proofList
|
||||
err := self.trie.Prove(crypto.Keccak256(a.Bytes()), 0, &proof)
|
||||
err := s.trie.Prove(crypto.Keccak256(a.Bytes()), 0, &proof)
|
||||
return [][]byte(proof), err
|
||||
}
|
||||
|
||||
// GetProof returns the StorageProof for given key
|
||||
func (self *StateDB) GetStorageProof(a common.Address, key common.Hash) ([][]byte, error) {
|
||||
func (s *StateDB) GetStorageProof(a common.Address, key common.Hash) ([][]byte, error) {
|
||||
var proof proofList
|
||||
trie := self.StorageTrie(a)
|
||||
trie := s.StorageTrie(a)
|
||||
if trie == nil {
|
||||
return proof, errors.New("storage trie for requested address does not exist")
|
||||
}
|
||||
|
|
@ -309,32 +309,32 @@ func (self *StateDB) GetStorageProof(a common.Address, key common.Hash) ([][]byt
|
|||
}
|
||||
|
||||
// GetCommittedState retrieves a value from the given account's committed storage trie.
|
||||
func (self *StateDB) GetCommittedState(addr common.Address, hash common.Hash) common.Hash {
|
||||
stateObject := self.getStateObject(addr)
|
||||
func (s *StateDB) GetCommittedState(addr common.Address, hash common.Hash) common.Hash {
|
||||
stateObject := s.getStateObject(addr)
|
||||
if stateObject != nil {
|
||||
return stateObject.GetCommittedState(self.db, hash)
|
||||
return stateObject.GetCommittedState(s.db, hash)
|
||||
}
|
||||
return common.Hash{}
|
||||
}
|
||||
|
||||
// Database retrieves the low level database supporting the lower level trie ops.
|
||||
func (self *StateDB) Database() Database {
|
||||
return self.db
|
||||
func (s *StateDB) Database() Database {
|
||||
return s.db
|
||||
}
|
||||
|
||||
// StorageTrie returns the storage trie of an account.
|
||||
// The return value is a copy and is nil for non-existent accounts.
|
||||
func (self *StateDB) StorageTrie(addr common.Address) Trie {
|
||||
stateObject := self.getStateObject(addr)
|
||||
func (s *StateDB) StorageTrie(addr common.Address) Trie {
|
||||
stateObject := s.getStateObject(addr)
|
||||
if stateObject == nil {
|
||||
return nil
|
||||
}
|
||||
cpy := stateObject.deepCopy(self)
|
||||
return cpy.updateTrie(self.db)
|
||||
cpy := stateObject.deepCopy(s)
|
||||
return cpy.updateTrie(s.db)
|
||||
}
|
||||
|
||||
func (self *StateDB) HasSuicided(addr common.Address) bool {
|
||||
stateObject := self.getStateObject(addr)
|
||||
func (s *StateDB) HasSuicided(addr common.Address) bool {
|
||||
stateObject := s.getStateObject(addr)
|
||||
if stateObject != nil {
|
||||
return stateObject.suicided
|
||||
}
|
||||
|
|
@ -346,53 +346,53 @@ func (self *StateDB) HasSuicided(addr common.Address) bool {
|
|||
*/
|
||||
|
||||
// AddBalance adds amount to the account associated with addr.
|
||||
func (self *StateDB) AddBalance(addr common.Address, amount *big.Int) {
|
||||
stateObject := self.GetOrNewStateObject(addr)
|
||||
func (s *StateDB) AddBalance(addr common.Address, amount *big.Int) {
|
||||
stateObject := s.GetOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.AddBalance(amount)
|
||||
}
|
||||
}
|
||||
|
||||
// SubBalance subtracts amount from the account associated with addr.
|
||||
func (self *StateDB) SubBalance(addr common.Address, amount *big.Int) {
|
||||
stateObject := self.GetOrNewStateObject(addr)
|
||||
func (s *StateDB) SubBalance(addr common.Address, amount *big.Int) {
|
||||
stateObject := s.GetOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.SubBalance(amount)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *StateDB) SetBalance(addr common.Address, amount *big.Int) {
|
||||
stateObject := self.GetOrNewStateObject(addr)
|
||||
func (s *StateDB) SetBalance(addr common.Address, amount *big.Int) {
|
||||
stateObject := s.GetOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.SetBalance(amount)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *StateDB) SetNonce(addr common.Address, nonce uint64) {
|
||||
stateObject := self.GetOrNewStateObject(addr)
|
||||
func (s *StateDB) SetNonce(addr common.Address, nonce uint64) {
|
||||
stateObject := s.GetOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.SetNonce(nonce)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *StateDB) SetCode(addr common.Address, code []byte) {
|
||||
stateObject := self.GetOrNewStateObject(addr)
|
||||
func (s *StateDB) SetCode(addr common.Address, code []byte) {
|
||||
stateObject := s.GetOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.SetCode(crypto.Keccak256Hash(code), code)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *StateDB) SetState(addr common.Address, key, value common.Hash) {
|
||||
stateObject := self.GetOrNewStateObject(addr)
|
||||
func (s *StateDB) SetState(addr common.Address, key, value common.Hash) {
|
||||
stateObject := s.GetOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.SetState(self.db, key, value)
|
||||
stateObject.SetState(s.db, key, value)
|
||||
}
|
||||
}
|
||||
|
||||
// SetStorage replaces the entire storage for the specified account with given
|
||||
// storage. This function should only be used for debugging.
|
||||
func (self *StateDB) SetStorage(addr common.Address, storage map[common.Hash]common.Hash) {
|
||||
stateObject := self.GetOrNewStateObject(addr)
|
||||
func (s *StateDB) SetStorage(addr common.Address, storage map[common.Hash]common.Hash) {
|
||||
stateObject := s.GetOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.SetStorage(storage)
|
||||
}
|
||||
|
|
@ -403,12 +403,12 @@ func (self *StateDB) SetStorage(addr common.Address, storage map[common.Hash]com
|
|||
//
|
||||
// The account's state object is still available until the state is committed,
|
||||
// getStateObject will return a non-nil account after Suicide.
|
||||
func (self *StateDB) Suicide(addr common.Address) bool {
|
||||
stateObject := self.getStateObject(addr)
|
||||
func (s *StateDB) Suicide(addr common.Address) bool {
|
||||
stateObject := s.getStateObject(addr)
|
||||
if stateObject == nil {
|
||||
return false
|
||||
}
|
||||
self.journal.append(suicideChange{
|
||||
s.journal.append(suicideChange{
|
||||
account: &addr,
|
||||
prev: stateObject.suicided,
|
||||
prevbalance: new(big.Int).Set(stateObject.Balance()),
|
||||
|
|
@ -462,7 +462,7 @@ func (s *StateDB) getStateObject(addr common.Address) *stateObject {
|
|||
|
||||
// getDeletedStateObject is similar to getStateObject, but instead of returning
|
||||
// nil for a deleted state object, it returns the actual object with the deleted
|
||||
// flag set. This is needed by the state journal to revert to the correct self-
|
||||
// flag set. This is needed by the state journal to revert to the correct s-
|
||||
// destructed object instead of wiping all knowledge about the state object.
|
||||
func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject {
|
||||
// Prefer live objects if any is available
|
||||
|
|
@ -490,32 +490,32 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject {
|
|||
return obj
|
||||
}
|
||||
|
||||
func (self *StateDB) setStateObject(object *stateObject) {
|
||||
self.stateObjects[object.Address()] = object
|
||||
func (s *StateDB) setStateObject(object *stateObject) {
|
||||
s.stateObjects[object.Address()] = object
|
||||
}
|
||||
|
||||
// Retrieve a state object or create a new state object if nil.
|
||||
func (self *StateDB) GetOrNewStateObject(addr common.Address) *stateObject {
|
||||
stateObject := self.getStateObject(addr)
|
||||
func (s *StateDB) GetOrNewStateObject(addr common.Address) *stateObject {
|
||||
stateObject := s.getStateObject(addr)
|
||||
if stateObject == nil {
|
||||
stateObject, _ = self.createObject(addr)
|
||||
stateObject, _ = s.createObject(addr)
|
||||
}
|
||||
return stateObject
|
||||
}
|
||||
|
||||
// createObject creates a new state object. If there is an existing account with
|
||||
// the given address, it is overwritten and returned as the second return value.
|
||||
func (self *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) {
|
||||
prev = self.getDeletedStateObject(addr) // Note, prev might have been deleted, we need that!
|
||||
func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) {
|
||||
prev = s.getDeletedStateObject(addr) // Note, prev might have been deleted, we need that!
|
||||
|
||||
newobj = newObject(self, addr, Account{})
|
||||
newobj = newObject(s, addr, Account{})
|
||||
newobj.setNonce(0) // sets the object to dirty
|
||||
if prev == nil {
|
||||
self.journal.append(createObjectChange{account: &addr})
|
||||
s.journal.append(createObjectChange{account: &addr})
|
||||
} else {
|
||||
self.journal.append(resetObjectChange{prev: prev})
|
||||
s.journal.append(resetObjectChange{prev: prev})
|
||||
}
|
||||
self.setStateObject(newobj)
|
||||
s.setStateObject(newobj)
|
||||
return newobj, prev
|
||||
}
|
||||
|
||||
|
|
@ -529,8 +529,8 @@ func (self *StateDB) createObject(addr common.Address) (newobj, prev *stateObjec
|
|||
// 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1)
|
||||
//
|
||||
// Carrying over the balance ensures that Ether doesn't disappear.
|
||||
func (self *StateDB) CreateAccount(addr common.Address) {
|
||||
newObj, prev := self.createObject(addr)
|
||||
func (s *StateDB) CreateAccount(addr common.Address) {
|
||||
newObj, prev := s.createObject(addr)
|
||||
if prev != nil {
|
||||
newObj.setBalance(prev.data.Balance)
|
||||
}
|
||||
|
|
@ -567,27 +567,27 @@ func (db *StateDB) ForEachStorage(addr common.Address, cb func(key, value common
|
|||
|
||||
// Copy creates a deep, independent copy of the state.
|
||||
// Snapshots of the copied state cannot be applied to the copy.
|
||||
func (self *StateDB) Copy() *StateDB {
|
||||
func (s *StateDB) Copy() *StateDB {
|
||||
// Copy all the basic fields, initialize the memory ones
|
||||
state := &StateDB{
|
||||
db: self.db,
|
||||
trie: self.db.CopyTrie(self.trie),
|
||||
stateObjects: make(map[common.Address]*stateObject, len(self.journal.dirties)),
|
||||
stateObjectsPending: make(map[common.Address]struct{}, len(self.stateObjectsPending)),
|
||||
stateObjectsDirty: make(map[common.Address]struct{}, len(self.journal.dirties)),
|
||||
refund: self.refund,
|
||||
logs: make(map[common.Hash][]*types.Log, len(self.logs)),
|
||||
logSize: self.logSize,
|
||||
preimages: make(map[common.Hash][]byte, len(self.preimages)),
|
||||
db: s.db,
|
||||
trie: s.db.CopyTrie(s.trie),
|
||||
stateObjects: make(map[common.Address]*stateObject, len(s.journal.dirties)),
|
||||
stateObjectsPending: make(map[common.Address]struct{}, len(s.stateObjectsPending)),
|
||||
stateObjectsDirty: make(map[common.Address]struct{}, len(s.journal.dirties)),
|
||||
refund: s.refund,
|
||||
logs: make(map[common.Hash][]*types.Log, len(s.logs)),
|
||||
logSize: s.logSize,
|
||||
preimages: make(map[common.Hash][]byte, len(s.preimages)),
|
||||
journal: newJournal(),
|
||||
}
|
||||
// Copy the dirty states, logs, and preimages
|
||||
for addr := range self.journal.dirties {
|
||||
for addr := range s.journal.dirties {
|
||||
// As documented [here](https://github.com/ethereum/go-ethereum/pull/16485#issuecomment-380438527),
|
||||
// and in the Finalise-method, there is a case where an object is in the journal but not
|
||||
// in the stateObjects: OOG after touch on ripeMD prior to Byzantium. Thus, we need to check for
|
||||
// nil
|
||||
if object, exist := self.stateObjects[addr]; exist {
|
||||
if object, exist := s.stateObjects[addr]; exist {
|
||||
// Even though the original object is dirty, we are not copying the journal,
|
||||
// so we need to make sure that anyside effect the journal would have caused
|
||||
// during a commit (or similar op) is already applied to the copy.
|
||||
|
|
@ -600,19 +600,19 @@ func (self *StateDB) Copy() *StateDB {
|
|||
// Above, we don't copy the actual journal. This means that if the copy is copied, the
|
||||
// loop above will be a no-op, since the copy's journal is empty.
|
||||
// Thus, here we iterate over stateObjects, to enable copies of copies
|
||||
for addr := range self.stateObjectsPending {
|
||||
for addr := range s.stateObjectsPending {
|
||||
if _, exist := state.stateObjects[addr]; !exist {
|
||||
state.stateObjects[addr] = self.stateObjects[addr].deepCopy(state)
|
||||
state.stateObjects[addr] = s.stateObjects[addr].deepCopy(state)
|
||||
}
|
||||
state.stateObjectsPending[addr] = struct{}{}
|
||||
}
|
||||
for addr := range self.stateObjectsDirty {
|
||||
for addr := range s.stateObjectsDirty {
|
||||
if _, exist := state.stateObjects[addr]; !exist {
|
||||
state.stateObjects[addr] = self.stateObjects[addr].deepCopy(state)
|
||||
state.stateObjects[addr] = s.stateObjects[addr].deepCopy(state)
|
||||
}
|
||||
state.stateObjectsDirty[addr] = struct{}{}
|
||||
}
|
||||
for hash, logs := range self.logs {
|
||||
for hash, logs := range s.logs {
|
||||
cpy := make([]*types.Log, len(logs))
|
||||
for i, l := range logs {
|
||||
cpy[i] = new(types.Log)
|
||||
|
|
@ -620,42 +620,42 @@ func (self *StateDB) Copy() *StateDB {
|
|||
}
|
||||
state.logs[hash] = cpy
|
||||
}
|
||||
for hash, preimage := range self.preimages {
|
||||
for hash, preimage := range s.preimages {
|
||||
state.preimages[hash] = preimage
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
// Snapshot returns an identifier for the current revision of the state.
|
||||
func (self *StateDB) Snapshot() int {
|
||||
id := self.nextRevisionId
|
||||
self.nextRevisionId++
|
||||
self.validRevisions = append(self.validRevisions, revision{id, self.journal.length()})
|
||||
func (s *StateDB) Snapshot() int {
|
||||
id := s.nextRevisionId
|
||||
s.nextRevisionId++
|
||||
s.validRevisions = append(s.validRevisions, revision{id, s.journal.length()})
|
||||
return id
|
||||
}
|
||||
|
||||
// RevertToSnapshot reverts all state changes made since the given revision.
|
||||
func (self *StateDB) RevertToSnapshot(revid int) {
|
||||
func (s *StateDB) RevertToSnapshot(revid int) {
|
||||
// Find the snapshot in the stack of valid snapshots.
|
||||
idx := sort.Search(len(self.validRevisions), func(i int) bool {
|
||||
return self.validRevisions[i].id >= revid
|
||||
idx := sort.Search(len(s.validRevisions), func(i int) bool {
|
||||
return s.validRevisions[i].id >= revid
|
||||
})
|
||||
if idx == len(self.validRevisions) || self.validRevisions[idx].id != revid {
|
||||
if idx == len(s.validRevisions) || s.validRevisions[idx].id != revid {
|
||||
panic(fmt.Errorf("revision id %v cannot be reverted", revid))
|
||||
}
|
||||
snapshot := self.validRevisions[idx].journalIndex
|
||||
snapshot := s.validRevisions[idx].journalIndex
|
||||
|
||||
// Replay the journal to undo changes and remove invalidated snapshots
|
||||
self.journal.revert(self, snapshot)
|
||||
self.validRevisions = self.validRevisions[:idx]
|
||||
s.journal.revert(s, snapshot)
|
||||
s.validRevisions = s.validRevisions[:idx]
|
||||
}
|
||||
|
||||
// GetRefund returns the current value of the refund counter.
|
||||
func (self *StateDB) GetRefund() uint64 {
|
||||
return self.refund
|
||||
func (s *StateDB) GetRefund() uint64 {
|
||||
return s.refund
|
||||
}
|
||||
|
||||
// Finalise finalises the state by removing the self destructed objects and clears
|
||||
// Finalise finalises the state by removing the s destructed objects and clears
|
||||
// the journal as well as the refunds. Finalise, however, will not push any updates
|
||||
// into the tries just yet. Only IntermediateRoot or Commit will do that.
|
||||
func (s *StateDB) Finalise(deleteEmptyObjects bool) {
|
||||
|
|
@ -710,10 +710,10 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
|
|||
|
||||
// Prepare sets the current transaction hash and index and block hash which is
|
||||
// used when the EVM emits new state logs.
|
||||
func (self *StateDB) Prepare(thash, bhash common.Hash, ti int) {
|
||||
self.thash = thash
|
||||
self.bhash = bhash
|
||||
self.txIndex = ti
|
||||
func (s *StateDB) Prepare(thash, bhash common.Hash, ti int) {
|
||||
s.thash = thash
|
||||
s.bhash = bhash
|
||||
s.txIndex = ti
|
||||
}
|
||||
|
||||
func (s *StateDB) clearJournalAndRefund() {
|
||||
|
|
|
|||
|
|
@ -29,8 +29,6 @@ import (
|
|||
"testing"
|
||||
"testing/quick"
|
||||
|
||||
"gopkg.in/check.v1"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
|
|
@ -458,7 +456,8 @@ func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *StateSuite) TestTouchDelete(c *check.C) {
|
||||
func TestTouchDelete(t *testing.T) {
|
||||
s := newStateTest()
|
||||
s.state.GetOrNewStateObject(common.Address{})
|
||||
root, _ := s.state.Commit(false)
|
||||
s.state.Reset(root)
|
||||
|
|
@ -467,11 +466,11 @@ func (s *StateSuite) TestTouchDelete(c *check.C) {
|
|||
s.state.AddBalance(common.Address{}, new(big.Int))
|
||||
|
||||
if len(s.state.journal.dirties) != 1 {
|
||||
c.Fatal("expected one dirty state object")
|
||||
t.Fatal("expected one dirty state object")
|
||||
}
|
||||
s.state.RevertToSnapshot(snapshot)
|
||||
if len(s.state.journal.dirties) != 0 {
|
||||
c.Fatal("expected no dirty state object")
|
||||
t.Fatal("expected no dirty state object")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import (
|
|||
"io"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"sort"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
|
|
@ -394,26 +393,3 @@ func (b *Block) Hash() common.Hash {
|
|||
}
|
||||
|
||||
type Blocks []*Block
|
||||
|
||||
type BlockBy func(b1, b2 *Block) bool
|
||||
|
||||
func (self BlockBy) Sort(blocks Blocks) {
|
||||
bs := blockSorter{
|
||||
blocks: blocks,
|
||||
by: self,
|
||||
}
|
||||
sort.Sort(bs)
|
||||
}
|
||||
|
||||
type blockSorter struct {
|
||||
blocks Blocks
|
||||
by func(b1, b2 *Block) bool
|
||||
}
|
||||
|
||||
func (self blockSorter) Len() int { return len(self.blocks) }
|
||||
func (self blockSorter) Swap(i, j int) {
|
||||
self.blocks[i], self.blocks[j] = self.blocks[j], self.blocks[i]
|
||||
}
|
||||
func (self blockSorter) Less(i, j int) bool { return self.by(self.blocks[i], self.blocks[j]) }
|
||||
|
||||
func Number(b1, b2 *Block) bool { return b1.header.Number.Cmp(b2.header.Number) < 0 }
|
||||
|
|
|
|||
|
|
@ -419,17 +419,17 @@ func New(code string) (*Tracer, error) {
|
|||
tracer.tracerObject = 0 // yeah, nice, eval can't return the index itself
|
||||
|
||||
if !tracer.vm.GetPropString(tracer.tracerObject, "step") {
|
||||
return nil, fmt.Errorf("Trace object must expose a function step()")
|
||||
return nil, fmt.Errorf("trace object must expose a function step()")
|
||||
}
|
||||
tracer.vm.Pop()
|
||||
|
||||
if !tracer.vm.GetPropString(tracer.tracerObject, "fault") {
|
||||
return nil, fmt.Errorf("Trace object must expose a function fault()")
|
||||
return nil, fmt.Errorf("trace object must expose a function fault()")
|
||||
}
|
||||
tracer.vm.Pop()
|
||||
|
||||
if !tracer.vm.GetPropString(tracer.tracerObject, "result") {
|
||||
return nil, fmt.Errorf("Trace object must expose a function result()")
|
||||
return nil, fmt.Errorf("trace object must expose a function result()")
|
||||
}
|
||||
tracer.vm.Pop()
|
||||
|
||||
|
|
|
|||
67
go.mod
Normal file
67
go.mod
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
module github.com/ethereum/go-ethereum
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/Azure/azure-pipeline-go v0.2.2 // indirect
|
||||
github.com/Azure/azure-storage-blob-go v0.7.0
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.0 // indirect
|
||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect
|
||||
github.com/VictoriaMetrics/fastcache v1.5.2
|
||||
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847
|
||||
github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6
|
||||
github.com/cespare/cp v0.1.0
|
||||
github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea
|
||||
github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf
|
||||
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c
|
||||
github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa
|
||||
github.com/fatih/color v1.3.0
|
||||
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc
|
||||
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff
|
||||
github.com/go-ole/go-ole v1.2.1 // indirect
|
||||
github.com/go-stack/stack v1.8.0
|
||||
github.com/golang/protobuf v1.3.2-0.20190517061210-b285ee9cfc6c
|
||||
github.com/golang/snappy v0.0.1
|
||||
github.com/google/go-cmp v0.3.1 // indirect
|
||||
github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989
|
||||
github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277
|
||||
github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad
|
||||
github.com/huin/goupnp v0.0.0-20161224104101-679507af18f3
|
||||
github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883
|
||||
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458
|
||||
github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21
|
||||
github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356
|
||||
github.com/kr/pretty v0.1.0 // indirect
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.0
|
||||
github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035
|
||||
github.com/naoina/go-stringutil v0.1.0 // indirect
|
||||
github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416
|
||||
github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c
|
||||
github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222
|
||||
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7
|
||||
github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150
|
||||
github.com/rjeczalik/notify v0.9.1
|
||||
github.com/robertkrimen/otto v0.0.0-20170205013659-6a77b7cbc37d
|
||||
github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00
|
||||
github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521 // indirect
|
||||
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4
|
||||
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570
|
||||
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 // indirect
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d
|
||||
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef
|
||||
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7 // indirect
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f
|
||||
golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7
|
||||
golang.org/x/text v0.3.2
|
||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce
|
||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190213234257-ec84240a7772
|
||||
gopkg.in/sourcemap.v1 v1.0.5 // indirect
|
||||
gopkg.in/urfave/cli.v1 v1.20.0
|
||||
gotest.tools v2.2.0+incompatible // indirect
|
||||
)
|
||||
224
go.sum
Normal file
224
go.sum
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4=
|
||||
github.com/Azure/azure-pipeline-go v0.2.2 h1:6oiIS9yaG6XCCzhgAgKFfIWyo4LLCiDhZot6ltoThhY=
|
||||
github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc=
|
||||
github.com/Azure/azure-storage-blob-go v0.7.0 h1:MuueVOYkufCxJw5YZzF842DY2MBsp+hLuh2apKY0mck=
|
||||
github.com/Azure/azure-storage-blob-go v0.7.0/go.mod h1:f9YQKtsG1nMisotuTPpO0tjNuEjKRYAcJU8/ydDI++4=
|
||||
github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs=
|
||||
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.0 h1:CxTzQrySOxDnKpLjFJeZAS5Qrv/qFPkgLjx5bOAi//I=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc=
|
||||
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
|
||||
github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM=
|
||||
github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
|
||||
github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY=
|
||||
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/OneOfOne/xxhash v1.2.5 h1:zl/OfRA6nftbBK9qTohYBJ5xvw6C/oNKizR7cZGl3cI=
|
||||
github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
|
||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8=
|
||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||
github.com/VictoriaMetrics/fastcache v1.5.2 h1:Erd8iIuBAL9kke8JzM4+WxkKuFkHh3ktwLanJvDgR44=
|
||||
github.com/VictoriaMetrics/fastcache v1.5.2/go.mod h1:+jv9Ckb+za/P1ZRg/sulP5Ni1v49daAVERr0H3CuscE=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8=
|
||||
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847 h1:rtI0fD4oG/8eVokGVPYJEW1F88p1ZNgXiEIs9thEE4A=
|
||||
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6 h1:Eey/GGQ/E5Xp1P2Lyx1qj007hLZfbi0+CoVeJruGCtI=
|
||||
github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ=
|
||||
github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk=
|
||||
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.0.1-0.20190104013014-3767db7a7e18 h1:pl4eWIqvFe/Kg3zkn7NxevNzILnZYWDCG7qbA1CJik0=
|
||||
github.com/cespare/xxhash/v2 v2.0.1-0.20190104013014-3767db7a7e18/go.mod h1:HD5P3vAIAh+Y2GAxg0PrPN1P8WkepXGpjbUPDHJqqKM=
|
||||
github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9 h1:J82+/8rub3qSy0HxEnoYD8cs+HDlHWYrqYXe2Vqxluk=
|
||||
github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea h1:j4317fAZh7X6GqbFowYdYdI0L9bwxL07jyPZIdepyZ0=
|
||||
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf h1:sh8rkQZavChcmakYiSlqu2425CHyFXLZZnvm7PDpU8M=
|
||||
github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c h1:JHHhtb9XWJrGNMcrVP6vyzO4dusgi/HnceHTgxSejUM=
|
||||
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa h1:XKAhUk/dtp+CV0VO6mhG2V7jA9vbcGcnYF/Ay9NjZrY=
|
||||
github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
||||
github.com/fatih/color v1.3.0 h1:YehCCcyeQ6Km0D6+IapqPinWBK6y+0eB5umvZXK9WPs=
|
||||
github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc h1:jtW8jbpkO4YirRSyepBOH8E+2HEw6/hKkBvFPwhUN8c=
|
||||
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
|
||||
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
|
||||
github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0 h1:8HUsc87TaSWLKwrnumgC8/YconD2fJQsRJAsWaPg2ic=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E=
|
||||
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2-0.20190517061210-b285ee9cfc6c h1:zqAKixg3cTcIasAMJV+EcfVbWwLpOZ7LeoWJvcuD/5Q=
|
||||
github.com/golang/protobuf v1.3.2-0.20190517061210-b285ee9cfc6c/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989 h1:giknQ4mEuDFmmHSrGcbargOuLHQGtywqo4mheITex54=
|
||||
github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277 h1:E0whKxgp2ojts0FDgUA8dl62bmH0LxKanMoBr6MDTDM=
|
||||
github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc=
|
||||
github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad h1:eMxs9EL0PvIGS9TTtxg4R+JxuPGav82J8rA+GFnY7po=
|
||||
github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/huin/goupnp v0.0.0-20161224104101-679507af18f3 h1:DqD8eigqlUm0+znmx7zhL0xvTW3+e1jCekJMfBUADWI=
|
||||
github.com/huin/goupnp v0.0.0-20161224104101-679507af18f3/go.mod h1:MZ2ZmwcBpvOoJ22IJsc7va19ZwoheaBk43rKg12SKag=
|
||||
github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883 h1:FSeK4fZCo8u40n2JMnyAsd6x7+SbvoOMHvQOU/n10P4=
|
||||
github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
||||
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458 h1:6OvNmYgJyexcZ3pYbTI9jWx5tHo1Dee/tWbLMfPe2TA=
|
||||
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||
github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21 h1:F/iKcka0K2LgnKy/fgSBf235AETtm1n1TvBzqu40LE0=
|
||||
github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356 h1:I/yrLt2WilKxlQKCM52clh5rGzTKpVctGT1lH4Dc8Jw=
|
||||
github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/mattn/go-colorable v0.1.0 h1:v2XXALHHh6zHfYTJ+cSkwtyffnaOyR1MXaA91mTrb8o=
|
||||
github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d h1:oNAwILwmgWKFpuU+dXvI6dl9jG2mAWAZLX3r9s0PPiw=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
|
||||
github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035 h1:USWjF42jDCSEeikX/G1g40ZWnsPXN5WkZ4jMHZWyBK4=
|
||||
github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks=
|
||||
github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0=
|
||||
github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 h1:shk/vn9oCoOTmwcouEdwIeOtOGA/ELRUw/GwvxwfT+0=
|
||||
github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c h1:1RHs3tNxjXGHeul8z2t6H2N2TlAqpKe5yryJztRx4Jk=
|
||||
github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222 h1:goeTyGkArOZIVOMA0dQbyuPWGNQJZGPwPu/QS9GlpnA=
|
||||
github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
|
||||
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQmzR3rNLYGGz4g/UgFcjb28p/viDM=
|
||||
github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150 h1:ZeU+auZj1iNzN8iVhff6M38Mfu73FQiJve/GEXYJBjE=
|
||||
github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE=
|
||||
github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho=
|
||||
github.com/robertkrimen/otto v0.0.0-20170205013659-6a77b7cbc37d h1:ouzpe+YhpIfnjR40gSkJHWsvXmB6TiPKqMtMpfyU9DE=
|
||||
github.com/robertkrimen/otto v0.0.0-20170205013659-6a77b7cbc37d/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
|
||||
github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00 h1:8DPul/X0IT/1TNMIxoKLwdemEOBBHDC/K4EB16Cw5WE=
|
||||
github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521 h1:3hxavr+IHMsQBrYUPQM5v0CgENFktkkbg1sfpgM3h20=
|
||||
github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spaolacci/murmur3 v1.0.1-0.20190317074736-539464a789e9 h1:5Cp3cVwpQP4aCQ6jx6dNLP3IarbYiuStmIzYu+BjQwY=
|
||||
github.com/spaolacci/murmur3 v1.0.1-0.20190317074736-539464a789e9/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 h1:Gb2Tyox57NRNuZ2d3rmvB3pcmbu7O1RS3m8WRx7ilrg=
|
||||
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q=
|
||||
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 h1:gIlAHnH1vJb5vwEjIp5kBj/eu99p/bl0Ay2goiPe5xE=
|
||||
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw=
|
||||
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 h1:njlZPzLwU639dk2kqnCPPv+wNjq7Xb6EfUxe/oX0/NM=
|
||||
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d h1:gZZadD8H+fF+n9CmNhYL1Y0dJB+kLOmKd7FbPJLeGHs=
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA=
|
||||
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef h1:wHSqTBrZW24CsNJDfeh9Ex6Pm0Rcpc7qrgKBiL44vF4=
|
||||
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 h1:1cngl9mPEoITZG8s8cVcUy5CeIBYhEESkOB7m6Gmkrk=
|
||||
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7 h1:LepdCS8Gf/MVejFIt8lsiexZATdoGVyp5bcyS+rYoUI=
|
||||
golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
|
||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
|
||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190213234257-ec84240a7772 h1:hhsSf/5z74Ck/DJYc+R8zpq8KGm7uJvpdLRQED/IedA=
|
||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190213234257-ec84240a7772/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
||||
gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
|
||||
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0=
|
||||
gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
|
|
@ -118,28 +118,6 @@ func render(tpl *template.Template, outputFile string, outputPerm os.FileMode, x
|
|||
}
|
||||
}
|
||||
|
||||
// CopyFile copies a file.
|
||||
func CopyFile(dst, src string, mode os.FileMode) {
|
||||
if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
destFile, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, mode)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer destFile.Close()
|
||||
|
||||
srcFile, err := os.Open(src)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer srcFile.Close()
|
||||
|
||||
if _, err := io.Copy(destFile, srcFile); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// GoTool returns the command that runs a go tool. This uses go from GOROOT instead of PATH
|
||||
// so that go commands executed by build use the same version of Go as the 'host' that runs
|
||||
// build code. e.g.
|
||||
|
|
|
|||
|
|
@ -906,6 +906,18 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash
|
|||
}
|
||||
cap = hi
|
||||
|
||||
// Set sender address or use a default if none specified
|
||||
if args.From == nil {
|
||||
if wallets := b.AccountManager().Wallets(); len(wallets) > 0 {
|
||||
if accounts := wallets[0].Accounts(); len(accounts) > 0 {
|
||||
args.From = &accounts[0].Address
|
||||
}
|
||||
}
|
||||
}
|
||||
// Use zero-address if none other is available
|
||||
if args.From == nil {
|
||||
args.From = &common.Address{}
|
||||
}
|
||||
// Create a helper to check if a gas allowance results in an executable transaction
|
||||
executable := func(gas uint64) bool {
|
||||
args.Gas = (*hexutil.Uint64)(&gas)
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ func (api *PrivateLightServerAPI) clientInfo(c *clientInfo, id enode.ID) map[str
|
|||
info["priority"] = pb != 0
|
||||
} else {
|
||||
info["isConnected"] = false
|
||||
pb := api.server.clientPool.getPosBalance(id)
|
||||
pb := api.server.clientPool.ndb.getOrNewPB(id)
|
||||
info["pricing/balance"], info["pricing/balanceMeta"] = pb.value, pb.meta
|
||||
info["priority"] = pb.value != 0
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ func TestCounterClear(t *testing.T) {
|
|||
c := NewCounter()
|
||||
c.Inc(1)
|
||||
c.Clear()
|
||||
if count := c.Count(); 0 != count {
|
||||
if count := c.Count(); count != 0 {
|
||||
t.Errorf("c.Count(): 0 != %v\n", count)
|
||||
}
|
||||
}
|
||||
|
|
@ -22,7 +22,7 @@ func TestCounterClear(t *testing.T) {
|
|||
func TestCounterDec1(t *testing.T) {
|
||||
c := NewCounter()
|
||||
c.Dec(1)
|
||||
if count := c.Count(); -1 != count {
|
||||
if count := c.Count(); count != -1 {
|
||||
t.Errorf("c.Count(): -1 != %v\n", count)
|
||||
}
|
||||
}
|
||||
|
|
@ -30,7 +30,7 @@ func TestCounterDec1(t *testing.T) {
|
|||
func TestCounterDec2(t *testing.T) {
|
||||
c := NewCounter()
|
||||
c.Dec(2)
|
||||
if count := c.Count(); -2 != count {
|
||||
if count := c.Count(); count != -2 {
|
||||
t.Errorf("c.Count(): -2 != %v\n", count)
|
||||
}
|
||||
}
|
||||
|
|
@ -38,7 +38,7 @@ func TestCounterDec2(t *testing.T) {
|
|||
func TestCounterInc1(t *testing.T) {
|
||||
c := NewCounter()
|
||||
c.Inc(1)
|
||||
if count := c.Count(); 1 != count {
|
||||
if count := c.Count(); count != 1 {
|
||||
t.Errorf("c.Count(): 1 != %v\n", count)
|
||||
}
|
||||
}
|
||||
|
|
@ -46,7 +46,7 @@ func TestCounterInc1(t *testing.T) {
|
|||
func TestCounterInc2(t *testing.T) {
|
||||
c := NewCounter()
|
||||
c.Inc(2)
|
||||
if count := c.Count(); 2 != count {
|
||||
if count := c.Count(); count != 2 {
|
||||
t.Errorf("c.Count(): 2 != %v\n", count)
|
||||
}
|
||||
}
|
||||
|
|
@ -56,14 +56,14 @@ func TestCounterSnapshot(t *testing.T) {
|
|||
c.Inc(1)
|
||||
snapshot := c.Snapshot()
|
||||
c.Inc(1)
|
||||
if count := snapshot.Count(); 1 != count {
|
||||
if count := snapshot.Count(); count != 1 {
|
||||
t.Errorf("c.Count(): 1 != %v\n", count)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCounterZero(t *testing.T) {
|
||||
c := NewCounter()
|
||||
if count := c.Count(); 0 != count {
|
||||
if count := c.Count(); count != 0 {
|
||||
t.Errorf("c.Count(): 0 != %v\n", count)
|
||||
}
|
||||
}
|
||||
|
|
@ -71,7 +71,7 @@ func TestCounterZero(t *testing.T) {
|
|||
func TestGetOrRegisterCounter(t *testing.T) {
|
||||
r := NewRegistry()
|
||||
NewRegisteredCounter("foo", r).Inc(47)
|
||||
if c := GetOrRegisterCounter("foo", r); 47 != c.Count() {
|
||||
if c := GetOrRegisterCounter("foo", r); c.Count() != 47 {
|
||||
t.Fatal(c)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ func TestFunctionalGaugeFloat64(t *testing.T) {
|
|||
func TestGetOrRegisterFunctionalGaugeFloat64(t *testing.T) {
|
||||
r := NewRegistry()
|
||||
NewRegisteredFunctionalGaugeFloat64("foo", r, func() float64 { return 47 })
|
||||
if g := GetOrRegisterGaugeFloat64("foo", r); 47 != g.Value() {
|
||||
if g := GetOrRegisterGaugeFloat64("foo", r); g.Value() != 47 {
|
||||
t.Fatal(g)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ func BenchmarkGuage(b *testing.B) {
|
|||
func TestGauge(t *testing.T) {
|
||||
g := NewGauge()
|
||||
g.Update(int64(47))
|
||||
if v := g.Value(); 47 != v {
|
||||
if v := g.Value(); v != 47 {
|
||||
t.Errorf("g.Value(): 47 != %v\n", v)
|
||||
}
|
||||
}
|
||||
|
|
@ -26,7 +26,7 @@ func TestGaugeSnapshot(t *testing.T) {
|
|||
g.Update(int64(47))
|
||||
snapshot := g.Snapshot()
|
||||
g.Update(int64(0))
|
||||
if v := snapshot.Value(); 47 != v {
|
||||
if v := snapshot.Value(); v != 47 {
|
||||
t.Errorf("g.Value(): 47 != %v\n", v)
|
||||
}
|
||||
}
|
||||
|
|
@ -34,7 +34,7 @@ func TestGaugeSnapshot(t *testing.T) {
|
|||
func TestGetOrRegisterGauge(t *testing.T) {
|
||||
r := NewRegistry()
|
||||
NewRegisteredGauge("foo", r).Update(47)
|
||||
if g := GetOrRegisterGauge("foo", r); 47 != g.Value() {
|
||||
if g := GetOrRegisterGauge("foo", r); g.Value() != 47 {
|
||||
t.Fatal(g)
|
||||
}
|
||||
}
|
||||
|
|
@ -55,7 +55,7 @@ func TestFunctionalGauge(t *testing.T) {
|
|||
func TestGetOrRegisterFunctionalGauge(t *testing.T) {
|
||||
r := NewRegistry()
|
||||
NewRegisteredFunctionalGauge("foo", r, func() int64 { return 47 })
|
||||
if g := GetOrRegisterGauge("foo", r); 47 != g.Value() {
|
||||
if g := GetOrRegisterGauge("foo", r); g.Value() != 47 {
|
||||
t.Fatal(g)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ func TestGetOrRegisterHistogram(t *testing.T) {
|
|||
r := NewRegistry()
|
||||
s := NewUniformSample(100)
|
||||
NewRegisteredHistogram("foo", r, s).Update(47)
|
||||
if h := GetOrRegisterHistogram("foo", r, s); 1 != h.Count() {
|
||||
if h := GetOrRegisterHistogram("foo", r, s); h.Count() != 1 {
|
||||
t.Fatal(h)
|
||||
}
|
||||
}
|
||||
|
|
@ -29,29 +29,29 @@ func TestHistogram10000(t *testing.T) {
|
|||
|
||||
func TestHistogramEmpty(t *testing.T) {
|
||||
h := NewHistogram(NewUniformSample(100))
|
||||
if count := h.Count(); 0 != count {
|
||||
if count := h.Count(); count != 0 {
|
||||
t.Errorf("h.Count(): 0 != %v\n", count)
|
||||
}
|
||||
if min := h.Min(); 0 != min {
|
||||
if min := h.Min(); min != 0 {
|
||||
t.Errorf("h.Min(): 0 != %v\n", min)
|
||||
}
|
||||
if max := h.Max(); 0 != max {
|
||||
if max := h.Max(); max != 0 {
|
||||
t.Errorf("h.Max(): 0 != %v\n", max)
|
||||
}
|
||||
if mean := h.Mean(); 0.0 != mean {
|
||||
if mean := h.Mean(); mean != 0.0 {
|
||||
t.Errorf("h.Mean(): 0.0 != %v\n", mean)
|
||||
}
|
||||
if stdDev := h.StdDev(); 0.0 != stdDev {
|
||||
if stdDev := h.StdDev(); stdDev != 0.0 {
|
||||
t.Errorf("h.StdDev(): 0.0 != %v\n", stdDev)
|
||||
}
|
||||
ps := h.Percentiles([]float64{0.5, 0.75, 0.99})
|
||||
if 0.0 != ps[0] {
|
||||
if ps[0] != 0.0 {
|
||||
t.Errorf("median: 0.0 != %v\n", ps[0])
|
||||
}
|
||||
if 0.0 != ps[1] {
|
||||
if ps[1] != 0.0 {
|
||||
t.Errorf("75th percentile: 0.0 != %v\n", ps[1])
|
||||
}
|
||||
if 0.0 != ps[2] {
|
||||
if ps[2] != 0.0 {
|
||||
t.Errorf("99th percentile: 0.0 != %v\n", ps[2])
|
||||
}
|
||||
}
|
||||
|
|
@ -67,29 +67,29 @@ func TestHistogramSnapshot(t *testing.T) {
|
|||
}
|
||||
|
||||
func testHistogram10000(t *testing.T, h Histogram) {
|
||||
if count := h.Count(); 10000 != count {
|
||||
if count := h.Count(); count != 10000 {
|
||||
t.Errorf("h.Count(): 10000 != %v\n", count)
|
||||
}
|
||||
if min := h.Min(); 1 != min {
|
||||
if min := h.Min(); min != 1 {
|
||||
t.Errorf("h.Min(): 1 != %v\n", min)
|
||||
}
|
||||
if max := h.Max(); 10000 != max {
|
||||
if max := h.Max(); max != 10000 {
|
||||
t.Errorf("h.Max(): 10000 != %v\n", max)
|
||||
}
|
||||
if mean := h.Mean(); 5000.5 != mean {
|
||||
if mean := h.Mean(); mean != 5000.5 {
|
||||
t.Errorf("h.Mean(): 5000.5 != %v\n", mean)
|
||||
}
|
||||
if stdDev := h.StdDev(); 2886.751331514372 != stdDev {
|
||||
if stdDev := h.StdDev(); stdDev != 2886.751331514372 {
|
||||
t.Errorf("h.StdDev(): 2886.751331514372 != %v\n", stdDev)
|
||||
}
|
||||
ps := h.Percentiles([]float64{0.5, 0.75, 0.99})
|
||||
if 5000.5 != ps[0] {
|
||||
if ps[0] != 5000.5 {
|
||||
t.Errorf("median: 5000.5 != %v\n", ps[0])
|
||||
}
|
||||
if 7500.75 != ps[1] {
|
||||
if ps[1] != 7500.75 {
|
||||
t.Errorf("75th percentile: 7500.75 != %v\n", ps[1])
|
||||
}
|
||||
if 9900.99 != ps[2] {
|
||||
if ps[2] != 9900.99 {
|
||||
t.Errorf("99th percentile: 9900.99 != %v\n", ps[2])
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ func InfluxDBWithTags(r metrics.Registry, d time.Duration, url, database, userna
|
|||
func InfluxDBWithTagsOnce(r metrics.Registry, url, database, username, password, namespace string, tags map[string]string) error {
|
||||
u, err := uurl.Parse(url)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to parse InfluxDB. url: %s, err: %v", url, err)
|
||||
return fmt.Errorf("unable to parse InfluxDB. url: %s, err: %v", url, err)
|
||||
}
|
||||
|
||||
rep := &reporter{
|
||||
|
|
@ -76,11 +76,11 @@ func InfluxDBWithTagsOnce(r metrics.Registry, url, database, username, password,
|
|||
cache: make(map[string]int64),
|
||||
}
|
||||
if err := rep.makeClient(); err != nil {
|
||||
return fmt.Errorf("Unable to make InfluxDB client. err: %v", err)
|
||||
return fmt.Errorf("unable to make InfluxDB client. err: %v", err)
|
||||
}
|
||||
|
||||
if err := rep.send(); err != nil {
|
||||
return fmt.Errorf("Unable to send to InfluxDB. err: %v", err)
|
||||
return fmt.Errorf("unable to send to InfluxDB. err: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ func TestRegistryMarshallJSON(t *testing.T) {
|
|||
r := NewRegistry()
|
||||
r.Register("counter", NewCounter())
|
||||
enc.Encode(r)
|
||||
if s := b.String(); "{\"counter\":{\"count\":0}}\n" != s {
|
||||
if s := b.String(); s != "{\"counter\":{\"count\":0}}\n" {
|
||||
t.Fatalf(s)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ func (c *LibratoClient) PostMetrics(batch Batch) (err error) {
|
|||
if body, err = ioutil.ReadAll(resp.Body); err != nil {
|
||||
body = []byte(fmt.Sprintf("(could not fetch response body for error: %s)", err))
|
||||
}
|
||||
err = fmt.Errorf("Unable to post to Librato: %d %s %s", resp.StatusCode, resp.Status, string(body))
|
||||
err = fmt.Errorf("unable to post to Librato: %d %s %s", resp.StatusCode, resp.Status, string(body))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,9 +42,10 @@ func Librato(r metrics.Registry, d time.Duration, e string, t string, s string,
|
|||
|
||||
func (rep *Reporter) Run() {
|
||||
log.Printf("WARNING: This client has been DEPRECATED! It has been moved to https://github.com/mihasya/go-metrics-librato and will be removed from rcrowley/go-metrics on August 5th 2015")
|
||||
ticker := time.Tick(rep.Interval)
|
||||
ticker := time.NewTicker(rep.Interval)
|
||||
defer ticker.Stop()
|
||||
metricsApi := &LibratoClient{rep.Email, rep.Token}
|
||||
for now := range ticker {
|
||||
for now := range ticker.C {
|
||||
var metrics Batch
|
||||
var err error
|
||||
if metrics, err = rep.BuildRequest(now, rep.Registry); err != nil {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ func BenchmarkMeter(b *testing.B) {
|
|||
func TestGetOrRegisterMeter(t *testing.T) {
|
||||
r := NewRegistry()
|
||||
NewRegisteredMeter("foo", r).Mark(47)
|
||||
if m := GetOrRegisterMeter("foo", r); 47 != m.Count() {
|
||||
if m := GetOrRegisterMeter("foo", r); m.Count() != 47 {
|
||||
t.Fatal(m)
|
||||
}
|
||||
}
|
||||
|
|
@ -40,7 +40,7 @@ func TestMeterDecay(t *testing.T) {
|
|||
func TestMeterNonzero(t *testing.T) {
|
||||
m := NewMeter()
|
||||
m.Mark(3)
|
||||
if count := m.Count(); 3 != count {
|
||||
if count := m.Count(); count != 3 {
|
||||
t.Errorf("m.Count(): 3 != %v\n", count)
|
||||
}
|
||||
}
|
||||
|
|
@ -48,11 +48,11 @@ func TestMeterNonzero(t *testing.T) {
|
|||
func TestMeterStop(t *testing.T) {
|
||||
l := len(arbiter.meters)
|
||||
m := NewMeter()
|
||||
if len(arbiter.meters) != l+1 {
|
||||
if l+1 != len(arbiter.meters) {
|
||||
t.Errorf("arbiter.meters: %d != %d\n", l+1, len(arbiter.meters))
|
||||
}
|
||||
m.Stop()
|
||||
if len(arbiter.meters) != l {
|
||||
if l != len(arbiter.meters) {
|
||||
t.Errorf("arbiter.meters: %d != %d\n", l, len(arbiter.meters))
|
||||
}
|
||||
}
|
||||
|
|
@ -67,7 +67,7 @@ func TestMeterSnapshot(t *testing.T) {
|
|||
|
||||
func TestMeterZero(t *testing.T) {
|
||||
m := NewMeter()
|
||||
if count := m.Count(); 0 != count {
|
||||
if count := m.Count(); count != 0 {
|
||||
t.Errorf("m.Count(): 0 != %v\n", count)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,20 +19,20 @@ func TestRegistry(t *testing.T) {
|
|||
i := 0
|
||||
r.Each(func(name string, iface interface{}) {
|
||||
i++
|
||||
if "foo" != name {
|
||||
if name != "foo" {
|
||||
t.Fatal(name)
|
||||
}
|
||||
if _, ok := iface.(Counter); !ok {
|
||||
t.Fatal(iface)
|
||||
}
|
||||
})
|
||||
if 1 != i {
|
||||
if i != 1 {
|
||||
t.Fatal(i)
|
||||
}
|
||||
r.Unregister("foo")
|
||||
i = 0
|
||||
r.Each(func(string, interface{}) { i++ })
|
||||
if 0 != i {
|
||||
if i != 0 {
|
||||
t.Fatal(i)
|
||||
}
|
||||
}
|
||||
|
|
@ -52,7 +52,7 @@ func TestRegistryDuplicate(t *testing.T) {
|
|||
t.Fatal(iface)
|
||||
}
|
||||
})
|
||||
if 1 != i {
|
||||
if i != 1 {
|
||||
t.Fatal(i)
|
||||
}
|
||||
}
|
||||
|
|
@ -60,11 +60,11 @@ func TestRegistryDuplicate(t *testing.T) {
|
|||
func TestRegistryGet(t *testing.T) {
|
||||
r := NewRegistry()
|
||||
r.Register("foo", NewCounter())
|
||||
if count := r.Get("foo").(Counter).Count(); 0 != count {
|
||||
if count := r.Get("foo").(Counter).Count(); count != 0 {
|
||||
t.Fatal(count)
|
||||
}
|
||||
r.Get("foo").(Counter).Inc(1)
|
||||
if count := r.Get("foo").(Counter).Count(); 1 != count {
|
||||
if count := r.Get("foo").(Counter).Count(); count != 1 {
|
||||
t.Fatal(count)
|
||||
}
|
||||
}
|
||||
|
|
@ -271,6 +271,9 @@ func TestChildPrefixedRegistryOfChildRegister(t *testing.T) {
|
|||
t.Fatal(err.Error())
|
||||
}
|
||||
err = r2.Register("baz", NewCounter())
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
c := NewCounter()
|
||||
Register("bars", c)
|
||||
|
||||
|
|
@ -278,7 +281,7 @@ func TestChildPrefixedRegistryOfChildRegister(t *testing.T) {
|
|||
r2.Each(func(name string, m interface{}) {
|
||||
i++
|
||||
if name != "prefix.prefix2.baz" {
|
||||
//t.Fatal(name)
|
||||
t.Fatal(name)
|
||||
}
|
||||
})
|
||||
if i != 1 {
|
||||
|
|
@ -294,11 +297,14 @@ func TestWalkRegistries(t *testing.T) {
|
|||
t.Fatal(err.Error())
|
||||
}
|
||||
err = r2.Register("baz", NewCounter())
|
||||
if err != nil {
|
||||
t.Fatal(err.Error())
|
||||
}
|
||||
c := NewCounter()
|
||||
Register("bars", c)
|
||||
|
||||
_, prefix := findPrefix(r2, "")
|
||||
if "prefix.prefix2." != prefix {
|
||||
if prefix != "prefix.prefix2." {
|
||||
t.Fatal(prefix)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,27 +22,27 @@ func TestRuntimeMemStats(t *testing.T) {
|
|||
zero := runtimeMetrics.MemStats.PauseNs.Count() // Get a "zero" since GC may have run before these tests.
|
||||
runtime.GC()
|
||||
CaptureRuntimeMemStatsOnce(r)
|
||||
if count := runtimeMetrics.MemStats.PauseNs.Count(); 1 != count-zero {
|
||||
if count := runtimeMetrics.MemStats.PauseNs.Count(); count-zero != 1 {
|
||||
t.Fatal(count - zero)
|
||||
}
|
||||
runtime.GC()
|
||||
runtime.GC()
|
||||
CaptureRuntimeMemStatsOnce(r)
|
||||
if count := runtimeMetrics.MemStats.PauseNs.Count(); 3 != count-zero {
|
||||
if count := runtimeMetrics.MemStats.PauseNs.Count(); count-zero != 3 {
|
||||
t.Fatal(count - zero)
|
||||
}
|
||||
for i := 0; i < 256; i++ {
|
||||
runtime.GC()
|
||||
}
|
||||
CaptureRuntimeMemStatsOnce(r)
|
||||
if count := runtimeMetrics.MemStats.PauseNs.Count(); 259 != count-zero {
|
||||
if count := runtimeMetrics.MemStats.PauseNs.Count(); count-zero != 259 {
|
||||
t.Fatal(count - zero)
|
||||
}
|
||||
for i := 0; i < 257; i++ {
|
||||
runtime.GC()
|
||||
}
|
||||
CaptureRuntimeMemStatsOnce(r)
|
||||
if count := runtimeMetrics.MemStats.PauseNs.Count(); 515 != count-zero { // We lost one because there were too many GCs between captures.
|
||||
if count := runtimeMetrics.MemStats.PauseNs.Count(); count-zero != 515 { // We lost one because there were too many GCs between captures.
|
||||
t.Fatal(count - zero)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ func (NilSample) Variance() float64 { return 0.0 }
|
|||
|
||||
// SampleMax returns the maximum value of the slice of int64.
|
||||
func SampleMax(values []int64) int64 {
|
||||
if 0 == len(values) {
|
||||
if len(values) == 0 {
|
||||
return 0
|
||||
}
|
||||
var max int64 = math.MinInt64
|
||||
|
|
@ -248,7 +248,7 @@ func SampleMax(values []int64) int64 {
|
|||
|
||||
// SampleMean returns the mean value of the slice of int64.
|
||||
func SampleMean(values []int64) float64 {
|
||||
if 0 == len(values) {
|
||||
if len(values) == 0 {
|
||||
return 0.0
|
||||
}
|
||||
return float64(SampleSum(values)) / float64(len(values))
|
||||
|
|
@ -256,7 +256,7 @@ func SampleMean(values []int64) float64 {
|
|||
|
||||
// SampleMin returns the minimum value of the slice of int64.
|
||||
func SampleMin(values []int64) int64 {
|
||||
if 0 == len(values) {
|
||||
if len(values) == 0 {
|
||||
return 0
|
||||
}
|
||||
var min int64 = math.MaxInt64
|
||||
|
|
@ -382,7 +382,7 @@ func SampleSum(values []int64) int64 {
|
|||
|
||||
// SampleVariance returns the variance of the slice of int64.
|
||||
func SampleVariance(values []int64) float64 {
|
||||
if 0 == len(values) {
|
||||
if len(values) == 0 {
|
||||
return 0.0
|
||||
}
|
||||
m := SampleMean(values)
|
||||
|
|
|
|||
|
|
@ -85,13 +85,13 @@ func TestExpDecaySample10(t *testing.T) {
|
|||
for i := 0; i < 10; i++ {
|
||||
s.Update(int64(i))
|
||||
}
|
||||
if size := s.Count(); 10 != size {
|
||||
if size := s.Count(); size != 10 {
|
||||
t.Errorf("s.Count(): 10 != %v\n", size)
|
||||
}
|
||||
if size := s.Size(); 10 != size {
|
||||
if size := s.Size(); size != 10 {
|
||||
t.Errorf("s.Size(): 10 != %v\n", size)
|
||||
}
|
||||
if l := len(s.Values()); 10 != l {
|
||||
if l := len(s.Values()); l != 10 {
|
||||
t.Errorf("len(s.Values()): 10 != %v\n", l)
|
||||
}
|
||||
for _, v := range s.Values() {
|
||||
|
|
@ -107,13 +107,13 @@ func TestExpDecaySample100(t *testing.T) {
|
|||
for i := 0; i < 100; i++ {
|
||||
s.Update(int64(i))
|
||||
}
|
||||
if size := s.Count(); 100 != size {
|
||||
if size := s.Count(); size != 100 {
|
||||
t.Errorf("s.Count(): 100 != %v\n", size)
|
||||
}
|
||||
if size := s.Size(); 100 != size {
|
||||
if size := s.Size(); size != 100 {
|
||||
t.Errorf("s.Size(): 100 != %v\n", size)
|
||||
}
|
||||
if l := len(s.Values()); 100 != l {
|
||||
if l := len(s.Values()); l != 100 {
|
||||
t.Errorf("len(s.Values()): 100 != %v\n", l)
|
||||
}
|
||||
for _, v := range s.Values() {
|
||||
|
|
@ -129,13 +129,13 @@ func TestExpDecaySample1000(t *testing.T) {
|
|||
for i := 0; i < 1000; i++ {
|
||||
s.Update(int64(i))
|
||||
}
|
||||
if size := s.Count(); 1000 != size {
|
||||
if size := s.Count(); size != 1000 {
|
||||
t.Errorf("s.Count(): 1000 != %v\n", size)
|
||||
}
|
||||
if size := s.Size(); 100 != size {
|
||||
if size := s.Size(); size != 100 {
|
||||
t.Errorf("s.Size(): 100 != %v\n", size)
|
||||
}
|
||||
if l := len(s.Values()); 100 != l {
|
||||
if l := len(s.Values()); l != 100 {
|
||||
t.Errorf("len(s.Values()): 100 != %v\n", l)
|
||||
}
|
||||
for _, v := range s.Values() {
|
||||
|
|
@ -209,13 +209,13 @@ func TestUniformSample(t *testing.T) {
|
|||
for i := 0; i < 1000; i++ {
|
||||
s.Update(int64(i))
|
||||
}
|
||||
if size := s.Count(); 1000 != size {
|
||||
if size := s.Count(); size != 1000 {
|
||||
t.Errorf("s.Count(): 1000 != %v\n", size)
|
||||
}
|
||||
if size := s.Size(); 100 != size {
|
||||
if size := s.Size(); size != 100 {
|
||||
t.Errorf("s.Size(): 100 != %v\n", size)
|
||||
}
|
||||
if l := len(s.Values()); 100 != l {
|
||||
if l := len(s.Values()); l != 100 {
|
||||
t.Errorf("len(s.Values()): 100 != %v\n", l)
|
||||
}
|
||||
for _, v := range s.Values() {
|
||||
|
|
@ -277,54 +277,54 @@ func benchmarkSample(b *testing.B, s Sample) {
|
|||
}
|
||||
|
||||
func testExpDecaySampleStatistics(t *testing.T, s Sample) {
|
||||
if count := s.Count(); 10000 != count {
|
||||
if count := s.Count(); count != 10000 {
|
||||
t.Errorf("s.Count(): 10000 != %v\n", count)
|
||||
}
|
||||
if min := s.Min(); 107 != min {
|
||||
if min := s.Min(); min != 107 {
|
||||
t.Errorf("s.Min(): 107 != %v\n", min)
|
||||
}
|
||||
if max := s.Max(); 10000 != max {
|
||||
if max := s.Max(); max != 10000 {
|
||||
t.Errorf("s.Max(): 10000 != %v\n", max)
|
||||
}
|
||||
if mean := s.Mean(); 4965.98 != mean {
|
||||
if mean := s.Mean(); mean != 4965.98 {
|
||||
t.Errorf("s.Mean(): 4965.98 != %v\n", mean)
|
||||
}
|
||||
if stdDev := s.StdDev(); 2959.825156930727 != stdDev {
|
||||
if stdDev := s.StdDev(); stdDev != 2959.825156930727 {
|
||||
t.Errorf("s.StdDev(): 2959.825156930727 != %v\n", stdDev)
|
||||
}
|
||||
ps := s.Percentiles([]float64{0.5, 0.75, 0.99})
|
||||
if 4615 != ps[0] {
|
||||
if ps[0] != 4615 {
|
||||
t.Errorf("median: 4615 != %v\n", ps[0])
|
||||
}
|
||||
if 7672 != ps[1] {
|
||||
if ps[1] != 7672 {
|
||||
t.Errorf("75th percentile: 7672 != %v\n", ps[1])
|
||||
}
|
||||
if 9998.99 != ps[2] {
|
||||
if ps[2] != 9998.99 {
|
||||
t.Errorf("99th percentile: 9998.99 != %v\n", ps[2])
|
||||
}
|
||||
}
|
||||
|
||||
func testUniformSampleStatistics(t *testing.T, s Sample) {
|
||||
if count := s.Count(); 10000 != count {
|
||||
if count := s.Count(); count != 10000 {
|
||||
t.Errorf("s.Count(): 10000 != %v\n", count)
|
||||
}
|
||||
if min := s.Min(); 37 != min {
|
||||
if min := s.Min(); min != 37 {
|
||||
t.Errorf("s.Min(): 37 != %v\n", min)
|
||||
}
|
||||
if max := s.Max(); 9989 != max {
|
||||
if max := s.Max(); max != 9989 {
|
||||
t.Errorf("s.Max(): 9989 != %v\n", max)
|
||||
}
|
||||
if mean := s.Mean(); 4748.14 != mean {
|
||||
if mean := s.Mean(); mean != 4748.14 {
|
||||
t.Errorf("s.Mean(): 4748.14 != %v\n", mean)
|
||||
}
|
||||
if stdDev := s.StdDev(); 2826.684117548333 != stdDev {
|
||||
if stdDev := s.StdDev(); stdDev != 2826.684117548333 {
|
||||
t.Errorf("s.StdDev(): 2826.684117548333 != %v\n", stdDev)
|
||||
}
|
||||
ps := s.Percentiles([]float64{0.5, 0.75, 0.99})
|
||||
if 4599 != ps[0] {
|
||||
if ps[0] != 4599 {
|
||||
t.Errorf("median: 4599 != %v\n", ps[0])
|
||||
}
|
||||
if 7380.5 != ps[1] {
|
||||
if ps[1] != 7380.5 {
|
||||
t.Errorf("75th percentile: 7380.5 != %v\n", ps[1])
|
||||
}
|
||||
if math.Abs(9986.429999999998-ps[2]) > epsilonPercentile {
|
||||
|
|
|
|||
|
|
@ -76,10 +76,7 @@ func NewTimer() Timer {
|
|||
}
|
||||
|
||||
// NilTimer is a no-op Timer.
|
||||
type NilTimer struct {
|
||||
h Histogram
|
||||
m Meter
|
||||
}
|
||||
type NilTimer struct{}
|
||||
|
||||
// Count is a no-op.
|
||||
func (NilTimer) Count() int64 { return 0 }
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ func BenchmarkTimer(b *testing.B) {
|
|||
func TestGetOrRegisterTimer(t *testing.T) {
|
||||
r := NewRegistry()
|
||||
NewRegisteredTimer("foo", r).Update(47)
|
||||
if tm := GetOrRegisterTimer("foo", r); 1 != tm.Count() {
|
||||
if tm := GetOrRegisterTimer("foo", r); tm.Count() != 1 {
|
||||
t.Fatal(tm)
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ func TestTimerExtremes(t *testing.T) {
|
|||
tm := NewTimer()
|
||||
tm.Update(math.MaxInt64)
|
||||
tm.Update(0)
|
||||
if stdDev := tm.StdDev(); 4.611686018427388e+18 != stdDev {
|
||||
if stdDev := tm.StdDev(); stdDev != 4.611686018427388e+18 {
|
||||
t.Errorf("tm.StdDev(): 4.611686018427388e+18 != %v\n", stdDev)
|
||||
}
|
||||
}
|
||||
|
|
@ -35,11 +35,11 @@ func TestTimerExtremes(t *testing.T) {
|
|||
func TestTimerStop(t *testing.T) {
|
||||
l := len(arbiter.meters)
|
||||
tm := NewTimer()
|
||||
if len(arbiter.meters) != l+1 {
|
||||
if l+1 != len(arbiter.meters) {
|
||||
t.Errorf("arbiter.meters: %d != %d\n", l+1, len(arbiter.meters))
|
||||
}
|
||||
tm.Stop()
|
||||
if len(arbiter.meters) != l {
|
||||
if l != len(arbiter.meters) {
|
||||
t.Errorf("arbiter.meters: %d != %d\n", l, len(arbiter.meters))
|
||||
}
|
||||
}
|
||||
|
|
@ -54,41 +54,41 @@ func TestTimerFunc(t *testing.T) {
|
|||
|
||||
func TestTimerZero(t *testing.T) {
|
||||
tm := NewTimer()
|
||||
if count := tm.Count(); 0 != count {
|
||||
if count := tm.Count(); count != 0 {
|
||||
t.Errorf("tm.Count(): 0 != %v\n", count)
|
||||
}
|
||||
if min := tm.Min(); 0 != min {
|
||||
if min := tm.Min(); min != 0 {
|
||||
t.Errorf("tm.Min(): 0 != %v\n", min)
|
||||
}
|
||||
if max := tm.Max(); 0 != max {
|
||||
if max := tm.Max(); max != 0 {
|
||||
t.Errorf("tm.Max(): 0 != %v\n", max)
|
||||
}
|
||||
if mean := tm.Mean(); 0.0 != mean {
|
||||
if mean := tm.Mean(); mean != 0.0 {
|
||||
t.Errorf("tm.Mean(): 0.0 != %v\n", mean)
|
||||
}
|
||||
if stdDev := tm.StdDev(); 0.0 != stdDev {
|
||||
if stdDev := tm.StdDev(); stdDev != 0.0 {
|
||||
t.Errorf("tm.StdDev(): 0.0 != %v\n", stdDev)
|
||||
}
|
||||
ps := tm.Percentiles([]float64{0.5, 0.75, 0.99})
|
||||
if 0.0 != ps[0] {
|
||||
if ps[0] != 0.0 {
|
||||
t.Errorf("median: 0.0 != %v\n", ps[0])
|
||||
}
|
||||
if 0.0 != ps[1] {
|
||||
if ps[1] != 0.0 {
|
||||
t.Errorf("75th percentile: 0.0 != %v\n", ps[1])
|
||||
}
|
||||
if 0.0 != ps[2] {
|
||||
if ps[2] != 0.0 {
|
||||
t.Errorf("99th percentile: 0.0 != %v\n", ps[2])
|
||||
}
|
||||
if rate1 := tm.Rate1(); 0.0 != rate1 {
|
||||
if rate1 := tm.Rate1(); rate1 != 0.0 {
|
||||
t.Errorf("tm.Rate1(): 0.0 != %v\n", rate1)
|
||||
}
|
||||
if rate5 := tm.Rate5(); 0.0 != rate5 {
|
||||
if rate5 := tm.Rate5(); rate5 != 0.0 {
|
||||
t.Errorf("tm.Rate5(): 0.0 != %v\n", rate5)
|
||||
}
|
||||
if rate15 := tm.Rate15(); 0.0 != rate15 {
|
||||
if rate15 := tm.Rate15(); rate15 != 0.0 {
|
||||
t.Errorf("tm.Rate15(): 0.0 != %v\n", rate15)
|
||||
}
|
||||
if rateMean := tm.RateMean(); 0.0 != rateMean {
|
||||
if rateMean := tm.RateMean(); rateMean != 0.0 {
|
||||
t.Errorf("tm.RateMean(): 0.0 != %v\n", rateMean)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,8 +84,8 @@ func New(eth Backend, config *Config, chainConfig *params.ChainConfig, mux *even
|
|||
// It's entered once and as soon as `Done` or `Failed` has been broadcasted the events are unregistered and
|
||||
// the loop is exited. This to prevent a major security vuln where external parties can DOS you with blocks
|
||||
// and halt your mining operation for as long as the DOS continues.
|
||||
func (self *Miner) update() {
|
||||
events := self.mux.Subscribe(downloader.StartEvent{}, downloader.DoneEvent{}, downloader.FailedEvent{})
|
||||
func (miner *Miner) update() {
|
||||
events := miner.mux.Subscribe(downloader.StartEvent{}, downloader.DoneEvent{}, downloader.FailedEvent{})
|
||||
defer events.Unsubscribe()
|
||||
|
||||
for {
|
||||
|
|
@ -96,77 +96,77 @@ func (self *Miner) update() {
|
|||
}
|
||||
switch ev.Data.(type) {
|
||||
case downloader.StartEvent:
|
||||
atomic.StoreInt32(&self.canStart, 0)
|
||||
if self.Mining() {
|
||||
self.Stop()
|
||||
atomic.StoreInt32(&self.shouldStart, 1)
|
||||
atomic.StoreInt32(&miner.canStart, 0)
|
||||
if miner.Mining() {
|
||||
miner.Stop()
|
||||
atomic.StoreInt32(&miner.shouldStart, 1)
|
||||
log.Info("Mining aborted due to sync")
|
||||
}
|
||||
case downloader.DoneEvent, downloader.FailedEvent:
|
||||
shouldStart := atomic.LoadInt32(&self.shouldStart) == 1
|
||||
shouldStart := atomic.LoadInt32(&miner.shouldStart) == 1
|
||||
|
||||
atomic.StoreInt32(&self.canStart, 1)
|
||||
atomic.StoreInt32(&self.shouldStart, 0)
|
||||
atomic.StoreInt32(&miner.canStart, 1)
|
||||
atomic.StoreInt32(&miner.shouldStart, 0)
|
||||
if shouldStart {
|
||||
self.Start(self.coinbase)
|
||||
miner.Start(miner.coinbase)
|
||||
}
|
||||
// stop immediately and ignore all further pending events
|
||||
return
|
||||
}
|
||||
case <-self.exitCh:
|
||||
case <-miner.exitCh:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Miner) Start(coinbase common.Address) {
|
||||
atomic.StoreInt32(&self.shouldStart, 1)
|
||||
self.SetEtherbase(coinbase)
|
||||
func (miner *Miner) Start(coinbase common.Address) {
|
||||
atomic.StoreInt32(&miner.shouldStart, 1)
|
||||
miner.SetEtherbase(coinbase)
|
||||
|
||||
if atomic.LoadInt32(&self.canStart) == 0 {
|
||||
if atomic.LoadInt32(&miner.canStart) == 0 {
|
||||
log.Info("Network syncing, will start miner afterwards")
|
||||
return
|
||||
}
|
||||
self.worker.start()
|
||||
miner.worker.start()
|
||||
}
|
||||
|
||||
func (self *Miner) Stop() {
|
||||
self.worker.stop()
|
||||
atomic.StoreInt32(&self.shouldStart, 0)
|
||||
func (miner *Miner) Stop() {
|
||||
miner.worker.stop()
|
||||
atomic.StoreInt32(&miner.shouldStart, 0)
|
||||
}
|
||||
|
||||
func (self *Miner) Close() {
|
||||
self.worker.close()
|
||||
close(self.exitCh)
|
||||
func (miner *Miner) Close() {
|
||||
miner.worker.close()
|
||||
close(miner.exitCh)
|
||||
}
|
||||
|
||||
func (self *Miner) Mining() bool {
|
||||
return self.worker.isRunning()
|
||||
func (miner *Miner) Mining() bool {
|
||||
return miner.worker.isRunning()
|
||||
}
|
||||
|
||||
func (self *Miner) HashRate() uint64 {
|
||||
if pow, ok := self.engine.(consensus.PoW); ok {
|
||||
func (miner *Miner) HashRate() uint64 {
|
||||
if pow, ok := miner.engine.(consensus.PoW); ok {
|
||||
return uint64(pow.Hashrate())
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *Miner) SetExtra(extra []byte) error {
|
||||
func (miner *Miner) SetExtra(extra []byte) error {
|
||||
if uint64(len(extra)) > params.MaximumExtraDataSize {
|
||||
return fmt.Errorf("Extra exceeds max length. %d > %v", len(extra), params.MaximumExtraDataSize)
|
||||
return fmt.Errorf("extra exceeds max length. %d > %v", len(extra), params.MaximumExtraDataSize)
|
||||
}
|
||||
self.worker.setExtra(extra)
|
||||
miner.worker.setExtra(extra)
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetRecommitInterval sets the interval for sealing work resubmitting.
|
||||
func (self *Miner) SetRecommitInterval(interval time.Duration) {
|
||||
self.worker.setRecommitInterval(interval)
|
||||
func (miner *Miner) SetRecommitInterval(interval time.Duration) {
|
||||
miner.worker.setRecommitInterval(interval)
|
||||
}
|
||||
|
||||
// Pending returns the currently pending block and associated state.
|
||||
func (self *Miner) Pending() (*types.Block, *state.StateDB) {
|
||||
return self.worker.pending()
|
||||
func (miner *Miner) Pending() (*types.Block, *state.StateDB) {
|
||||
return miner.worker.pending()
|
||||
}
|
||||
|
||||
// PendingBlock returns the currently pending block.
|
||||
|
|
@ -174,11 +174,11 @@ func (self *Miner) Pending() (*types.Block, *state.StateDB) {
|
|||
// Note, to access both the pending block and the pending state
|
||||
// simultaneously, please use Pending(), as the pending state can
|
||||
// change between multiple method calls
|
||||
func (self *Miner) PendingBlock() *types.Block {
|
||||
return self.worker.pendingBlock()
|
||||
func (miner *Miner) PendingBlock() *types.Block {
|
||||
return miner.worker.pendingBlock()
|
||||
}
|
||||
|
||||
func (self *Miner) SetEtherbase(addr common.Address) {
|
||||
self.coinbase = addr
|
||||
self.worker.setEtherbase(addr)
|
||||
func (miner *Miner) SetEtherbase(addr common.Address) {
|
||||
miner.coinbase = addr
|
||||
miner.worker.setEtherbase(addr)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package miner
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"sync/atomic"
|
||||
|
|
@ -214,6 +215,7 @@ func testGenerateBlockAndImport(t *testing.T, isClique bool) {
|
|||
chain, _ := core.NewBlockChain(db2, nil, b.chain.Config(), engine, vm.Config{}, nil)
|
||||
defer chain.Stop()
|
||||
|
||||
loopErr := make(chan error)
|
||||
newBlock := make(chan struct{})
|
||||
listenNewBlock := func() {
|
||||
sub := w.mux.Subscribe(core.NewMinedBlockEvent{})
|
||||
|
|
@ -223,7 +225,7 @@ func testGenerateBlockAndImport(t *testing.T, isClique bool) {
|
|||
block := item.Data.(core.NewMinedBlockEvent).Block
|
||||
_, err := chain.InsertChain([]*types.Block{block})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to insert new mined block:%d, error:%v", block.NumberU64(), err)
|
||||
loopErr <- fmt.Errorf("failed to insert new mined block:%d, error:%v", block.NumberU64(), err)
|
||||
}
|
||||
newBlock <- struct{}{}
|
||||
}
|
||||
|
|
@ -241,6 +243,8 @@ func testGenerateBlockAndImport(t *testing.T, isClique bool) {
|
|||
w.postSideBlock(core.ChainSideEvent{Block: b.newRandomUncle()})
|
||||
w.postSideBlock(core.ChainSideEvent{Block: b.newRandomUncle()})
|
||||
select {
|
||||
case e := <-loopErr:
|
||||
t.Fatal(e)
|
||||
case <-newBlock:
|
||||
case <-time.NewTimer(3 * time.Second).C: // Worker needs 1s to include new changes.
|
||||
t.Fatalf("timeout")
|
||||
|
|
@ -343,7 +347,9 @@ func TestStreamUncleBlock(t *testing.T) {
|
|||
t.Error("new task timeout")
|
||||
}
|
||||
}
|
||||
|
||||
w.postSideBlock(core.ChainSideEvent{Block: b.uncleBlock})
|
||||
|
||||
select {
|
||||
case <-taskCh:
|
||||
case <-time.NewTimer(time.Second).C:
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/internal/build"
|
||||
"github.com/cespare/cp"
|
||||
)
|
||||
|
||||
// androidTestClass is a Java class to do some lightweight tests against the Android
|
||||
|
|
@ -212,7 +212,7 @@ func TestAndroid(t *testing.T) {
|
|||
t.Logf("%s", output)
|
||||
t.Fatalf("failed to run gomobile bind: %v", err)
|
||||
}
|
||||
build.CopyFile(filepath.Join("libs", "geth.aar"), "geth.aar", os.ModePerm)
|
||||
cp.CopyFile(filepath.Join("libs", "geth.aar"), "geth.aar")
|
||||
|
||||
if err = ioutil.WriteFile(filepath.Join("src", "androidTest", "java", "org", "ethereum", "gethtest", "AndroidTest.java"), []byte(androidTestClass), os.ModePerm); err != nil {
|
||||
t.Fatalf("failed to write Android test class: %v", err)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package discover
|
|||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
)
|
||||
|
|
@ -106,6 +107,12 @@ func (it *lookup) startQueries() bool {
|
|||
it.tab.mutex.Lock()
|
||||
closest := it.tab.closest(it.result.target, bucketSize, false)
|
||||
it.tab.mutex.Unlock()
|
||||
// Avoid finishing the lookup too quickly if table is empty. It'd be better to wait
|
||||
// for the table to fill in this case, but there is no good mechanism for that
|
||||
// yet.
|
||||
if len(closest.entries) == 0 {
|
||||
it.slowdown()
|
||||
}
|
||||
it.queries = 1
|
||||
it.replyCh <- closest.entries
|
||||
return true
|
||||
|
|
@ -124,6 +131,15 @@ func (it *lookup) startQueries() bool {
|
|||
return it.queries > 0
|
||||
}
|
||||
|
||||
func (it *lookup) slowdown() {
|
||||
sleep := time.NewTimer(1 * time.Second)
|
||||
defer sleep.Stop()
|
||||
select {
|
||||
case <-sleep.C:
|
||||
case <-it.tab.closeReq:
|
||||
}
|
||||
}
|
||||
|
||||
func (it *lookup) query(n *node, reply chan<- []*node) {
|
||||
fails := it.tab.db.FindFails(n.ID(), n.IP())
|
||||
r, err := it.queryfunc(n)
|
||||
|
|
|
|||
4
p2p/discv5/README
Normal file
4
p2p/discv5/README
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
This package is an early prototype of Discovery v5. Do not use this code.
|
||||
|
||||
See https://github.com/ethereum/devp2p/blob/master/discv5/discv5.md for the
|
||||
current Discovery v5 specification.
|
||||
|
|
@ -62,7 +62,6 @@ var (
|
|||
nodeDBDiscoverPing = nodeDBDiscoverRoot + ":lastping"
|
||||
nodeDBDiscoverPong = nodeDBDiscoverRoot + ":lastpong"
|
||||
nodeDBDiscoverFindFails = nodeDBDiscoverRoot + ":findfail"
|
||||
nodeDBDiscoverLocalEndpoint = nodeDBDiscoverRoot + ":localendpoint"
|
||||
nodeDBTopicRegTickets = ":tickets"
|
||||
)
|
||||
|
||||
|
|
@ -311,20 +310,6 @@ func (db *nodeDB) updateFindFails(id NodeID, fails int) error {
|
|||
return db.storeInt64(makeKey(id, nodeDBDiscoverFindFails), int64(fails))
|
||||
}
|
||||
|
||||
// localEndpoint returns the last local endpoint communicated to the
|
||||
// given remote node.
|
||||
func (db *nodeDB) localEndpoint(id NodeID) *rpcEndpoint {
|
||||
var ep rpcEndpoint
|
||||
if err := db.fetchRLP(makeKey(id, nodeDBDiscoverLocalEndpoint), &ep); err != nil {
|
||||
return nil
|
||||
}
|
||||
return &ep
|
||||
}
|
||||
|
||||
func (db *nodeDB) updateLocalEndpoint(id NodeID, ep rpcEndpoint) error {
|
||||
return db.storeRLP(makeKey(id, nodeDBDiscoverLocalEndpoint), &ep)
|
||||
}
|
||||
|
||||
// querySeeds retrieves random nodes to be used as potential seed nodes
|
||||
// for bootstrapping.
|
||||
func (db *nodeDB) querySeeds(n int, maxAge time.Duration) []*Node {
|
||||
|
|
|
|||
|
|
@ -77,14 +77,6 @@ type Network struct {
|
|||
nursery []*Node
|
||||
nodes map[NodeID]*Node // tracks active nodes with state != known
|
||||
timeoutTimers map[timeoutEvent]*time.Timer
|
||||
|
||||
// Revalidation queues.
|
||||
// Nodes put on these queues will be pinged eventually.
|
||||
slowRevalidateQueue []*Node
|
||||
fastRevalidateQueue []*Node
|
||||
|
||||
// Buffers for state transition.
|
||||
sendBuf []*ingressPacket
|
||||
}
|
||||
|
||||
// transport is implemented by the UDP transport.
|
||||
|
|
@ -107,7 +99,6 @@ type findnodeQuery struct {
|
|||
remote *Node
|
||||
target common.Hash
|
||||
reply chan<- []*Node
|
||||
nresults int // counter for received nodes
|
||||
}
|
||||
|
||||
type topicRegisterReq struct {
|
||||
|
|
@ -650,10 +641,10 @@ loop:
|
|||
if net.conn != nil {
|
||||
net.conn.Close()
|
||||
}
|
||||
if refreshDone != nil {
|
||||
// TODO: wait for pending refresh.
|
||||
//<-refreshResults
|
||||
}
|
||||
// if refreshDone != nil {
|
||||
// <-refreshResults
|
||||
// }
|
||||
// Cancel all pending timeouts.
|
||||
for _, timer := range net.timeoutTimers {
|
||||
timer.Stop()
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
package discv5
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"testing"
|
||||
"time"
|
||||
|
|
@ -265,10 +264,6 @@ type preminedTestnet struct {
|
|||
net *Network
|
||||
}
|
||||
|
||||
func (tn *preminedTestnet) sendFindnode(to *Node, target NodeID) {
|
||||
panic("sendFindnode called")
|
||||
}
|
||||
|
||||
func (tn *preminedTestnet) sendFindnodeHash(to *Node, target common.Hash) {
|
||||
// current log distance is encoded in port number
|
||||
// fmt.Println("findnode query at dist", toaddr.Port)
|
||||
|
|
@ -316,10 +311,6 @@ func (tn *preminedTestnet) sendNeighbours(to *Node, nodes []*Node) {
|
|||
panic("sendNeighbours called")
|
||||
}
|
||||
|
||||
func (tn *preminedTestnet) sendTopicQuery(to *Node, topic Topic) {
|
||||
panic("sendTopicQuery called")
|
||||
}
|
||||
|
||||
func (tn *preminedTestnet) sendTopicNodes(to *Node, queryHash common.Hash, nodes []*Node) {
|
||||
panic("sendTopicNodes called")
|
||||
}
|
||||
|
|
@ -334,41 +325,6 @@ func (*preminedTestnet) localAddr() *net.UDPAddr {
|
|||
return &net.UDPAddr{IP: net.ParseIP("10.0.1.1"), Port: 40000}
|
||||
}
|
||||
|
||||
// mine generates a testnet struct literal with nodes at
|
||||
// various distances to the given target.
|
||||
func (tn *preminedTestnet) mine(target NodeID) {
|
||||
tn.target = target
|
||||
tn.targetSha = crypto.Keccak256Hash(tn.target[:])
|
||||
found := 0
|
||||
for found < bucketSize*10 {
|
||||
k := newkey()
|
||||
id := PubkeyID(&k.PublicKey)
|
||||
sha := crypto.Keccak256Hash(id[:])
|
||||
ld := logdist(tn.targetSha, sha)
|
||||
if len(tn.dists[ld]) < bucketSize {
|
||||
tn.dists[ld] = append(tn.dists[ld], id)
|
||||
fmt.Println("found ID with ld", ld)
|
||||
found++
|
||||
}
|
||||
}
|
||||
fmt.Println("&preminedTestnet{")
|
||||
fmt.Printf(" target: %#v,\n", tn.target)
|
||||
fmt.Printf(" targetSha: %#v,\n", tn.targetSha)
|
||||
fmt.Printf(" dists: [%d][]NodeID{\n", len(tn.dists))
|
||||
for ld, ns := range &tn.dists {
|
||||
if len(ns) == 0 {
|
||||
continue
|
||||
}
|
||||
fmt.Printf(" %d: []NodeID{\n", ld)
|
||||
for _, n := range ns {
|
||||
fmt.Printf(" MustHexID(\"%x\"),\n", n[:])
|
||||
}
|
||||
fmt.Println(" },")
|
||||
}
|
||||
fmt.Println(" },")
|
||||
fmt.Println("}")
|
||||
}
|
||||
|
||||
func injectResponse(net *Network, from *Node, ev nodeEvent, packet interface{}) {
|
||||
go net.reqReadPacket(ingressPacket{remoteID: from.ID, remoteAddr: from.addr(), ev: ev, data: packet})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,23 +66,6 @@ func (n *Node) addr() *net.UDPAddr {
|
|||
return &net.UDPAddr{IP: n.IP, Port: int(n.UDP)}
|
||||
}
|
||||
|
||||
func (n *Node) setAddr(a *net.UDPAddr) {
|
||||
n.IP = a.IP
|
||||
if ipv4 := a.IP.To4(); ipv4 != nil {
|
||||
n.IP = ipv4
|
||||
}
|
||||
n.UDP = uint16(a.Port)
|
||||
}
|
||||
|
||||
// compares the given address against the stored values.
|
||||
func (n *Node) addrEqual(a *net.UDPAddr) bool {
|
||||
ip := a.IP
|
||||
if ipv4 := a.IP.To4(); ipv4 != nil {
|
||||
ip = ipv4
|
||||
}
|
||||
return n.UDP == uint16(a.Port) && n.IP.Equal(ip)
|
||||
}
|
||||
|
||||
// Incomplete returns true for nodes with no IP address.
|
||||
func (n *Node) Incomplete() bool {
|
||||
return n.IP == nil
|
||||
|
|
@ -326,14 +309,6 @@ func (n NodeID) Pubkey() (*ecdsa.PublicKey, error) {
|
|||
return p, nil
|
||||
}
|
||||
|
||||
func (id NodeID) mustPubkey() ecdsa.PublicKey {
|
||||
pk, err := id.Pubkey()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return *pk
|
||||
}
|
||||
|
||||
// recoverNodeID computes the public key used to sign the
|
||||
// given hash from the signature.
|
||||
func recoverNodeID(hash, sig []byte) (id NodeID, err error) {
|
||||
|
|
|
|||
|
|
@ -1,126 +0,0 @@
|
|||
// 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/>.
|
||||
|
||||
// Contains the NTP time drift detection via the SNTP protocol:
|
||||
// https://tools.ietf.org/html/rfc4330
|
||||
|
||||
package discv5
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
)
|
||||
|
||||
const (
|
||||
ntpPool = "pool.ntp.org" // ntpPool is the NTP server to query for the current time
|
||||
ntpChecks = 3 // Number of measurements to do against the NTP server
|
||||
)
|
||||
|
||||
// durationSlice attaches the methods of sort.Interface to []time.Duration,
|
||||
// sorting in increasing order.
|
||||
type durationSlice []time.Duration
|
||||
|
||||
func (s durationSlice) Len() int { return len(s) }
|
||||
func (s durationSlice) Less(i, j int) bool { return s[i] < s[j] }
|
||||
func (s durationSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
// checkClockDrift queries an NTP server for clock drifts and warns the user if
|
||||
// one large enough is detected.
|
||||
func checkClockDrift() {
|
||||
drift, err := sntpDrift(ntpChecks)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if drift < -driftThreshold || drift > driftThreshold {
|
||||
warning := fmt.Sprintf("System clock seems off by %v, which can prevent network connectivity", drift)
|
||||
howtofix := fmt.Sprintf("Please enable network time synchronisation in system settings")
|
||||
separator := strings.Repeat("-", len(warning))
|
||||
|
||||
log.Warn(separator)
|
||||
log.Warn(warning)
|
||||
log.Warn(howtofix)
|
||||
log.Warn(separator)
|
||||
} else {
|
||||
log.Debug(fmt.Sprintf("Sanity NTP check reported %v drift, all ok", drift))
|
||||
}
|
||||
}
|
||||
|
||||
// sntpDrift does a naive time resolution against an NTP server and returns the
|
||||
// measured drift. This method uses the simple version of NTP. It's not precise
|
||||
// but should be fine for these purposes.
|
||||
//
|
||||
// Note, it executes two extra measurements compared to the number of requested
|
||||
// ones to be able to discard the two extremes as outliers.
|
||||
func sntpDrift(measurements int) (time.Duration, error) {
|
||||
// Resolve the address of the NTP server
|
||||
addr, err := net.ResolveUDPAddr("udp", ntpPool+":123")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// Construct the time request (empty package with only 2 fields set):
|
||||
// Bits 3-5: Protocol version, 3
|
||||
// Bits 6-8: Mode of operation, client, 3
|
||||
request := make([]byte, 48)
|
||||
request[0] = 3<<3 | 3
|
||||
|
||||
// Execute each of the measurements
|
||||
drifts := []time.Duration{}
|
||||
for i := 0; i < measurements+2; i++ {
|
||||
// Dial the NTP server and send the time retrieval request
|
||||
conn, err := net.DialUDP("udp", nil, addr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
sent := time.Now()
|
||||
if _, err = conn.Write(request); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// Retrieve the reply and calculate the elapsed time
|
||||
conn.SetDeadline(time.Now().Add(5 * time.Second))
|
||||
|
||||
reply := make([]byte, 48)
|
||||
if _, err = conn.Read(reply); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
elapsed := time.Since(sent)
|
||||
|
||||
// Reconstruct the time from the reply data
|
||||
sec := uint64(reply[43]) | uint64(reply[42])<<8 | uint64(reply[41])<<16 | uint64(reply[40])<<24
|
||||
frac := uint64(reply[47]) | uint64(reply[46])<<8 | uint64(reply[45])<<16 | uint64(reply[44])<<24
|
||||
|
||||
nanosec := sec*1e9 + (frac*1e9)>>32
|
||||
|
||||
t := time.Date(1900, 1, 1, 0, 0, 0, 0, time.UTC).Add(time.Duration(nanosec)).Local()
|
||||
|
||||
// Calculate the drift based on an assumed answer time of RRT/2
|
||||
drifts = append(drifts, sent.Sub(t)+elapsed/2)
|
||||
}
|
||||
// Calculate average drif (drop two extremities to avoid outliers)
|
||||
sort.Sort(durationSlice(drifts))
|
||||
|
||||
drift := time.Duration(0)
|
||||
for i := 1; i < len(drifts)-1; i++ {
|
||||
drift += drifts[i]
|
||||
}
|
||||
return drift / time.Duration(measurements), nil
|
||||
}
|
||||
|
|
@ -294,15 +294,6 @@ func (s *simulation) launchNode(log bool) *Network {
|
|||
return net
|
||||
}
|
||||
|
||||
func (s *simulation) dropNode(id NodeID) {
|
||||
s.mu.Lock()
|
||||
n := s.nodes[id]
|
||||
delete(s.nodes, id)
|
||||
s.mu.Unlock()
|
||||
|
||||
n.Close()
|
||||
}
|
||||
|
||||
type simTransport struct {
|
||||
joinTime time.Time
|
||||
sender NodeID
|
||||
|
|
@ -358,22 +349,6 @@ func (st *simTransport) sendPing(remote *Node, remoteAddr *net.UDPAddr, topics [
|
|||
return hash
|
||||
}
|
||||
|
||||
func (st *simTransport) sendPong(remote *Node, pingHash []byte) {
|
||||
raddr := remote.addr()
|
||||
|
||||
st.sendPacket(remote.ID, ingressPacket{
|
||||
remoteID: st.sender,
|
||||
remoteAddr: st.senderAddr,
|
||||
hash: st.nextHash(),
|
||||
ev: pongPacket,
|
||||
data: &pong{
|
||||
To: rpcEndpoint{IP: raddr.IP, UDP: uint16(raddr.Port), TCP: 30303},
|
||||
ReplyTok: pingHash,
|
||||
Expiration: uint64(time.Now().Unix() + int64(expiration)),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (st *simTransport) sendFindnodeHash(remote *Node, target common.Hash) {
|
||||
st.sendPacket(remote.ID, ingressPacket{
|
||||
remoteID: st.sender,
|
||||
|
|
|
|||
|
|
@ -14,12 +14,8 @@
|
|||
// 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 discv5 implements the RLPx v5 Topic Discovery Protocol.
|
||||
//
|
||||
// The Topic Discovery protocol provides a way to find RLPx nodes that
|
||||
// can be connected to. It uses a Kademlia-like protocol to maintain a
|
||||
// distributed database of the IDs and endpoints of all listening
|
||||
// nodes.
|
||||
// Package discv5 is a prototype implementation of Discvery v5.
|
||||
// Deprecated: do not use this package.
|
||||
package discv5
|
||||
|
||||
import (
|
||||
|
|
|
|||
|
|
@ -31,72 +31,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/crypto"
|
||||
)
|
||||
|
||||
type nullTransport struct{}
|
||||
|
||||
func (nullTransport) sendPing(remote *Node, remoteAddr *net.UDPAddr) []byte { return []byte{1} }
|
||||
func (nullTransport) sendPong(remote *Node, pingHash []byte) {}
|
||||
func (nullTransport) sendFindnode(remote *Node, target NodeID) {}
|
||||
func (nullTransport) sendNeighbours(remote *Node, nodes []*Node) {}
|
||||
func (nullTransport) localAddr() *net.UDPAddr { return new(net.UDPAddr) }
|
||||
func (nullTransport) Close() {}
|
||||
|
||||
// func TestTable_pingReplace(t *testing.T) {
|
||||
// doit := func(newNodeIsResponding, lastInBucketIsResponding bool) {
|
||||
// transport := newPingRecorder()
|
||||
// tab, _ := newTable(transport, NodeID{}, &net.UDPAddr{})
|
||||
// defer tab.Close()
|
||||
// pingSender := NewNode(MustHexID("a502af0f59b2aab7746995408c79e9ca312d2793cc997e44fc55eda62f0150bbb8c59a6f9269ba3a081518b62699ee807c7c19c20125ddfccca872608af9e370"), net.IP{}, 99, 99)
|
||||
//
|
||||
// // fill up the sender's bucket.
|
||||
// last := fillBucket(tab, 253)
|
||||
//
|
||||
// // this call to bond should replace the last node
|
||||
// // in its bucket if the node is not responding.
|
||||
// transport.responding[last.ID] = lastInBucketIsResponding
|
||||
// transport.responding[pingSender.ID] = newNodeIsResponding
|
||||
// tab.bond(true, pingSender.ID, &net.UDPAddr{}, 0)
|
||||
//
|
||||
// // first ping goes to sender (bonding pingback)
|
||||
// if !transport.pinged[pingSender.ID] {
|
||||
// t.Error("table did not ping back sender")
|
||||
// }
|
||||
// if newNodeIsResponding {
|
||||
// // second ping goes to oldest node in bucket
|
||||
// // to see whether it is still alive.
|
||||
// if !transport.pinged[last.ID] {
|
||||
// t.Error("table did not ping last node in bucket")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// tab.mutex.Lock()
|
||||
// defer tab.mutex.Unlock()
|
||||
// if l := len(tab.buckets[253].entries); l != bucketSize {
|
||||
// t.Errorf("wrong bucket size after bond: got %d, want %d", l, bucketSize)
|
||||
// }
|
||||
//
|
||||
// if lastInBucketIsResponding || !newNodeIsResponding {
|
||||
// if !contains(tab.buckets[253].entries, last.ID) {
|
||||
// t.Error("last entry was removed")
|
||||
// }
|
||||
// if contains(tab.buckets[253].entries, pingSender.ID) {
|
||||
// t.Error("new entry was added")
|
||||
// }
|
||||
// } else {
|
||||
// if contains(tab.buckets[253].entries, last.ID) {
|
||||
// t.Error("last entry was not removed")
|
||||
// }
|
||||
// if !contains(tab.buckets[253].entries, pingSender.ID) {
|
||||
// t.Error("new entry was not added")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// doit(true, true)
|
||||
// doit(false, true)
|
||||
// doit(true, false)
|
||||
// doit(false, false)
|
||||
// }
|
||||
|
||||
func TestBucket_bumpNoDuplicates(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &quick.Config{
|
||||
|
|
@ -139,17 +73,6 @@ func TestBucket_bumpNoDuplicates(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// fillBucket inserts nodes into the given bucket until
|
||||
// it is full. The node's IDs dont correspond to their
|
||||
// hashes.
|
||||
func fillBucket(tab *Table, ld int) (last *Node) {
|
||||
b := tab.buckets[ld]
|
||||
for len(b.entries) < bucketSize {
|
||||
b.entries = append(b.entries, nodeAtDistance(tab.self.sha, ld))
|
||||
}
|
||||
return b.entries[bucketSize-1]
|
||||
}
|
||||
|
||||
// nodeAtDistance creates a node for which logdist(base, n.sha) == ld.
|
||||
// The node's ID does not correspond to n.sha.
|
||||
func nodeAtDistance(base common.Hash, ld int) (n *Node) {
|
||||
|
|
@ -159,28 +82,6 @@ func nodeAtDistance(base common.Hash, ld int) (n *Node) {
|
|||
return n
|
||||
}
|
||||
|
||||
type pingRecorder struct{ responding, pinged map[NodeID]bool }
|
||||
|
||||
func newPingRecorder() *pingRecorder {
|
||||
return &pingRecorder{make(map[NodeID]bool), make(map[NodeID]bool)}
|
||||
}
|
||||
|
||||
func (t *pingRecorder) findnode(toid NodeID, toaddr *net.UDPAddr, target NodeID) ([]*Node, error) {
|
||||
panic("findnode called on pingRecorder")
|
||||
}
|
||||
func (t *pingRecorder) close() {}
|
||||
func (t *pingRecorder) waitping(from NodeID) error {
|
||||
return nil // remote always pings
|
||||
}
|
||||
func (t *pingRecorder) ping(toid NodeID, toaddr *net.UDPAddr) error {
|
||||
t.pinged[toid] = true
|
||||
if t.responding[toid] {
|
||||
return nil
|
||||
} else {
|
||||
return errTimeout
|
||||
}
|
||||
}
|
||||
|
||||
func TestTable_closest(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import (
|
|||
"fmt"
|
||||
"math"
|
||||
"math/rand"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
|
@ -33,8 +32,6 @@ import (
|
|||
|
||||
const (
|
||||
ticketTimeBucketLen = time.Minute
|
||||
timeWindow = 10 // * ticketTimeBucketLen
|
||||
wantTicketsInWindow = 10
|
||||
collectFrequency = time.Second * 30
|
||||
registerFrequency = time.Second * 60
|
||||
maxCollectDebt = 10
|
||||
|
|
@ -139,7 +136,6 @@ type ticketStore struct {
|
|||
|
||||
lastBucketFetched timeBucket
|
||||
nextTicketCached *ticketRef
|
||||
nextTicketReg mclock.AbsTime
|
||||
|
||||
searchTopicMap map[Topic]searchTopic
|
||||
nextTopicQueryCleanup mclock.AbsTime
|
||||
|
|
@ -268,57 +264,6 @@ func (s *ticketStore) nextSearchLookup(topic Topic) lookupInfo {
|
|||
return target
|
||||
}
|
||||
|
||||
// ticketsInWindow returns the tickets of a given topic in the registration window.
|
||||
func (s *ticketStore) ticketsInWindow(topic Topic) []ticketRef {
|
||||
// Sanity check that the topic still exists before operating on it
|
||||
if s.tickets[topic] == nil {
|
||||
log.Warn("Listing non-existing discovery tickets", "topic", topic)
|
||||
return nil
|
||||
}
|
||||
// Gather all the tickers in the next time window
|
||||
var tickets []ticketRef
|
||||
|
||||
buckets := s.tickets[topic].buckets
|
||||
for idx := timeBucket(0); idx < timeWindow; idx++ {
|
||||
tickets = append(tickets, buckets[s.lastBucketFetched+idx]...)
|
||||
}
|
||||
log.Trace("Retrieved discovery registration tickets", "topic", topic, "from", s.lastBucketFetched, "tickets", len(tickets))
|
||||
return tickets
|
||||
}
|
||||
|
||||
func (s *ticketStore) removeExcessTickets(t Topic) {
|
||||
tickets := s.ticketsInWindow(t)
|
||||
if len(tickets) <= wantTicketsInWindow {
|
||||
return
|
||||
}
|
||||
sort.Sort(ticketRefByWaitTime(tickets))
|
||||
for _, r := range tickets[wantTicketsInWindow:] {
|
||||
s.removeTicketRef(r)
|
||||
}
|
||||
}
|
||||
|
||||
type ticketRefByWaitTime []ticketRef
|
||||
|
||||
// Len is the number of elements in the collection.
|
||||
func (s ticketRefByWaitTime) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func (ref ticketRef) waitTime() mclock.AbsTime {
|
||||
return ref.t.regTime[ref.idx] - ref.t.issueTime
|
||||
}
|
||||
|
||||
// Less reports whether the element with
|
||||
// index i should sort before the element with index j.
|
||||
func (s ticketRefByWaitTime) Less(i, j int) bool {
|
||||
return s[i].waitTime() < s[j].waitTime()
|
||||
}
|
||||
|
||||
// Swap swaps the elements with indexes i and j.
|
||||
func (s ticketRefByWaitTime) Swap(i, j int) {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
|
||||
func (s *ticketStore) addTicketRef(r ticketRef) {
|
||||
topic := r.t.topics[r.idx]
|
||||
tickets := s.tickets[topic]
|
||||
|
|
@ -565,15 +510,6 @@ func (s *ticketStore) addTicket(localTime mclock.AbsTime, pingHash []byte, ticke
|
|||
}
|
||||
}
|
||||
|
||||
func (s *ticketStore) getNodeTicket(node *Node) *ticket {
|
||||
if s.nodes[node] == nil {
|
||||
log.Trace("Retrieving node ticket", "node", node.ID, "serial", nil)
|
||||
} else {
|
||||
log.Trace("Retrieving node ticket", "node", node.ID, "serial", s.nodes[node].serial)
|
||||
}
|
||||
return s.nodes[node]
|
||||
}
|
||||
|
||||
func (s *ticketStore) canQueryTopic(node *Node, topic Topic) bool {
|
||||
qq := s.queriesSent[node]
|
||||
if qq != nil {
|
||||
|
|
@ -770,12 +706,6 @@ func globalRandRead(b []byte) {
|
|||
}
|
||||
}
|
||||
|
||||
func (r *topicRadius) isInRadius(addrHash common.Hash) bool {
|
||||
nodePrefix := binary.BigEndian.Uint64(addrHash[0:8])
|
||||
dist := nodePrefix ^ r.topicHashPrefix
|
||||
return dist < r.radius
|
||||
}
|
||||
|
||||
func (r *topicRadius) chooseLookupBucket(a, b int) int {
|
||||
if a < 0 {
|
||||
a = 0
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/p2p/nat"
|
||||
"github.com/ethereum/go-ethereum/p2p/netutil"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
|
@ -38,15 +37,12 @@ const Version = 4
|
|||
var (
|
||||
errPacketTooSmall = errors.New("too small")
|
||||
errBadPrefix = errors.New("bad prefix")
|
||||
errTimeout = errors.New("RPC timeout")
|
||||
)
|
||||
|
||||
// Timeouts
|
||||
const (
|
||||
respTimeout = 500 * time.Millisecond
|
||||
expiration = 20 * time.Second
|
||||
|
||||
driftThreshold = 10 * time.Second // Allowed clock drift before warning user
|
||||
)
|
||||
|
||||
// RPC request structures
|
||||
|
|
@ -187,10 +183,6 @@ func makeEndpoint(addr *net.UDPAddr, tcpPort uint16) rpcEndpoint {
|
|||
return rpcEndpoint{IP: ip, UDP: uint16(addr.Port), TCP: tcpPort}
|
||||
}
|
||||
|
||||
func (e1 rpcEndpoint) equal(e2 rpcEndpoint) bool {
|
||||
return e1.UDP == e2.UDP && e1.TCP == e2.TCP && e1.IP.Equal(e2.IP)
|
||||
}
|
||||
|
||||
func nodeFromRPC(sender *net.UDPAddr, rn rpcNode) (*Node, error) {
|
||||
if err := netutil.CheckRelayIP(sender.IP, rn.IP); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -225,7 +217,6 @@ type udp struct {
|
|||
conn conn
|
||||
priv *ecdsa.PrivateKey
|
||||
ourEndpoint rpcEndpoint
|
||||
nat nat.Interface
|
||||
net *Network
|
||||
}
|
||||
|
||||
|
|
@ -274,13 +265,6 @@ func (t *udp) sendPing(remote *Node, toaddr *net.UDPAddr, topics []Topic) (hash
|
|||
return hash
|
||||
}
|
||||
|
||||
func (t *udp) sendFindnode(remote *Node, target NodeID) {
|
||||
t.sendPacket(remote.ID, remote.addr(), byte(findnodePacket), findnode{
|
||||
Target: target,
|
||||
Expiration: uint64(time.Now().Add(expiration).Unix()),
|
||||
})
|
||||
}
|
||||
|
||||
func (t *udp) sendNeighbours(remote *Node, results []*Node) {
|
||||
// Send neighbors in chunks with at most maxNeighbors per packet
|
||||
// to stay below the 1280 byte limit.
|
||||
|
|
|
|||
|
|
@ -1,450 +0,0 @@
|
|||
// 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 discv5
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
"reflect"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
func init() {
|
||||
spew.Config.DisableMethods = true
|
||||
}
|
||||
|
||||
// shared test variables
|
||||
var (
|
||||
testLocal = rpcEndpoint{IP: net.ParseIP("3.3.3.3").To4(), UDP: 5, TCP: 6}
|
||||
)
|
||||
|
||||
// type udpTest struct {
|
||||
// t *testing.T
|
||||
// pipe *dgramPipe
|
||||
// table *Table
|
||||
// udp *udp
|
||||
// sent [][]byte
|
||||
// localkey, remotekey *ecdsa.PrivateKey
|
||||
// remoteaddr *net.UDPAddr
|
||||
// }
|
||||
//
|
||||
// func newUDPTest(t *testing.T) *udpTest {
|
||||
// test := &udpTest{
|
||||
// t: t,
|
||||
// pipe: newpipe(),
|
||||
// localkey: newkey(),
|
||||
// remotekey: newkey(),
|
||||
// remoteaddr: &net.UDPAddr{IP: net.IP{1, 2, 3, 4}, Port: 30303},
|
||||
// }
|
||||
// test.table, test.udp, _ = newUDP(test.localkey, test.pipe, nil, "")
|
||||
// return test
|
||||
// }
|
||||
//
|
||||
// // handles a packet as if it had been sent to the transport.
|
||||
// func (test *udpTest) packetIn(wantError error, ptype byte, data packet) error {
|
||||
// enc, err := encodePacket(test.remotekey, ptype, data)
|
||||
// if err != nil {
|
||||
// return test.errorf("packet (%d) encode error: %v", ptype, err)
|
||||
// }
|
||||
// test.sent = append(test.sent, enc)
|
||||
// if err = test.udp.handlePacket(test.remoteaddr, enc); err != wantError {
|
||||
// return test.errorf("error mismatch: got %q, want %q", err, wantError)
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
//
|
||||
// // waits for a packet to be sent by the transport.
|
||||
// // validate should have type func(*udpTest, X) error, where X is a packet type.
|
||||
// func (test *udpTest) waitPacketOut(validate interface{}) error {
|
||||
// dgram := test.pipe.waitPacketOut()
|
||||
// p, _, _, err := decodePacket(dgram)
|
||||
// if err != nil {
|
||||
// return test.errorf("sent packet decode error: %v", err)
|
||||
// }
|
||||
// fn := reflect.ValueOf(validate)
|
||||
// exptype := fn.Type().In(0)
|
||||
// if reflect.TypeOf(p) != exptype {
|
||||
// return test.errorf("sent packet type mismatch, got: %v, want: %v", reflect.TypeOf(p), exptype)
|
||||
// }
|
||||
// fn.Call([]reflect.Value{reflect.ValueOf(p)})
|
||||
// return nil
|
||||
// }
|
||||
//
|
||||
// func (test *udpTest) errorf(format string, args ...interface{}) error {
|
||||
// _, file, line, ok := runtime.Caller(2) // errorf + waitPacketOut
|
||||
// if ok {
|
||||
// file = filepath.Base(file)
|
||||
// } else {
|
||||
// file = "???"
|
||||
// line = 1
|
||||
// }
|
||||
// err := fmt.Errorf(format, args...)
|
||||
// fmt.Printf("\t%s:%d: %v\n", file, line, err)
|
||||
// test.t.Fail()
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// func TestUDP_packetErrors(t *testing.T) {
|
||||
// test := newUDPTest(t)
|
||||
// defer test.table.Close()
|
||||
//
|
||||
// test.packetIn(errExpired, pingPacket, &ping{From: testRemote, To: testLocalAnnounced, Version: Version})
|
||||
// test.packetIn(errUnsolicitedReply, pongPacket, &pong{ReplyTok: []byte{}, Expiration: futureExp})
|
||||
// test.packetIn(errUnknownNode, findnodePacket, &findnode{Expiration: futureExp})
|
||||
// test.packetIn(errUnsolicitedReply, neighborsPacket, &neighbors{Expiration: futureExp})
|
||||
// }
|
||||
//
|
||||
// func TestUDP_findnode(t *testing.T) {
|
||||
// test := newUDPTest(t)
|
||||
// defer test.table.Close()
|
||||
//
|
||||
// // put a few nodes into the table. their exact
|
||||
// // distribution shouldn't matter much, although we need to
|
||||
// // take care not to overflow any bucket.
|
||||
// targetHash := crypto.Keccak256Hash(testTarget[:])
|
||||
// nodes := &nodesByDistance{target: targetHash}
|
||||
// for i := 0; i < bucketSize; i++ {
|
||||
// nodes.push(nodeAtDistance(test.table.self.sha, i+2), bucketSize)
|
||||
// }
|
||||
// test.table.stuff(nodes.entries)
|
||||
//
|
||||
// // ensure there's a bond with the test node,
|
||||
// // findnode won't be accepted otherwise.
|
||||
// test.table.db.updateNode(NewNode(
|
||||
// PubkeyID(&test.remotekey.PublicKey),
|
||||
// test.remoteaddr.IP,
|
||||
// uint16(test.remoteaddr.Port),
|
||||
// 99,
|
||||
// ))
|
||||
// // check that closest neighbors are returned.
|
||||
// test.packetIn(nil, findnodePacket, &findnode{Target: testTarget, Expiration: futureExp})
|
||||
// expected := test.table.closest(targetHash, bucketSize)
|
||||
//
|
||||
// waitNeighbors := func(want []*Node) {
|
||||
// test.waitPacketOut(func(p *neighbors) {
|
||||
// if len(p.Nodes) != len(want) {
|
||||
// t.Errorf("wrong number of results: got %d, want %d", len(p.Nodes), bucketSize)
|
||||
// }
|
||||
// for i := range p.Nodes {
|
||||
// if p.Nodes[i].ID != want[i].ID {
|
||||
// t.Errorf("result mismatch at %d:\n got: %v\n want: %v", i, p.Nodes[i], expected.entries[i])
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// waitNeighbors(expected.entries[:maxNeighbors])
|
||||
// waitNeighbors(expected.entries[maxNeighbors:])
|
||||
// }
|
||||
//
|
||||
// func TestUDP_findnodeMultiReply(t *testing.T) {
|
||||
// test := newUDPTest(t)
|
||||
// defer test.table.Close()
|
||||
//
|
||||
// // queue a pending findnode request
|
||||
// resultc, errc := make(chan []*Node), make(chan error)
|
||||
// go func() {
|
||||
// rid := PubkeyID(&test.remotekey.PublicKey)
|
||||
// ns, err := test.udp.findnode(rid, test.remoteaddr, testTarget)
|
||||
// if err != nil && len(ns) == 0 {
|
||||
// errc <- err
|
||||
// } else {
|
||||
// resultc <- ns
|
||||
// }
|
||||
// }()
|
||||
//
|
||||
// // wait for the findnode to be sent.
|
||||
// // after it is sent, the transport is waiting for a reply
|
||||
// test.waitPacketOut(func(p *findnode) {
|
||||
// if p.Target != testTarget {
|
||||
// t.Errorf("wrong target: got %v, want %v", p.Target, testTarget)
|
||||
// }
|
||||
// })
|
||||
//
|
||||
// // send the reply as two packets.
|
||||
// list := []*Node{
|
||||
// MustParseNode("enode://ba85011c70bcc5c04d8607d3a0ed29aa6179c092cbdda10d5d32684fb33ed01bd94f588ca8f91ac48318087dcb02eaf36773a7a453f0eedd6742af668097b29c@10.0.1.16:30303?discport=30304"),
|
||||
// MustParseNode("enode://81fa361d25f157cd421c60dcc28d8dac5ef6a89476633339c5df30287474520caca09627da18543d9079b5b288698b542d56167aa5c09111e55acdbbdf2ef799@10.0.1.16:30303"),
|
||||
// MustParseNode("enode://9bffefd833d53fac8e652415f4973bee289e8b1a5c6c4cbe70abf817ce8a64cee11b823b66a987f51aaa9fba0d6a91b3e6bf0d5a5d1042de8e9eeea057b217f8@10.0.1.36:30301?discport=17"),
|
||||
// MustParseNode("enode://1b5b4aa662d7cb44a7221bfba67302590b643028197a7d5214790f3bac7aaa4a3241be9e83c09cf1f6c69d007c634faae3dc1b1221793e8446c0b3a09de65960@10.0.1.16:30303"),
|
||||
// }
|
||||
// rpclist := make([]rpcNode, len(list))
|
||||
// for i := range list {
|
||||
// rpclist[i] = nodeToRPC(list[i])
|
||||
// }
|
||||
// test.packetIn(nil, neighborsPacket, &neighbors{Expiration: futureExp, Nodes: rpclist[:2]})
|
||||
// test.packetIn(nil, neighborsPacket, &neighbors{Expiration: futureExp, Nodes: rpclist[2:]})
|
||||
//
|
||||
// // check that the sent neighbors are all returned by findnode
|
||||
// select {
|
||||
// case result := <-resultc:
|
||||
// if !reflect.DeepEqual(result, list) {
|
||||
// t.Errorf("neighbors mismatch:\n got: %v\n want: %v", result, list)
|
||||
// }
|
||||
// case err := <-errc:
|
||||
// t.Errorf("findnode error: %v", err)
|
||||
// case <-time.After(5 * time.Second):
|
||||
// t.Error("findnode did not return within 5 seconds")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// func TestUDP_successfulPing(t *testing.T) {
|
||||
// test := newUDPTest(t)
|
||||
// added := make(chan *Node, 1)
|
||||
// test.table.nodeAddedHook = func(n *Node) { added <- n }
|
||||
// defer test.table.Close()
|
||||
//
|
||||
// // The remote side sends a ping packet to initiate the exchange.
|
||||
// go test.packetIn(nil, pingPacket, &ping{From: testRemote, To: testLocalAnnounced, Version: Version, Expiration: futureExp})
|
||||
//
|
||||
// // the ping is replied to.
|
||||
// test.waitPacketOut(func(p *pong) {
|
||||
// pinghash := test.sent[0][:macSize]
|
||||
// if !bytes.Equal(p.ReplyTok, pinghash) {
|
||||
// t.Errorf("got pong.ReplyTok %x, want %x", p.ReplyTok, pinghash)
|
||||
// }
|
||||
// wantTo := rpcEndpoint{
|
||||
// // The mirrored UDP address is the UDP packet sender
|
||||
// IP: test.remoteaddr.IP, UDP: uint16(test.remoteaddr.Port),
|
||||
// // The mirrored TCP port is the one from the ping packet
|
||||
// TCP: testRemote.TCP,
|
||||
// }
|
||||
// if !reflect.DeepEqual(p.To, wantTo) {
|
||||
// t.Errorf("got pong.To %v, want %v", p.To, wantTo)
|
||||
// }
|
||||
// })
|
||||
//
|
||||
// // remote is unknown, the table pings back.
|
||||
// test.waitPacketOut(func(p *ping) error {
|
||||
// if !reflect.DeepEqual(p.From, test.udp.ourEndpoint) {
|
||||
// t.Errorf("got ping.From %v, want %v", p.From, test.udp.ourEndpoint)
|
||||
// }
|
||||
// wantTo := rpcEndpoint{
|
||||
// // The mirrored UDP address is the UDP packet sender.
|
||||
// IP: test.remoteaddr.IP, UDP: uint16(test.remoteaddr.Port),
|
||||
// TCP: 0,
|
||||
// }
|
||||
// if !reflect.DeepEqual(p.To, wantTo) {
|
||||
// t.Errorf("got ping.To %v, want %v", p.To, wantTo)
|
||||
// }
|
||||
// return nil
|
||||
// })
|
||||
// test.packetIn(nil, pongPacket, &pong{Expiration: futureExp})
|
||||
//
|
||||
// // the node should be added to the table shortly after getting the
|
||||
// // pong packet.
|
||||
// select {
|
||||
// case n := <-added:
|
||||
// rid := PubkeyID(&test.remotekey.PublicKey)
|
||||
// if n.ID != rid {
|
||||
// t.Errorf("node has wrong ID: got %v, want %v", n.ID, rid)
|
||||
// }
|
||||
// if !bytes.Equal(n.IP, test.remoteaddr.IP) {
|
||||
// t.Errorf("node has wrong IP: got %v, want: %v", n.IP, test.remoteaddr.IP)
|
||||
// }
|
||||
// if int(n.UDP) != test.remoteaddr.Port {
|
||||
// t.Errorf("node has wrong UDP port: got %v, want: %v", n.UDP, test.remoteaddr.Port)
|
||||
// }
|
||||
// if n.TCP != testRemote.TCP {
|
||||
// t.Errorf("node has wrong TCP port: got %v, want: %v", n.TCP, testRemote.TCP)
|
||||
// }
|
||||
// case <-time.After(2 * time.Second):
|
||||
// t.Errorf("node was not added within 2 seconds")
|
||||
// }
|
||||
// }
|
||||
|
||||
var testPackets = []struct {
|
||||
input string
|
||||
wantPacket interface{}
|
||||
}{
|
||||
{
|
||||
input: "71dbda3a79554728d4f94411e42ee1f8b0d561c10e1e5f5893367948c6a7d70bb87b235fa28a77070271b6c164a2dce8c7e13a5739b53b5e96f2e5acb0e458a02902f5965d55ecbeb2ebb6cabb8b2b232896a36b737666c55265ad0a68412f250001ea04cb847f000001820cfa8215a8d790000000000000000000000000000000018208ae820d058443b9a355",
|
||||
wantPacket: &ping{
|
||||
Version: 4,
|
||||
From: rpcEndpoint{net.ParseIP("127.0.0.1").To4(), 3322, 5544},
|
||||
To: rpcEndpoint{net.ParseIP("::1"), 2222, 3333},
|
||||
Expiration: 1136239445,
|
||||
Rest: []rlp.RawValue{},
|
||||
},
|
||||
},
|
||||
{
|
||||
input: "e9614ccfd9fc3e74360018522d30e1419a143407ffcce748de3e22116b7e8dc92ff74788c0b6663aaa3d67d641936511c8f8d6ad8698b820a7cf9e1be7155e9a241f556658c55428ec0563514365799a4be2be5a685a80971ddcfa80cb422cdd0101ec04cb847f000001820cfa8215a8d790000000000000000000000000000000018208ae820d058443b9a3550102",
|
||||
wantPacket: &ping{
|
||||
Version: 4,
|
||||
From: rpcEndpoint{net.ParseIP("127.0.0.1").To4(), 3322, 5544},
|
||||
To: rpcEndpoint{net.ParseIP("::1"), 2222, 3333},
|
||||
Expiration: 1136239445,
|
||||
Rest: []rlp.RawValue{{0x01}, {0x02}},
|
||||
},
|
||||
},
|
||||
{
|
||||
input: "577be4349c4dd26768081f58de4c6f375a7a22f3f7adda654d1428637412c3d7fe917cadc56d4e5e7ffae1dbe3efffb9849feb71b262de37977e7c7a44e677295680e9e38ab26bee2fcbae207fba3ff3d74069a50b902a82c9903ed37cc993c50001f83e82022bd79020010db83c4d001500000000abcdef12820cfa8215a8d79020010db885a308d313198a2e037073488208ae82823a8443b9a355c5010203040531b9019afde696e582a78fa8d95ea13ce3297d4afb8ba6433e4154caa5ac6431af1b80ba76023fa4090c408f6b4bc3701562c031041d4702971d102c9ab7fa5eed4cd6bab8f7af956f7d565ee1917084a95398b6a21eac920fe3dd1345ec0a7ef39367ee69ddf092cbfe5b93e5e568ebc491983c09c76d922dc3",
|
||||
wantPacket: &ping{
|
||||
Version: 555,
|
||||
From: rpcEndpoint{net.ParseIP("2001:db8:3c4d:15::abcd:ef12"), 3322, 5544},
|
||||
To: rpcEndpoint{net.ParseIP("2001:db8:85a3:8d3:1319:8a2e:370:7348"), 2222, 33338},
|
||||
Expiration: 1136239445,
|
||||
Rest: []rlp.RawValue{{0xC5, 0x01, 0x02, 0x03, 0x04, 0x05}},
|
||||
},
|
||||
},
|
||||
{
|
||||
input: "09b2428d83348d27cdf7064ad9024f526cebc19e4958f0fdad87c15eb598dd61d08423e0bf66b2069869e1724125f820d851c136684082774f870e614d95a2855d000f05d1648b2d5945470bc187c2d2216fbe870f43ed0909009882e176a46b0102f846d79020010db885a308d313198a2e037073488208ae82823aa0fbc914b16819237dcd8801d7e53f69e9719adecb3cc0e790c57e91ca4461c9548443b9a355c6010203c2040506a0c969a58f6f9095004c0177a6b47f451530cab38966a25cca5cb58f055542124e",
|
||||
wantPacket: &pong{
|
||||
To: rpcEndpoint{net.ParseIP("2001:db8:85a3:8d3:1319:8a2e:370:7348"), 2222, 33338},
|
||||
ReplyTok: common.Hex2Bytes("fbc914b16819237dcd8801d7e53f69e9719adecb3cc0e790c57e91ca4461c954"),
|
||||
Expiration: 1136239445,
|
||||
Rest: []rlp.RawValue{{0xC6, 0x01, 0x02, 0x03, 0xC2, 0x04, 0x05}, {0x06}},
|
||||
},
|
||||
},
|
||||
{
|
||||
input: "c7c44041b9f7c7e41934417ebac9a8e1a4c6298f74553f2fcfdcae6ed6fe53163eb3d2b52e39fe91831b8a927bf4fc222c3902202027e5e9eb812195f95d20061ef5cd31d502e47ecb61183f74a504fe04c51e73df81f25c4d506b26db4517490103f84eb840ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd31387574077f301b421bc84df7266c44e9e6d569fc56be00812904767bf5ccd1fc7f8443b9a35582999983999999280dc62cc8255c73471e0a61da0c89acdc0e035e260add7fc0c04ad9ebf3919644c91cb247affc82b69bd2ca235c71eab8e49737c937a2c396",
|
||||
wantPacket: &findnode{
|
||||
Target: MustHexID("ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd31387574077f301b421bc84df7266c44e9e6d569fc56be00812904767bf5ccd1fc7f"),
|
||||
Expiration: 1136239445,
|
||||
Rest: []rlp.RawValue{{0x82, 0x99, 0x99}, {0x83, 0x99, 0x99, 0x99}},
|
||||
},
|
||||
},
|
||||
{
|
||||
input: "c679fc8fe0b8b12f06577f2e802d34f6fa257e6137a995f6f4cbfc9ee50ed3710faf6e66f932c4c8d81d64343f429651328758b47d3dbc02c4042f0fff6946a50f4a49037a72bb550f3a7872363a83e1b9ee6469856c24eb4ef80b7535bcf99c0004f9015bf90150f84d846321163782115c82115db8403155e1427f85f10a5c9a7755877748041af1bcd8d474ec065eb33df57a97babf54bfd2103575fa829115d224c523596b401065a97f74010610fce76382c0bf32f84984010203040101b840312c55512422cf9b8a4097e9a6ad79402e87a15ae909a4bfefa22398f03d20951933beea1e4dfa6f968212385e829f04c2d314fc2d4e255e0d3bc08792b069dbf8599020010db83c4d001500000000abcdef12820d05820d05b84038643200b172dcfef857492156971f0e6aa2c538d8b74010f8e140811d53b98c765dd2d96126051913f44582e8c199ad7c6d6819e9a56483f637feaac9448aacf8599020010db885a308d313198a2e037073488203e78203e8b8408dcab8618c3253b558d459da53bd8fa68935a719aff8b811197101a4b2b47dd2d47295286fc00cc081bb542d760717d1bdd6bec2c37cd72eca367d6dd3b9df738443b9a355010203b525a138aa34383fec3d2719a0",
|
||||
wantPacket: &neighbors{
|
||||
Nodes: []rpcNode{
|
||||
{
|
||||
ID: MustHexID("3155e1427f85f10a5c9a7755877748041af1bcd8d474ec065eb33df57a97babf54bfd2103575fa829115d224c523596b401065a97f74010610fce76382c0bf32"),
|
||||
IP: net.ParseIP("99.33.22.55").To4(),
|
||||
UDP: 4444,
|
||||
TCP: 4445,
|
||||
},
|
||||
{
|
||||
ID: MustHexID("312c55512422cf9b8a4097e9a6ad79402e87a15ae909a4bfefa22398f03d20951933beea1e4dfa6f968212385e829f04c2d314fc2d4e255e0d3bc08792b069db"),
|
||||
IP: net.ParseIP("1.2.3.4").To4(),
|
||||
UDP: 1,
|
||||
TCP: 1,
|
||||
},
|
||||
{
|
||||
ID: MustHexID("38643200b172dcfef857492156971f0e6aa2c538d8b74010f8e140811d53b98c765dd2d96126051913f44582e8c199ad7c6d6819e9a56483f637feaac9448aac"),
|
||||
IP: net.ParseIP("2001:db8:3c4d:15::abcd:ef12"),
|
||||
UDP: 3333,
|
||||
TCP: 3333,
|
||||
},
|
||||
{
|
||||
ID: MustHexID("8dcab8618c3253b558d459da53bd8fa68935a719aff8b811197101a4b2b47dd2d47295286fc00cc081bb542d760717d1bdd6bec2c37cd72eca367d6dd3b9df73"),
|
||||
IP: net.ParseIP("2001:db8:85a3:8d3:1319:8a2e:370:7348"),
|
||||
UDP: 999,
|
||||
TCP: 1000,
|
||||
},
|
||||
},
|
||||
Expiration: 1136239445,
|
||||
Rest: []rlp.RawValue{{0x01}, {0x02}, {0x03}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestForwardCompatibility(t *testing.T) {
|
||||
t.Skip("skipped while working on discovery v5")
|
||||
|
||||
testkey, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||
wantNodeID := PubkeyID(&testkey.PublicKey)
|
||||
|
||||
for _, test := range testPackets {
|
||||
input, err := hex.DecodeString(test.input)
|
||||
if err != nil {
|
||||
t.Fatalf("invalid hex: %s", test.input)
|
||||
}
|
||||
var pkt ingressPacket
|
||||
if err := decodePacket(input, &pkt); err != nil {
|
||||
t.Errorf("did not accept packet %s\n%v", test.input, err)
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(pkt.data, test.wantPacket) {
|
||||
t.Errorf("got %s\nwant %s", spew.Sdump(pkt.data), spew.Sdump(test.wantPacket))
|
||||
}
|
||||
if pkt.remoteID != wantNodeID {
|
||||
t.Errorf("got id %v\nwant id %v", pkt.remoteID, wantNodeID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// dgramPipe is a fake UDP socket. It queues all sent datagrams.
|
||||
type dgramPipe struct {
|
||||
mu *sync.Mutex
|
||||
cond *sync.Cond
|
||||
closing chan struct{}
|
||||
closed bool
|
||||
queue [][]byte
|
||||
}
|
||||
|
||||
func newpipe() *dgramPipe {
|
||||
mu := new(sync.Mutex)
|
||||
return &dgramPipe{
|
||||
closing: make(chan struct{}),
|
||||
cond: &sync.Cond{L: mu},
|
||||
mu: mu,
|
||||
}
|
||||
}
|
||||
|
||||
// WriteToUDP queues a datagram.
|
||||
func (c *dgramPipe) WriteToUDP(b []byte, to *net.UDPAddr) (n int, err error) {
|
||||
msg := make([]byte, len(b))
|
||||
copy(msg, b)
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if c.closed {
|
||||
return 0, errors.New("closed")
|
||||
}
|
||||
c.queue = append(c.queue, msg)
|
||||
c.cond.Signal()
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
// ReadFromUDP just hangs until the pipe is closed.
|
||||
func (c *dgramPipe) ReadFromUDP(b []byte) (n int, addr *net.UDPAddr, err error) {
|
||||
<-c.closing
|
||||
return 0, nil, io.EOF
|
||||
}
|
||||
|
||||
func (c *dgramPipe) Close() error {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if !c.closed {
|
||||
close(c.closing)
|
||||
c.closed = true
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *dgramPipe) LocalAddr() net.Addr {
|
||||
return &net.UDPAddr{IP: testLocal.IP, Port: int(testLocal.UDP)}
|
||||
}
|
||||
|
||||
func (c *dgramPipe) waitPacketOut() []byte {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
for len(c.queue) == 0 {
|
||||
c.cond.Wait()
|
||||
}
|
||||
p := c.queue[0]
|
||||
copy(c.queue, c.queue[1:])
|
||||
c.queue = c.queue[:len(c.queue)-1]
|
||||
return p
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@ import (
|
|||
const (
|
||||
VersionMajor = 1 // Major version component of the current release
|
||||
VersionMinor = 9 // Minor version component of the current release
|
||||
VersionPatch = 8 // Patch version component of the current release
|
||||
VersionPatch = 9 // Patch version component of the current release
|
||||
VersionMeta = "unstable" // Version metadata to append to the version string
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -29,12 +29,13 @@ import (
|
|||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
// EOL is returned when the end of the current list
|
||||
// has been reached during streaming.
|
||||
EOL = errors.New("rlp: end of list")
|
||||
//lint:ignore ST1012 EOL is not an error.
|
||||
|
||||
// Actual Errors
|
||||
// EOL is returned when the end of the current list
|
||||
// has been reached during streaming.
|
||||
var EOL = errors.New("rlp: end of list")
|
||||
|
||||
var (
|
||||
ErrExpectedString = errors.New("rlp: expected String or Byte")
|
||||
ErrExpectedList = errors.New("rlp: expected List")
|
||||
ErrCanonInt = errors.New("rlp: non-canonical integer format")
|
||||
|
|
|
|||
|
|
@ -354,7 +354,7 @@ type tailUint struct {
|
|||
type tailPrivateFields struct {
|
||||
A uint
|
||||
Tail []uint `rlp:"tail"`
|
||||
x, y bool
|
||||
x, y bool //lint:ignore U1000 unused fields required for testing purposes.
|
||||
}
|
||||
|
||||
type nilListUint struct {
|
||||
|
|
@ -807,7 +807,6 @@ func ExampleDecode() {
|
|||
|
||||
type example struct {
|
||||
A, B uint
|
||||
private uint // private fields are ignored
|
||||
String string
|
||||
}
|
||||
|
||||
|
|
@ -819,7 +818,7 @@ func ExampleDecode() {
|
|||
fmt.Printf("Decoded value: %#v\n", s)
|
||||
}
|
||||
// Output:
|
||||
// Decoded value: rlp.example{A:0xa, B:0x14, private:0x0, String:"foobar"}
|
||||
// Decoded value: rlp.example{A:0xa, B:0x14, String:"foobar"}
|
||||
}
|
||||
|
||||
func ExampleDecode_structTagNil() {
|
||||
|
|
|
|||
|
|
@ -40,11 +40,11 @@ func TestClientRequest(t *testing.T) {
|
|||
client := DialInProc(server)
|
||||
defer client.Close()
|
||||
|
||||
var resp Result
|
||||
if err := client.Call(&resp, "test_echo", "hello", 10, &Args{"world"}); err != nil {
|
||||
var resp echoResult
|
||||
if err := client.Call(&resp, "test_echo", "hello", 10, &echoArgs{"world"}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(resp, Result{"hello", 10, &Args{"world"}}) {
|
||||
if !reflect.DeepEqual(resp, echoResult{"hello", 10, &echoArgs{"world"}}) {
|
||||
t.Errorf("incorrect result %#v", resp)
|
||||
}
|
||||
}
|
||||
|
|
@ -58,13 +58,13 @@ func TestClientBatchRequest(t *testing.T) {
|
|||
batch := []BatchElem{
|
||||
{
|
||||
Method: "test_echo",
|
||||
Args: []interface{}{"hello", 10, &Args{"world"}},
|
||||
Result: new(Result),
|
||||
Args: []interface{}{"hello", 10, &echoArgs{"world"}},
|
||||
Result: new(echoResult),
|
||||
},
|
||||
{
|
||||
Method: "test_echo",
|
||||
Args: []interface{}{"hello2", 11, &Args{"world"}},
|
||||
Result: new(Result),
|
||||
Args: []interface{}{"hello2", 11, &echoArgs{"world"}},
|
||||
Result: new(echoResult),
|
||||
},
|
||||
{
|
||||
Method: "no_such_method",
|
||||
|
|
@ -78,13 +78,13 @@ func TestClientBatchRequest(t *testing.T) {
|
|||
wantResult := []BatchElem{
|
||||
{
|
||||
Method: "test_echo",
|
||||
Args: []interface{}{"hello", 10, &Args{"world"}},
|
||||
Result: &Result{"hello", 10, &Args{"world"}},
|
||||
Args: []interface{}{"hello", 10, &echoArgs{"world"}},
|
||||
Result: &echoResult{"hello", 10, &echoArgs{"world"}},
|
||||
},
|
||||
{
|
||||
Method: "test_echo",
|
||||
Args: []interface{}{"hello2", 11, &Args{"world"}},
|
||||
Result: &Result{"hello2", 11, &Args{"world"}},
|
||||
Args: []interface{}{"hello2", 11, &echoArgs{"world"}},
|
||||
Result: &echoResult{"hello2", 11, &echoArgs{"world"}},
|
||||
},
|
||||
{
|
||||
Method: "no_such_method",
|
||||
|
|
@ -104,7 +104,7 @@ func TestClientNotify(t *testing.T) {
|
|||
client := DialInProc(server)
|
||||
defer client.Close()
|
||||
|
||||
if err := client.Notify(context.Background(), "test_echo", "hello", 10, &Args{"world"}); err != nil {
|
||||
if err := client.Notify(context.Background(), "test_echo", "hello", 10, &echoArgs{"world"}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
@ -393,9 +393,9 @@ func TestClientHTTP(t *testing.T) {
|
|||
|
||||
// Launch concurrent requests.
|
||||
var (
|
||||
results = make([]Result, 100)
|
||||
results = make([]echoResult, 100)
|
||||
errc = make(chan error)
|
||||
wantResult = Result{"a", 1, new(Args)}
|
||||
wantResult = echoResult{"a", 1, new(echoArgs)}
|
||||
)
|
||||
defer client.Close()
|
||||
for i := range results {
|
||||
|
|
@ -450,7 +450,7 @@ func TestClientReconnect(t *testing.T) {
|
|||
}
|
||||
|
||||
// Perform a call. This should work because the server is up.
|
||||
var resp Result
|
||||
var resp echoResult
|
||||
if err := client.CallContext(ctx, &resp, "test_echo", "", 1, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -478,7 +478,7 @@ func TestClientReconnect(t *testing.T) {
|
|||
for i := 0; i < cap(errors); i++ {
|
||||
go func() {
|
||||
<-start
|
||||
var resp Result
|
||||
var resp echoResult
|
||||
errors <- client.CallContext(ctx, &resp, "test_echo", "", 3, nil)
|
||||
}()
|
||||
}
|
||||
|
|
|
|||
10
rpc/doc.go
10
rpc/doc.go
|
|
@ -29,8 +29,6 @@ Methods that satisfy the following criteria are made available for remote access
|
|||
|
||||
- method must be exported
|
||||
- method returns 0, 1 (response or error) or 2 (response and error) values
|
||||
- method argument(s) must be exported or builtin types
|
||||
- method returned value(s) must be exported or builtin types
|
||||
|
||||
An example method:
|
||||
|
||||
|
|
@ -74,13 +72,8 @@ An example server which uses the JSON codec:
|
|||
calculator := new(CalculatorService)
|
||||
server := NewServer()
|
||||
server.RegisterName("calculator", calculator)
|
||||
|
||||
l, _ := net.ListenUnix("unix", &net.UnixAddr{Net: "unix", Name: "/tmp/calculator.sock"})
|
||||
for {
|
||||
c, _ := l.AcceptUnix()
|
||||
codec := v2.NewJSONCodec(c)
|
||||
go server.ServeCodec(codec, 0)
|
||||
}
|
||||
server.ServeListener(l)
|
||||
|
||||
Subscriptions
|
||||
|
||||
|
|
@ -90,7 +83,6 @@ criteria:
|
|||
|
||||
- method must be exported
|
||||
- first method argument type must be context.Context
|
||||
- method argument(s) must be exported or builtin types
|
||||
- method must have return types (rpc.Subscription, error)
|
||||
|
||||
An example method:
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ func (h *handler) cancelAllRequests(err error, inflightReq *requestOp) {
|
|||
}
|
||||
for id, sub := range h.clientSubs {
|
||||
delete(h.clientSubs, id)
|
||||
sub.quitWithError(err, false)
|
||||
sub.quitWithError(false, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -153,14 +153,6 @@ type ConnRemoteAddr interface {
|
|||
RemoteAddr() string
|
||||
}
|
||||
|
||||
// connWithRemoteAddr overrides the remote address of a connection.
|
||||
type connWithRemoteAddr struct {
|
||||
Conn
|
||||
addr string
|
||||
}
|
||||
|
||||
func (c connWithRemoteAddr) RemoteAddr() string { return c.addr }
|
||||
|
||||
// jsonCodec reads and writes JSON-RPC messages to the underlying connection. It also has
|
||||
// support for parsing arguments and serializing (result) objects.
|
||||
type jsonCodec struct {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ import (
|
|||
"strings"
|
||||
"sync"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
)
|
||||
|
|
@ -139,16 +138,14 @@ func newCallback(receiver, fn reflect.Value) *callback {
|
|||
c := &callback{fn: fn, rcvr: receiver, errPos: -1, isSubscribe: isPubSub(fntype)}
|
||||
// Determine parameter types. They must all be exported or builtin types.
|
||||
c.makeArgTypes()
|
||||
if !allExportedOrBuiltin(c.argTypes) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Verify return types. The function must return at most one error
|
||||
// and/or one other non-error value.
|
||||
outs := make([]reflect.Type, fntype.NumOut())
|
||||
for i := 0; i < fntype.NumOut(); i++ {
|
||||
outs[i] = fntype.Out(i)
|
||||
}
|
||||
if len(outs) > 2 || !allExportedOrBuiltin(outs) {
|
||||
if len(outs) > 2 {
|
||||
return nil
|
||||
}
|
||||
// If an error is returned, it must be the last returned value.
|
||||
|
|
@ -218,27 +215,6 @@ func (c *callback) call(ctx context.Context, method string, args []reflect.Value
|
|||
return results[0].Interface(), nil
|
||||
}
|
||||
|
||||
// Is this an exported - upper case - name?
|
||||
func isExported(name string) bool {
|
||||
rune, _ := utf8.DecodeRuneInString(name)
|
||||
return unicode.IsUpper(rune)
|
||||
}
|
||||
|
||||
// Are all those types exported or built-in?
|
||||
func allExportedOrBuiltin(types []reflect.Type) bool {
|
||||
for _, typ := range types {
|
||||
for typ.Kind() == reflect.Ptr {
|
||||
typ = typ.Elem()
|
||||
}
|
||||
// PkgPath will be non-empty even for an exported type,
|
||||
// so we need to check the type name as well.
|
||||
if !isExported(typ.Name()) && typ.PkgPath() != "" {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Is t context.Context or *context.Context?
|
||||
func isContextType(t reflect.Type) bool {
|
||||
for t.Kind() == reflect.Ptr {
|
||||
|
|
|
|||
|
|
@ -241,11 +241,11 @@ func (sub *ClientSubscription) Err() <-chan error {
|
|||
// Unsubscribe unsubscribes the notification and closes the error channel.
|
||||
// It can safely be called more than once.
|
||||
func (sub *ClientSubscription) Unsubscribe() {
|
||||
sub.quitWithError(nil, true)
|
||||
sub.quitWithError(true, nil)
|
||||
sub.errOnce.Do(func() { close(sub.err) })
|
||||
}
|
||||
|
||||
func (sub *ClientSubscription) quitWithError(err error, unsubscribeServer bool) {
|
||||
func (sub *ClientSubscription) quitWithError(unsubscribeServer bool, err error) {
|
||||
sub.quitOnce.Do(func() {
|
||||
// The dispatch loop won't be able to execute the unsubscribe call
|
||||
// if it is blocked on deliver. Close sub.quit first because it
|
||||
|
|
@ -276,7 +276,7 @@ func (sub *ClientSubscription) start() {
|
|||
sub.quitWithError(sub.forward())
|
||||
}
|
||||
|
||||
func (sub *ClientSubscription) forward() (err error, unsubscribeServer bool) {
|
||||
func (sub *ClientSubscription) forward() (unsubscribeServer bool, err error) {
|
||||
cases := []reflect.SelectCase{
|
||||
{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(sub.quit)},
|
||||
{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(sub.in)},
|
||||
|
|
@ -298,14 +298,14 @@ func (sub *ClientSubscription) forward() (err error, unsubscribeServer bool) {
|
|||
|
||||
switch chosen {
|
||||
case 0: // <-sub.quit
|
||||
return nil, false
|
||||
return false, nil
|
||||
case 1: // <-sub.in
|
||||
val, err := sub.unmarshal(recv.Interface().(json.RawMessage))
|
||||
if err != nil {
|
||||
return err, true
|
||||
return true, err
|
||||
}
|
||||
if buffer.Len() == maxClientSubscriptionBuffer {
|
||||
return ErrSubscriptionQueueOverflow, true
|
||||
return true, ErrSubscriptionQueueOverflow
|
||||
}
|
||||
buffer.PushBack(val)
|
||||
case 2: // sub.channel<-
|
||||
|
|
|
|||
|
|
@ -53,24 +53,24 @@ func sequentialIDGenerator() func() ID {
|
|||
|
||||
type testService struct{}
|
||||
|
||||
type Args struct {
|
||||
type echoArgs struct {
|
||||
S string
|
||||
}
|
||||
|
||||
type Result struct {
|
||||
type echoResult struct {
|
||||
String string
|
||||
Int int
|
||||
Args *Args
|
||||
Args *echoArgs
|
||||
}
|
||||
|
||||
func (s *testService) NoArgsRets() {}
|
||||
|
||||
func (s *testService) Echo(str string, i int, args *Args) Result {
|
||||
return Result{str, i, args}
|
||||
func (s *testService) Echo(str string, i int, args *echoArgs) echoResult {
|
||||
return echoResult{str, i, args}
|
||||
}
|
||||
|
||||
func (s *testService) EchoWithCtx(ctx context.Context, str string, i int, args *Args) Result {
|
||||
return Result{str, i, args}
|
||||
func (s *testService) EchoWithCtx(ctx context.Context, str string, i int, args *echoArgs) echoResult {
|
||||
return echoResult{str, i, args}
|
||||
}
|
||||
|
||||
func (s *testService) Sleep(ctx context.Context, duration time.Duration) {
|
||||
|
|
@ -81,6 +81,7 @@ func (s *testService) Rets() (string, error) {
|
|||
return "", nil
|
||||
}
|
||||
|
||||
//lint:ignore ST1008 returns error first on purpose.
|
||||
func (s *testService) InvalidRets1() (error, string) {
|
||||
return nil, ""
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,9 +97,8 @@ func (bn *BlockNumber) UnmarshalJSON(data []byte) error {
|
|||
return err
|
||||
}
|
||||
if blckNum > math.MaxInt64 {
|
||||
return fmt.Errorf("Blocknumber too high")
|
||||
return fmt.Errorf("block number larger than int64")
|
||||
}
|
||||
|
||||
*bn = BlockNumber(blckNum)
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ func TestWebsocketLargeCall(t *testing.T) {
|
|||
defer client.Close()
|
||||
|
||||
// This call sends slightly less than the limit and should work.
|
||||
var result Result
|
||||
var result echoResult
|
||||
arg := strings.Repeat("x", maxRequestContentLength-200)
|
||||
if err := client.Call(&result, "test_echo", arg, 1); err != nil {
|
||||
t.Fatalf("valid call didn't work: %v", err)
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ type (
|
|||
}
|
||||
)
|
||||
|
||||
var ErrRequestDenied = errors.New("Request denied")
|
||||
var ErrRequestDenied = errors.New("request denied")
|
||||
|
||||
// NewSignerAPI creates a new API that can be used for Account management.
|
||||
// ksLocation specifies the directory where to store the password protected private
|
||||
|
|
@ -552,6 +552,9 @@ func (api *SignerAPI) SignTransaction(ctx context.Context, args SendTxArgs, meth
|
|||
}
|
||||
|
||||
rlpdata, err := rlp.EncodeToBytes(signedTx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response := ethapi.SignTransactionResult{Raw: rlpdata, Tx: signedTx}
|
||||
|
||||
// Finally, send the signed tx to the UI
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ func (ui *headlessUi) ApproveTx(request *core.SignTxRequest) (core.SignTxRespons
|
|||
}
|
||||
|
||||
func (ui *headlessUi) ApproveSignData(request *core.SignDataRequest) (core.SignDataResponse, error) {
|
||||
approved := "Y" == <-ui.approveCh
|
||||
approved := (<-ui.approveCh == "Y")
|
||||
return core.SignDataResponse{approved}, nil
|
||||
}
|
||||
|
||||
|
|
@ -91,7 +91,7 @@ func (ui *headlessUi) ApproveListing(request *core.ListRequest) (core.ListRespon
|
|||
}
|
||||
|
||||
func (ui *headlessUi) ApproveNewAccount(request *core.NewAccountRequest) (core.NewAccountResponse, error) {
|
||||
if "Y" == <-ui.approveCh {
|
||||
if <-ui.approveCh == "Y" {
|
||||
return core.NewAccountResponse{true}, nil
|
||||
}
|
||||
return core.NewAccountResponse{false}, nil
|
||||
|
|
|
|||
|
|
@ -58,34 +58,6 @@ func (ui *CommandlineUI) readString() string {
|
|||
}
|
||||
}
|
||||
|
||||
// readPassword reads a single line from stdin, trimming it from the trailing new
|
||||
// line and returns it. The input will not be echoed.
|
||||
func (ui *CommandlineUI) readPassword() string {
|
||||
fmt.Printf("Enter password to approve:\n")
|
||||
fmt.Printf("> ")
|
||||
|
||||
text, err := terminal.ReadPassword(int(os.Stdin.Fd()))
|
||||
if err != nil {
|
||||
log.Crit("Failed to read password", "err", err)
|
||||
}
|
||||
fmt.Println()
|
||||
fmt.Println("-----------------------")
|
||||
return string(text)
|
||||
}
|
||||
|
||||
// readPassword reads a single line from stdin, trimming it from the trailing new
|
||||
// line and returns it. The input will not be echoed.
|
||||
func (ui *CommandlineUI) readPasswordText(inputstring string) string {
|
||||
fmt.Printf("Enter %s:\n", inputstring)
|
||||
fmt.Printf("> ")
|
||||
text, err := terminal.ReadPassword(int(os.Stdin.Fd()))
|
||||
if err != nil {
|
||||
log.Crit("Failed to read password", "err", err)
|
||||
}
|
||||
fmt.Println("-----------------------")
|
||||
return string(text)
|
||||
}
|
||||
|
||||
func (ui *CommandlineUI) OnInputRequired(info UserInputRequest) (UserInputResponse, error) {
|
||||
|
||||
fmt.Printf("## %s\n\n%s\n", info.Title, info.Prompt)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ package core
|
|||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
|
|
@ -27,7 +26,6 @@ import (
|
|||
|
||||
type StdIOUI struct {
|
||||
client rpc.Client
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func NewStdIOUI() *StdIOUI {
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ func (v *ValidationMessages) getWarnings() error {
|
|||
}
|
||||
}
|
||||
if len(messages) > 0 {
|
||||
return fmt.Errorf("Validation failed: %s", strings.Join(messages, ","))
|
||||
return fmt.Errorf("validation failed: %s", strings.Join(messages, ","))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ func (s *UIServerAPI) Export(ctx context.Context, addr common.Address) (json.Raw
|
|||
return nil, err
|
||||
}
|
||||
if wallet.URL().Scheme != keystore.KeyStoreScheme {
|
||||
return nil, fmt.Errorf("Account is not a keystore-account")
|
||||
return nil, fmt.Errorf("account is not a keystore-account")
|
||||
}
|
||||
return ioutil.ReadFile(wallet.URL().Path)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
// Code generated by go-bindata.
|
||||
// Package deps Code generated by go-bindata. (@generated) DO NOT EDIT.
|
||||
// sources:
|
||||
// bignumber.js
|
||||
// DO NOT EDIT!
|
||||
|
||||
package deps
|
||||
|
||||
import (
|
||||
|
|
@ -20,7 +18,7 @@ import (
|
|||
func bindataRead(data []byte, name string) ([]byte, error) {
|
||||
gz, err := gzip.NewReader(bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Read %q: %v", name, err)
|
||||
return nil, fmt.Errorf("read %q: %v", name, err)
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
|
@ -28,7 +26,7 @@ func bindataRead(data []byte, name string) ([]byte, error) {
|
|||
clErr := gz.Close()
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Read %q: %v", name, err)
|
||||
return nil, fmt.Errorf("read %q: %v", name, err)
|
||||
}
|
||||
if clErr != nil {
|
||||
return nil, err
|
||||
|
|
@ -49,21 +47,32 @@ type bindataFileInfo struct {
|
|||
modTime time.Time
|
||||
}
|
||||
|
||||
// Name return file name
|
||||
func (fi bindataFileInfo) Name() string {
|
||||
return fi.name
|
||||
}
|
||||
|
||||
// Size return file size
|
||||
func (fi bindataFileInfo) Size() int64 {
|
||||
return fi.size
|
||||
}
|
||||
|
||||
// Mode return file mode
|
||||
func (fi bindataFileInfo) Mode() os.FileMode {
|
||||
return fi.mode
|
||||
}
|
||||
|
||||
// ModTime return file modify time
|
||||
func (fi bindataFileInfo) ModTime() time.Time {
|
||||
return fi.modTime
|
||||
}
|
||||
|
||||
// IsDir return file whether a directory
|
||||
func (fi bindataFileInfo) IsDir() bool {
|
||||
return false
|
||||
return fi.mode&os.ModeDir != 0
|
||||
}
|
||||
|
||||
// Sys return file is sys mode
|
||||
func (fi bindataFileInfo) Sys() interface{} {
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ func (r *rulesetUI) checkApproval(jsfunc string, jsarg []byte, err error) (bool,
|
|||
log.Info("Op rejected")
|
||||
return false, nil
|
||||
}
|
||||
return false, fmt.Errorf("Unknown response")
|
||||
return false, fmt.Errorf("unknown response")
|
||||
}
|
||||
|
||||
func (r *rulesetUI) ApproveTx(request *core.SignTxRequest) (core.SignTxResponse, error) {
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ type Storage interface {
|
|||
// not persist values to disk. Mainly used for testing
|
||||
type EphemeralStorage struct {
|
||||
data map[string]string
|
||||
namespace string
|
||||
}
|
||||
|
||||
// Put stores a value by key. 0-length keys results in noop.
|
||||
|
|
@ -83,5 +82,5 @@ type NoStorage struct{}
|
|||
func (s *NoStorage) Put(key, value string) {}
|
||||
func (s *NoStorage) Del(key string) {}
|
||||
func (s *NoStorage) Get(key string) (string, error) {
|
||||
return "", errors.New("I forgot")
|
||||
return "", errors.New("missing key, I probably forgot")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ func (t *BlockTest) insertBlocks(blockchain *core.BlockChain) ([]btBlock, error)
|
|||
if b.BlockHeader == nil {
|
||||
continue // OK - block is supposed to be invalid, continue with next block
|
||||
} else {
|
||||
return nil, fmt.Errorf("Block RLP decoding failed when expected to succeed: %v", err)
|
||||
return nil, fmt.Errorf("block RLP decoding failed when expected to succeed: %v", err)
|
||||
}
|
||||
}
|
||||
// RLP decoding worked, try to insert into chain:
|
||||
|
|
@ -189,16 +189,16 @@ func (t *BlockTest) insertBlocks(blockchain *core.BlockChain) ([]btBlock, error)
|
|||
if b.BlockHeader == nil {
|
||||
continue // OK - block is supposed to be invalid, continue with next block
|
||||
} else {
|
||||
return nil, fmt.Errorf("Block #%v insertion into chain failed: %v", blocks[i].Number(), err)
|
||||
return nil, fmt.Errorf("block #%v insertion into chain failed: %v", blocks[i].Number(), err)
|
||||
}
|
||||
}
|
||||
if b.BlockHeader == nil {
|
||||
return nil, fmt.Errorf("Block insertion should have failed")
|
||||
return nil, fmt.Errorf("block insertion should have failed")
|
||||
}
|
||||
|
||||
// validate RLP decoding by checking all values against test file JSON
|
||||
if err = validateHeader(b.BlockHeader, cb.Header()); err != nil {
|
||||
return nil, fmt.Errorf("Deserialised block header validation failed: %v", err)
|
||||
return nil, fmt.Errorf("deserialised block header validation failed: %v", err)
|
||||
}
|
||||
validBlocks = append(validBlocks, b)
|
||||
}
|
||||
|
|
@ -207,49 +207,49 @@ func (t *BlockTest) insertBlocks(blockchain *core.BlockChain) ([]btBlock, error)
|
|||
|
||||
func validateHeader(h *btHeader, h2 *types.Header) error {
|
||||
if h.Bloom != h2.Bloom {
|
||||
return fmt.Errorf("Bloom: want: %x have: %x", h.Bloom, h2.Bloom)
|
||||
return fmt.Errorf("bloom: want: %x have: %x", h.Bloom, h2.Bloom)
|
||||
}
|
||||
if h.Coinbase != h2.Coinbase {
|
||||
return fmt.Errorf("Coinbase: want: %x have: %x", h.Coinbase, h2.Coinbase)
|
||||
return fmt.Errorf("coinbase: want: %x have: %x", h.Coinbase, h2.Coinbase)
|
||||
}
|
||||
if h.MixHash != h2.MixDigest {
|
||||
return fmt.Errorf("MixHash: want: %x have: %x", h.MixHash, h2.MixDigest)
|
||||
}
|
||||
if h.Nonce != h2.Nonce {
|
||||
return fmt.Errorf("Nonce: want: %x have: %x", h.Nonce, h2.Nonce)
|
||||
return fmt.Errorf("nonce: want: %x have: %x", h.Nonce, h2.Nonce)
|
||||
}
|
||||
if h.Number.Cmp(h2.Number) != 0 {
|
||||
return fmt.Errorf("Number: want: %v have: %v", h.Number, h2.Number)
|
||||
return fmt.Errorf("number: want: %v have: %v", h.Number, h2.Number)
|
||||
}
|
||||
if h.ParentHash != h2.ParentHash {
|
||||
return fmt.Errorf("Parent hash: want: %x have: %x", h.ParentHash, h2.ParentHash)
|
||||
return fmt.Errorf("parent hash: want: %x have: %x", h.ParentHash, h2.ParentHash)
|
||||
}
|
||||
if h.ReceiptTrie != h2.ReceiptHash {
|
||||
return fmt.Errorf("Receipt hash: want: %x have: %x", h.ReceiptTrie, h2.ReceiptHash)
|
||||
return fmt.Errorf("receipt hash: want: %x have: %x", h.ReceiptTrie, h2.ReceiptHash)
|
||||
}
|
||||
if h.TransactionsTrie != h2.TxHash {
|
||||
return fmt.Errorf("Tx hash: want: %x have: %x", h.TransactionsTrie, h2.TxHash)
|
||||
return fmt.Errorf("tx hash: want: %x have: %x", h.TransactionsTrie, h2.TxHash)
|
||||
}
|
||||
if h.StateRoot != h2.Root {
|
||||
return fmt.Errorf("State hash: want: %x have: %x", h.StateRoot, h2.Root)
|
||||
return fmt.Errorf("state hash: want: %x have: %x", h.StateRoot, h2.Root)
|
||||
}
|
||||
if h.UncleHash != h2.UncleHash {
|
||||
return fmt.Errorf("Uncle hash: want: %x have: %x", h.UncleHash, h2.UncleHash)
|
||||
return fmt.Errorf("uncle hash: want: %x have: %x", h.UncleHash, h2.UncleHash)
|
||||
}
|
||||
if !bytes.Equal(h.ExtraData, h2.Extra) {
|
||||
return fmt.Errorf("Extra data: want: %x have: %x", h.ExtraData, h2.Extra)
|
||||
return fmt.Errorf("extra data: want: %x have: %x", h.ExtraData, h2.Extra)
|
||||
}
|
||||
if h.Difficulty.Cmp(h2.Difficulty) != 0 {
|
||||
return fmt.Errorf("Difficulty: want: %v have: %v", h.Difficulty, h2.Difficulty)
|
||||
return fmt.Errorf("difficulty: want: %v have: %v", h.Difficulty, h2.Difficulty)
|
||||
}
|
||||
if h.GasLimit != h2.GasLimit {
|
||||
return fmt.Errorf("GasLimit: want: %d have: %d", h.GasLimit, h2.GasLimit)
|
||||
return fmt.Errorf("gasLimit: want: %d have: %d", h.GasLimit, h2.GasLimit)
|
||||
}
|
||||
if h.GasUsed != h2.GasUsed {
|
||||
return fmt.Errorf("GasUsed: want: %d have: %d", h.GasUsed, h2.GasUsed)
|
||||
return fmt.Errorf("gasUsed: want: %d have: %d", h.GasUsed, h2.GasUsed)
|
||||
}
|
||||
if h.Timestamp != h2.Time {
|
||||
return fmt.Errorf("Timestamp: want: %v have: %v", h.Timestamp, h2.Time)
|
||||
return fmt.Errorf("timestamp: want: %v have: %v", h.Timestamp, h2.Time)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -287,7 +287,7 @@ func (t *BlockTest) validateImportedHeaders(cm *core.BlockChain, validBlocks []b
|
|||
// be part of the longest chain until last block is imported.
|
||||
for b := cm.CurrentBlock(); b != nil && b.NumberU64() != 0; b = cm.GetBlockByHash(b.Header().ParentHash) {
|
||||
if err := validateHeader(bmap[b.Hash()].BlockHeader, b.Header()); err != nil {
|
||||
return fmt.Errorf("Imported block header validation failed: %v", err)
|
||||
return fmt.Errorf("imported block header validation failed: %v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -289,3 +289,14 @@ func runTestFunc(runTest interface{}, t *testing.T, name string, m reflect.Value
|
|||
m.MapIndex(reflect.ValueOf(key)),
|
||||
})
|
||||
}
|
||||
|
||||
func TestMatcherWhitelist(t *testing.T) {
|
||||
t.Parallel()
|
||||
tm := new(testMatcher)
|
||||
tm.whitelist("invalid*")
|
||||
tm.walk(t, rlpTestDir, func(t *testing.T, name string, test *RLPTest) {
|
||||
if name[:len("invalidRLPTest.json")] != "invalidRLPTest.json" {
|
||||
t.Fatalf("invalid test found: %s != invalidRLPTest.json", name)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue