From 7e57fee3551ad5b66c985ad208613fd80c2d6b8a Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 18 Aug 2017 12:14:00 +0200 Subject: [PATCH 01/19] node: fix instance dir locking and improve error message The lock file was ineffective because opening leveldb storage in read-only mode doesn't really take the lock. Fix it by including a dedicated flock library (which is actually split out of goleveldb). --- node/errors.go | 18 ++ node/node.go | 36 ++-- .../github.com/prometheus/prometheus/LICENSE | 201 ++++++++++++++++++ .../github.com/prometheus/prometheus/NOTICE | 87 ++++++++ .../prometheus/prometheus/util/flock/flock.go | 46 ++++ .../prometheus/util/flock/flock_plan9.go | 32 +++ .../prometheus/util/flock/flock_solaris.go | 59 +++++ .../prometheus/util/flock/flock_unix.go | 54 +++++ .../prometheus/util/flock/flock_windows.go | 36 ++++ vendor/vendor.json | 6 + 10 files changed, 551 insertions(+), 24 deletions(-) create mode 100644 vendor/github.com/prometheus/prometheus/LICENSE create mode 100644 vendor/github.com/prometheus/prometheus/NOTICE create mode 100644 vendor/github.com/prometheus/prometheus/util/flock/flock.go create mode 100644 vendor/github.com/prometheus/prometheus/util/flock/flock_plan9.go create mode 100644 vendor/github.com/prometheus/prometheus/util/flock/flock_solaris.go create mode 100644 vendor/github.com/prometheus/prometheus/util/flock/flock_unix.go create mode 100644 vendor/github.com/prometheus/prometheus/util/flock/flock_windows.go diff --git a/node/errors.go b/node/errors.go index bd5ddeb5de..2e0dadc4d6 100644 --- a/node/errors.go +++ b/node/errors.go @@ -17,10 +17,28 @@ package node import ( + "errors" "fmt" "reflect" + "syscall" ) +var ( + ErrDatadirUsed = errors.New("datadir already used by another process") + ErrNodeStopped = errors.New("node not started") + ErrNodeRunning = errors.New("node already running") + ErrServiceUnknown = errors.New("unknown service") + + datadirInUseErrnos = map[uint]bool{11: true, 32: true, 35: true} +) + +func convertFileLockError(err error) error { + if errno, ok := err.(syscall.Errno); ok && datadirInUseErrnos[uint(errno)] { + return ErrDatadirUsed + } + return err +} + // DuplicateServiceError is returned during Node startup if a registered service // constructor returns a service of the same type that was already started. type DuplicateServiceError struct { diff --git a/node/node.go b/node/node.go index e3f0232b4b..86cfb29baf 100644 --- a/node/node.go +++ b/node/node.go @@ -25,7 +25,6 @@ import ( "reflect" "strings" "sync" - "syscall" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/ethdb" @@ -34,16 +33,7 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/rpc" - "github.com/syndtr/goleveldb/leveldb/storage" -) - -var ( - ErrDatadirUsed = errors.New("datadir already used") - ErrNodeStopped = errors.New("node not started") - ErrNodeRunning = errors.New("node already running") - ErrServiceUnknown = errors.New("unknown service") - - datadirInUseErrnos = map[uint]bool{11: true, 32: true, 35: true} + "github.com/prometheus/prometheus/util/flock" ) // Node is a container on which services can be registered. @@ -52,8 +42,8 @@ type Node struct { config *Config accman *accounts.Manager - ephemeralKeystore string // if non-empty, the key directory that will be removed by Stop - instanceDirLock storage.Storage // prevents concurrent use of instance directory + ephemeralKeystore string // if non-empty, the key directory that will be removed by Stop + instanceDirLock flock.Releaser // prevents concurrent use of instance directory serverConfig p2p.Config server *p2p.Server // Currently running P2P networking layer @@ -197,10 +187,7 @@ func (n *Node) Start() error { running.Protocols = append(running.Protocols, service.Protocols()...) } if err := running.Start(); err != nil { - if errno, ok := err.(syscall.Errno); ok && datadirInUseErrnos[uint(errno)] { - return ErrDatadirUsed - } - return err + return convertFileLockError(err) } // Start each of the services started := []reflect.Type{} @@ -242,14 +229,13 @@ func (n *Node) openDataDir() error { if err := os.MkdirAll(instdir, 0700); err != nil { return err } - // Try to open the instance directory as LevelDB storage. This creates a lock file - // which prevents concurrent use by another instance as well as accidental use of the - // instance directory as a database. - storage, err := storage.OpenFile(instdir, true) + // Lock the instance directory to prevent concurrent use by another instance as well as + // accidental use of the instance directory as a database. + release, _, err := flock.New(filepath.Join(instdir, "LOCK")) if err != nil { - return err + return convertFileLockError(err) } - n.instanceDirLock = storage + n.instanceDirLock = release return nil } @@ -509,7 +495,9 @@ func (n *Node) Stop() error { // Release instance directory lock. if n.instanceDirLock != nil { - n.instanceDirLock.Close() + if err := n.instanceDirLock.Release(); err != nil { + log.Error("Can't release datadir lock", "err", err) + } n.instanceDirLock = nil } diff --git a/vendor/github.com/prometheus/prometheus/LICENSE b/vendor/github.com/prometheus/prometheus/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/vendor/github.com/prometheus/prometheus/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/prometheus/prometheus/NOTICE b/vendor/github.com/prometheus/prometheus/NOTICE new file mode 100644 index 0000000000..47de2415e1 --- /dev/null +++ b/vendor/github.com/prometheus/prometheus/NOTICE @@ -0,0 +1,87 @@ +The Prometheus systems and service monitoring server +Copyright 2012-2015 The Prometheus Authors + +This product includes software developed at +SoundCloud Ltd. (http://soundcloud.com/). + + +The following components are included in this product: + +Bootstrap +http://getbootstrap.com +Copyright 2011-2014 Twitter, Inc. +Licensed under the MIT License + +bootstrap3-typeahead.js +https://github.com/bassjobsen/Bootstrap-3-Typeahead +Original written by @mdo and @fat +Copyright 2014 Bass Jobsen @bassjobsen +Licensed under the Apache License, Version 2.0 + +fuzzy +https://github.com/mattyork/fuzzy +Original written by @mattyork +Copyright 2012 Matt York +Licensed under the MIT License + +bootstrap-datetimepicker.js +https://github.com/Eonasdan/bootstrap-datetimepicker +Copyright 2015 Jonathan Peterson (@Eonasdan) +Licensed under the MIT License + +moment.js +https://github.com/moment/moment/ +Copyright JS Foundation and other contributors +Licensed under the MIT License + +Rickshaw +https://github.com/shutterstock/rickshaw +Copyright 2011-2014 by Shutterstock Images, LLC +See https://github.com/shutterstock/rickshaw/blob/master/LICENSE for license details + +mustache.js +https://github.com/janl/mustache.js +Copyright 2009 Chris Wanstrath (Ruby) +Copyright 2010-2014 Jan Lehnardt (JavaScript) +Copyright 2010-2015 The mustache.js community +Licensed under the MIT License + +jQuery +https://jquery.org +Copyright jQuery Foundation and other contributors +Licensed under the MIT License + +Go support for Protocol Buffers - Google's data interchange format +http://github.com/golang/protobuf/ +Copyright 2010 The Go Authors +See source code for license details. + +Go support for leveled logs, analogous to +https://code.google.com/p/google-glog/ +Copyright 2013 Google Inc. +Licensed under the Apache License, Version 2.0 + +Support for streaming Protocol Buffer messages for the Go language (golang). +https://github.com/matttproud/golang_protobuf_extensions +Copyright 2013 Matt T. Proud +Licensed under the Apache License, Version 2.0 + +DNS library in Go +http://miek.nl/posts/2014/Aug/16/go-dns-package/ +Copyright 2009 The Go Authors, 2011 Miek Gieben +See https://github.com/miekg/dns/blob/master/LICENSE for license details. + +LevelDB key/value database in Go +https://github.com/syndtr/goleveldb +Copyright 2012 Suryandaru Triandana +See https://github.com/syndtr/goleveldb/blob/master/LICENSE for license details. + +gosnappy - a fork of code.google.com/p/snappy-go +https://github.com/syndtr/gosnappy +Copyright 2011 The Snappy-Go Authors +See https://github.com/syndtr/gosnappy/blob/master/LICENSE for license details. + +go-zookeeper - Native ZooKeeper client for Go +https://github.com/samuel/go-zookeeper +Copyright (c) 2013, Samuel Stauffer +See https://github.com/samuel/go-zookeeper/blob/master/LICENSE for license details. diff --git a/vendor/github.com/prometheus/prometheus/util/flock/flock.go b/vendor/github.com/prometheus/prometheus/util/flock/flock.go new file mode 100644 index 0000000000..5dc22a2fae --- /dev/null +++ b/vendor/github.com/prometheus/prometheus/util/flock/flock.go @@ -0,0 +1,46 @@ +// Copyright 2016 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package flock provides portable file locking. It is essentially ripped out +// from the code of github.com/syndtr/goleveldb. Strange enough that the +// standard library does not provide this functionality. Once this package has +// proven to work as expected, we should probably turn it into a separate +// general purpose package for humanity. +package flock + +import ( + "os" + "path/filepath" +) + +// Releaser provides the Release method to release a file lock. +type Releaser interface { + Release() error +} + +// New locks the file with the provided name. If the file does not exist, it is +// created. The returned Releaser is used to release the lock. existed is true +// if the file to lock already existed. A non-nil error is returned if the +// locking has failed. Neither this function nor the returned Releaser is +// goroutine-safe. +func New(fileName string) (r Releaser, existed bool, err error) { + if err = os.MkdirAll(filepath.Dir(fileName), 0755); err != nil { + return + } + + _, err = os.Stat(fileName) + existed = err == nil + + r, err = newLock(fileName) + return +} diff --git a/vendor/github.com/prometheus/prometheus/util/flock/flock_plan9.go b/vendor/github.com/prometheus/prometheus/util/flock/flock_plan9.go new file mode 100644 index 0000000000..004e85c0fe --- /dev/null +++ b/vendor/github.com/prometheus/prometheus/util/flock/flock_plan9.go @@ -0,0 +1,32 @@ +// Copyright 2016 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package flock + +import "os" + +type plan9Lock struct { + f *os.File +} + +func (l *plan9Lock) Release() error { + return l.f.Close() +} + +func newLock(fileName string) (Releaser, error) { + f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, os.ModeExclusive|0644) + if err != nil { + return nil, err + } + return &plan9Lock{f}, nil +} diff --git a/vendor/github.com/prometheus/prometheus/util/flock/flock_solaris.go b/vendor/github.com/prometheus/prometheus/util/flock/flock_solaris.go new file mode 100644 index 0000000000..299fc87446 --- /dev/null +++ b/vendor/github.com/prometheus/prometheus/util/flock/flock_solaris.go @@ -0,0 +1,59 @@ +// Copyright 2016 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build solaris + +package flock + +import ( + "os" + "syscall" +) + +type unixLock struct { + f *os.File +} + +func (l *unixLock) Release() error { + if err := l.set(false); err != nil { + return err + } + return l.f.Close() +} + +func (l *unixLock) set(lock bool) error { + flock := syscall.Flock_t{ + Type: syscall.F_UNLCK, + Start: 0, + Len: 0, + Whence: 1, + } + if lock { + flock.Type = syscall.F_WRLCK + } + return syscall.FcntlFlock(l.f.Fd(), syscall.F_SETLK, &flock) +} + +func newLock(fileName string) (Releaser, error) { + f, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0644) + if err != nil { + return nil, err + } + l := &unixLock{f} + err = l.set(true) + if err != nil { + f.Close() + return nil, err + } + return l, nil +} diff --git a/vendor/github.com/prometheus/prometheus/util/flock/flock_unix.go b/vendor/github.com/prometheus/prometheus/util/flock/flock_unix.go new file mode 100644 index 0000000000..7d71f8fc09 --- /dev/null +++ b/vendor/github.com/prometheus/prometheus/util/flock/flock_unix.go @@ -0,0 +1,54 @@ +// Copyright 2016 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build darwin dragonfly freebsd linux netbsd openbsd + +package flock + +import ( + "os" + "syscall" +) + +type unixLock struct { + f *os.File +} + +func (l *unixLock) Release() error { + if err := l.set(false); err != nil { + return err + } + return l.f.Close() +} + +func (l *unixLock) set(lock bool) error { + how := syscall.LOCK_UN + if lock { + how = syscall.LOCK_EX + } + return syscall.Flock(int(l.f.Fd()), how|syscall.LOCK_NB) +} + +func newLock(fileName string) (Releaser, error) { + f, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0644) + if err != nil { + return nil, err + } + l := &unixLock{f} + err = l.set(true) + if err != nil { + f.Close() + return nil, err + } + return l, nil +} diff --git a/vendor/github.com/prometheus/prometheus/util/flock/flock_windows.go b/vendor/github.com/prometheus/prometheus/util/flock/flock_windows.go new file mode 100644 index 0000000000..bf7266f14c --- /dev/null +++ b/vendor/github.com/prometheus/prometheus/util/flock/flock_windows.go @@ -0,0 +1,36 @@ +// Copyright 2016 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package flock + +import "syscall" + +type windowsLock struct { + fd syscall.Handle +} + +func (fl *windowsLock) Release() error { + return syscall.Close(fl.fd) +} + +func newLock(fileName string) (Releaser, error) { + pathp, err := syscall.UTF16PtrFromString(fileName) + if err != nil { + return nil, err + } + fd, err := syscall.CreateFile(pathp, syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.CREATE_ALWAYS, syscall.FILE_ATTRIBUTE_NORMAL, 0) + if err != nil { + return nil, err + } + return &windowsLock{fd}, nil +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 8be10b94fb..b0bc88adc6 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -255,6 +255,12 @@ "revision": "bf27d3ba8e1d9899d45a457ffac16c953eb2d647", "revisionTime": "2017-02-11T19:53:22Z" }, + { + "checksumSHA1": "WbbxCn2jUYIL5viqLo0BKXEdPrQ=", + "path": "github.com/prometheus/prometheus/util/flock", + "revision": "3101606756c53221ed58ba94ecba6b26adf89dcc", + "revisionTime": "2017-08-14T17:01:13Z" + }, { "checksumSHA1": "KAzbLjI9MzW2tjfcAsK75lVRp6I=", "path": "github.com/rcrowley/go-metrics", From b4b27ebaea3e1145926555b139a2910af855215e Mon Sep 17 00:00:00 2001 From: Bo Ye Date: Tue, 22 Aug 2017 18:35:09 +1200 Subject: [PATCH 02/19] metrics: change MetricsEnabledFlag to be const --- metrics/metrics.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metrics/metrics.go b/metrics/metrics.go index 9906bb8ad2..da2cdbc53c 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -29,7 +29,7 @@ import ( ) // MetricsEnabledFlag is the CLI flag name to use to enable metrics collections. -var MetricsEnabledFlag = "metrics" +const MetricsEnabledFlag = "metrics" // Enabled is the flag specifying if metrics are enable or not. var Enabled = false From 28aea46ac08579f3ecd1c35620915b8e1bfcc8b0 Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Mon, 21 Aug 2017 08:47:15 +0800 Subject: [PATCH 03/19] core: implement Metropolis EIP 658, receipt status byte --- accounts/abi/bind/backends/simulated.go | 3 +- common/bytes.go | 3 ++ core/database_util_test.go | 4 +-- core/state_processor.go | 4 +-- core/state_transition.go | 19 +++++------ core/types/gen_receipt_json.go | 6 ++++ core/types/receipt.go | 44 ++++++++++++++++--------- core/vm/evm.go | 6 +++- core/vm/instructions.go | 2 +- eth/api.go | 5 +-- eth/backend_test.go | 4 +-- eth/filters/filter_test.go | 10 +++--- internal/ethapi/api.go | 3 +- les/odr_test.go | 4 +-- light/odr_test.go | 2 +- tests/state_test_util.go | 2 +- 16 files changed, 75 insertions(+), 46 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index e0ee06a0a1..88fb3331e8 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -253,7 +253,8 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM // about the transaction and calling mechanisms. vmenv := vm.NewEVM(evmContext, statedb, b.config, vm.Config{}) gaspool := new(core.GasPool).AddGas(math.MaxBig256) - ret, gasUsed, _, err := core.NewStateTransition(vmenv, msg, gaspool).TransitionDb() + // TODO utilize returned failed flag to help gas estimation. + ret, gasUsed, _, _, err := core.NewStateTransition(vmenv, msg, gaspool).TransitionDb() return ret, gasUsed, err } diff --git a/common/bytes.go b/common/bytes.go index c445968f22..66577bbfd0 100644 --- a/common/bytes.go +++ b/common/bytes.go @@ -47,6 +47,9 @@ func FromHex(s string) []byte { // // Returns an exact copy of the provided bytes func CopyBytes(b []byte) (copiedBytes []byte) { + if b == nil { + return nil + } copiedBytes = make([]byte, len(b)) copy(copiedBytes, b) diff --git a/core/database_util_test.go b/core/database_util_test.go index e9a6df97b7..5c75d53d0d 100644 --- a/core/database_util_test.go +++ b/core/database_util_test.go @@ -461,12 +461,12 @@ func TestMipmapChain(t *testing.T) { var receipts types.Receipts switch i { case 1: - receipt := types.NewReceipt(nil, new(big.Int)) + receipt := types.NewReceipt(nil, false, new(big.Int)) receipt.Logs = []*types.Log{{Address: addr, Topics: []common.Hash{hash1}}} gen.AddUncheckedReceipt(receipt) receipts = types.Receipts{receipt} case 1000: - receipt := types.NewReceipt(nil, new(big.Int)) + receipt := types.NewReceipt(nil, false, new(big.Int)) receipt.Logs = []*types.Log{{Address: addr2}} gen.AddUncheckedReceipt(receipt) receipts = types.Receipts{receipt} diff --git a/core/state_processor.go b/core/state_processor.go index 4489cfce25..a4b554b10a 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -98,7 +98,7 @@ func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common // about the transaction and calling mechanisms. vmenv := vm.NewEVM(context, statedb, config, cfg) // Apply the transaction to the current state (included in the env) - _, gas, err := ApplyMessage(vmenv, msg, gp) + _, gas, failed, err := ApplyMessage(vmenv, msg, gp) if err != nil { return nil, nil, err } @@ -114,7 +114,7 @@ func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common // Create a new receipt for the transaction, storing the intermediate root and gas used by the tx // based on the eip phase, we're passing wether the root touch-delete accounts. - receipt := types.NewReceipt(root, usedGas) + receipt := types.NewReceipt(root, failed, usedGas) receipt.TxHash = tx.Hash() receipt.GasUsed = new(big.Int).Set(gas) // if the transaction created a contract, store the creation address in the receipt. diff --git a/core/state_transition.go b/core/state_transition.go index 0ae9d7fcbf..bab4540be8 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -59,8 +59,7 @@ type StateTransition struct { value *big.Int data []byte state vm.StateDB - - evm *vm.EVM + evm *vm.EVM } // Message represents a message sent to a contract. @@ -127,11 +126,11 @@ func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition // the gas used (which includes gas refunds) and an error if it failed. An error always // indicates a core error meaning that the message would always fail for that particular // state and would never be accepted within a block. -func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) ([]byte, *big.Int, error) { +func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) ([]byte, *big.Int, bool, error) { st := NewStateTransition(evm, msg, gp) - ret, _, gasUsed, err := st.TransitionDb() - return ret, gasUsed, err + ret, _, gasUsed, failed, err := st.TransitionDb() + return ret, gasUsed, failed, err } func (st *StateTransition) from() vm.AccountRef { @@ -208,7 +207,7 @@ func (st *StateTransition) preCheck() error { // TransitionDb will transition the state by applying the current message and returning the result // including the required gas for the operation as well as the used gas. It returns an error if it // failed. An error indicates a consensus issue. -func (st *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big.Int, err error) { +func (st *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big.Int, failed bool, err error) { if err = st.preCheck(); err != nil { return } @@ -222,10 +221,10 @@ func (st *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big // TODO convert to uint64 intrinsicGas := IntrinsicGas(st.data, contractCreation, homestead) if intrinsicGas.BitLen() > 64 { - return nil, nil, nil, vm.ErrOutOfGas + return nil, nil, nil, false, vm.ErrOutOfGas } if err = st.useGas(intrinsicGas.Uint64()); err != nil { - return nil, nil, nil, err + return nil, nil, nil, false, err } var ( @@ -248,7 +247,7 @@ func (st *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big // sufficient balance to make the transfer happen. The first // balance transfer may never fail. if vmerr == vm.ErrInsufficientBalance { - return nil, nil, nil, vmerr + return nil, nil, nil, false, vmerr } } requiredGas = new(big.Int).Set(st.gasUsed()) @@ -256,7 +255,7 @@ func (st *StateTransition) TransitionDb() (ret []byte, requiredGas, usedGas *big st.refundGas() st.state.AddBalance(st.evm.Coinbase, new(big.Int).Mul(st.gasUsed(), st.gasPrice)) - return ret, requiredGas, st.gasUsed(), err + return ret, requiredGas, st.gasUsed(), vmerr != nil, err } func (st *StateTransition) refundGas() { diff --git a/core/types/gen_receipt_json.go b/core/types/gen_receipt_json.go index eb2e5d42b4..1e6880c223 100644 --- a/core/types/gen_receipt_json.go +++ b/core/types/gen_receipt_json.go @@ -14,6 +14,7 @@ import ( func (r Receipt) MarshalJSON() ([]byte, error) { type Receipt struct { PostState hexutil.Bytes `json:"root"` + Failed bool `json:"failed"` CumulativeGasUsed *hexutil.Big `json:"cumulativeGasUsed" gencodec:"required"` Bloom Bloom `json:"logsBloom" gencodec:"required"` Logs []*Log `json:"logs" gencodec:"required"` @@ -23,6 +24,7 @@ func (r Receipt) MarshalJSON() ([]byte, error) { } var enc Receipt enc.PostState = r.PostState + enc.Failed = r.Failed enc.CumulativeGasUsed = (*hexutil.Big)(r.CumulativeGasUsed) enc.Bloom = r.Bloom enc.Logs = r.Logs @@ -35,6 +37,7 @@ func (r Receipt) MarshalJSON() ([]byte, error) { func (r *Receipt) UnmarshalJSON(input []byte) error { type Receipt struct { PostState hexutil.Bytes `json:"root"` + Failed *bool `json:"failed"` CumulativeGasUsed *hexutil.Big `json:"cumulativeGasUsed" gencodec:"required"` Bloom *Bloom `json:"logsBloom" gencodec:"required"` Logs []*Log `json:"logs" gencodec:"required"` @@ -49,6 +52,9 @@ func (r *Receipt) UnmarshalJSON(input []byte) error { if dec.PostState != nil { r.PostState = dec.PostState } + if dec.Failed != nil { + r.Failed = *dec.Failed + } if dec.CumulativeGasUsed == nil { return errors.New("missing required field 'cumulativeGasUsed' for Receipt") } diff --git a/core/types/receipt.go b/core/types/receipt.go index c9906b0154..9c49648b43 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -28,10 +28,16 @@ import ( //go:generate gencodec -type Receipt -field-override receiptMarshaling -out gen_receipt_json.go +const ( + receiptStatusSuccessful = byte(0x01) + receiptStatusFailed = byte(0x00) +) + // Receipt represents the results of a transaction. type Receipt struct { // Consensus fields PostState []byte `json:"root"` + Failed bool `json:"failed"` CumulativeGasUsed *big.Int `json:"cumulativeGasUsed" gencodec:"required"` Bloom Bloom `json:"logsBloom" gencodec:"required"` Logs []*Log `json:"logs" gencodec:"required"` @@ -60,21 +66,26 @@ type homesteadReceiptRLP struct { // metropolisReceiptRLP contains the receipt's Metropolis consensus fields, used // during RLP serialization. type metropolisReceiptRLP struct { + Status byte CumulativeGasUsed *big.Int Bloom Bloom Logs []*Log } // NewReceipt creates a barebone transaction receipt, copying the init fields. -func NewReceipt(root []byte, cumulativeGasUsed *big.Int) *Receipt { - return &Receipt{PostState: common.CopyBytes(root), CumulativeGasUsed: new(big.Int).Set(cumulativeGasUsed)} +func NewReceipt(root []byte, failed bool, cumulativeGasUsed *big.Int) *Receipt { + return &Receipt{PostState: common.CopyBytes(root), Failed: failed, CumulativeGasUsed: new(big.Int).Set(cumulativeGasUsed)} } // EncodeRLP implements rlp.Encoder, and flattens the consensus fields of a receipt // into an RLP stream. If no post state is present, metropolis fork is assumed. func (r *Receipt) EncodeRLP(w io.Writer) error { if r.PostState == nil { - return rlp.Encode(w, &metropolisReceiptRLP{r.CumulativeGasUsed, r.Bloom, r.Logs}) + status := receiptStatusSuccessful + if r.Failed { + status = receiptStatusFailed + } + return rlp.Encode(w, &metropolisReceiptRLP{status, r.CumulativeGasUsed, r.Bloom, r.Logs}) } return rlp.Encode(w, &homesteadReceiptRLP{r.PostState, r.CumulativeGasUsed, r.Bloom, r.Logs}) } @@ -87,29 +98,31 @@ func (r *Receipt) DecodeRLP(s *rlp.Stream) error { if err != nil { return err } - list, _, err := rlp.SplitList(raw) + content, _, err := rlp.SplitList(raw) if err != nil { return err } - items, err := rlp.CountValues(list) + kind, cnt, _, err := rlp.Split(content) if err != nil { return err } - // Deserialize based on the number of content items - switch items { - case 3: - // Metropolis receipts have 3 components + // Deserialize based on the first component type. + switch { + case kind == rlp.Byte || kind == rlp.String && len(cnt) == 0: + // The first component of metropolis receipts is Byte + // or empty String(byte with 0x00 value). var metro metropolisReceiptRLP if err := rlp.DecodeBytes(raw, &metro); err != nil { return err } + r.Failed = metro.Status == receiptStatusFailed r.CumulativeGasUsed = metro.CumulativeGasUsed r.Bloom = metro.Bloom r.Logs = metro.Logs return nil - case 4: - // Homestead receipts have 4 components + case kind == rlp.String: + // The first component of homestead receipts is non-empty String. var home homesteadReceiptRLP if err := rlp.DecodeBytes(raw, &home); err != nil { return err @@ -121,14 +134,14 @@ func (r *Receipt) DecodeRLP(s *rlp.Stream) error { return nil default: - return fmt.Errorf("invalid receipt components: %v", items) + return fmt.Errorf("invalid first receipt component: %v", kind) } } // String implements the Stringer interface. func (r *Receipt) String() string { if r.PostState == nil { - return fmt.Sprintf("receipt{cgas=%v bloom=%x logs=%v}", r.CumulativeGasUsed, r.Bloom, r.Logs) + return fmt.Sprintf("receipt{failed=%t cgas=%v bloom=%x logs=%v}", r.Failed, r.CumulativeGasUsed, r.Bloom, r.Logs) } return fmt.Sprintf("receipt{med=%x cgas=%v bloom=%x logs=%v}", r.PostState, r.CumulativeGasUsed, r.Bloom, r.Logs) } @@ -144,7 +157,7 @@ func (r *ReceiptForStorage) EncodeRLP(w io.Writer) error { for i, log := range r.Logs { logs[i] = (*LogForStorage)(log) } - return rlp.Encode(w, []interface{}{r.PostState, r.CumulativeGasUsed, r.Bloom, r.TxHash, r.ContractAddress, logs, r.GasUsed}) + return rlp.Encode(w, []interface{}{r.PostState, r.Failed, r.CumulativeGasUsed, r.Bloom, r.TxHash, r.ContractAddress, logs, r.GasUsed}) } // DecodeRLP implements rlp.Decoder, and loads both consensus and implementation @@ -152,6 +165,7 @@ func (r *ReceiptForStorage) EncodeRLP(w io.Writer) error { func (r *ReceiptForStorage) DecodeRLP(s *rlp.Stream) error { var receipt struct { PostState []byte + Failed bool CumulativeGasUsed *big.Int Bloom Bloom TxHash common.Hash @@ -163,7 +177,7 @@ func (r *ReceiptForStorage) DecodeRLP(s *rlp.Stream) error { return err } // Assign the consensus fields - r.PostState, r.CumulativeGasUsed, r.Bloom = receipt.PostState, receipt.CumulativeGasUsed, receipt.Bloom + r.PostState, r.Failed, r.CumulativeGasUsed, r.Bloom = receipt.PostState, receipt.Failed, receipt.CumulativeGasUsed, receipt.Bloom r.Logs = make([]*Log, len(receipt.Logs)) for i, log := range receipt.Logs { r.Logs[i] = (*Log)(log) diff --git a/core/vm/evm.go b/core/vm/evm.go index 8d654c666e..34933a1dc4 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -158,7 +158,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value) // initialise a new contract and set the code that is to be used by the - // E The contract is a scoped evmironment for this execution context + // E The contract is a scoped environment for this execution context // only. contract := NewContract(caller, to, value, gas) contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) @@ -351,6 +351,10 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I contract.UseGas(contract.Gas) } } + // Assign err if contract code size exceeds the max while the err is still empty. + if maxCodeSizeExceeded && err == nil { + err = errMaxCodeSizeExceeded + } return ret, contractAddr, contract.Gas, err } diff --git a/core/vm/instructions.go b/core/vm/instructions.go index ece4d2229a..b6d6e22c4c 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -33,6 +33,7 @@ var ( errWriteProtection = errors.New("evm: write protection") errReturnDataOutOfBounds = errors.New("evm: return data out of bounds") errExecutionReverted = errors.New("evm: execution reverted") + errMaxCodeSizeExceeded = errors.New("evm: max code size exceeded") ) func opAdd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { @@ -619,7 +620,6 @@ func opCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta if value.Sign() != 0 { gas += params.CallStipend } - ret, returnGas, err := evm.Call(contract, address, args, gas, value) if err != nil { stack.push(new(big.Int)) diff --git a/eth/api.go b/eth/api.go index f5214fc379..9904c6f536 100644 --- a/eth/api.go +++ b/eth/api.go @@ -523,7 +523,8 @@ func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, txHash common. // Run the transaction with tracing enabled. vmenv := vm.NewEVM(context, statedb, api.config, vm.Config{Debug: true, Tracer: tracer}) - ret, gas, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())) + // TODO utilize failed flag + ret, gas, _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())) if err != nil { return nil, fmt.Errorf("tracing failed: %v", err) } @@ -570,7 +571,7 @@ func (api *PrivateDebugAPI) computeTxEnv(blockHash common.Hash, txIndex int) (co vmenv := vm.NewEVM(context, statedb, api.config, vm.Config{}) gp := new(core.GasPool).AddGas(tx.Gas()) - _, _, err := core.ApplyMessage(vmenv, msg, gp) + _, _, _, err := core.ApplyMessage(vmenv, msg, gp) if err != nil { return nil, vm.Context{}, nil, fmt.Errorf("tx %x failed: %v", tx.Hash(), err) } diff --git a/eth/backend_test.go b/eth/backend_test.go index 4351b24cfb..1fd25e95aa 100644 --- a/eth/backend_test.go +++ b/eth/backend_test.go @@ -35,11 +35,11 @@ func TestMipmapUpgrade(t *testing.T) { chain, receipts := core.GenerateChain(params.TestChainConfig, genesis, db, 10, func(i int, gen *core.BlockGen) { switch i { case 1: - receipt := types.NewReceipt(nil, new(big.Int)) + receipt := types.NewReceipt(nil, false, new(big.Int)) receipt.Logs = []*types.Log{{Address: addr}} gen.AddUncheckedReceipt(receipt) case 2: - receipt := types.NewReceipt(nil, new(big.Int)) + receipt := types.NewReceipt(nil, false, new(big.Int)) receipt.Logs = []*types.Log{{Address: addr}} gen.AddUncheckedReceipt(receipt) } diff --git a/eth/filters/filter_test.go b/eth/filters/filter_test.go index 3244c04d74..cf508a218d 100644 --- a/eth/filters/filter_test.go +++ b/eth/filters/filter_test.go @@ -33,7 +33,7 @@ import ( ) func makeReceipt(addr common.Address) *types.Receipt { - receipt := types.NewReceipt(nil, new(big.Int)) + receipt := types.NewReceipt(nil, false, new(big.Int)) receipt.Logs = []*types.Log{ {Address: addr}, } @@ -145,7 +145,7 @@ func TestFilters(t *testing.T) { var receipts types.Receipts switch i { case 1: - receipt := types.NewReceipt(nil, new(big.Int)) + receipt := types.NewReceipt(nil, false, new(big.Int)) receipt.Logs = []*types.Log{ { Address: addr, @@ -155,7 +155,7 @@ func TestFilters(t *testing.T) { gen.AddUncheckedReceipt(receipt) receipts = types.Receipts{receipt} case 2: - receipt := types.NewReceipt(nil, new(big.Int)) + receipt := types.NewReceipt(nil, false, new(big.Int)) receipt.Logs = []*types.Log{ { Address: addr, @@ -165,7 +165,7 @@ func TestFilters(t *testing.T) { gen.AddUncheckedReceipt(receipt) receipts = types.Receipts{receipt} case 998: - receipt := types.NewReceipt(nil, new(big.Int)) + receipt := types.NewReceipt(nil, false, new(big.Int)) receipt.Logs = []*types.Log{ { Address: addr, @@ -175,7 +175,7 @@ func TestFilters(t *testing.T) { gen.AddUncheckedReceipt(receipt) receipts = types.Receipts{receipt} case 999: - receipt := types.NewReceipt(nil, new(big.Int)) + receipt := types.NewReceipt(nil, false, new(big.Int)) receipt.Logs = []*types.Log{ { Address: addr, diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index c3924b93a7..30710aaabd 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -635,7 +635,8 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr // Setup the gas pool (also for unmetered requests) // and apply the message. gp := new(core.GasPool).AddGas(math.MaxBig256) - res, gas, err := core.ApplyMessage(evm, msg, gp) + // TODO utilize failed flag to help gas estimation + res, gas, _, err := core.ApplyMessage(evm, msg, gp) if err := vmError(); err != nil { return nil, common.Big0, err } diff --git a/les/odr_test.go b/les/odr_test.go index 3a0fd6738f..f56c4036d4 100644 --- a/les/odr_test.go +++ b/les/odr_test.go @@ -127,7 +127,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai //vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{}) gp := new(core.GasPool).AddGas(math.MaxBig256) - ret, _, _ := core.ApplyMessage(vmenv, msg, gp) + ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp) res = append(res, ret...) } } else { @@ -138,7 +138,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai context := core.NewEVMContext(msg, header, lc, nil) vmenv := vm.NewEVM(context, state, config, vm.Config{}) gp := new(core.GasPool).AddGas(math.MaxBig256) - ret, _, _ := core.ApplyMessage(vmenv, msg, gp) + ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp) if state.Error() == nil { res = append(res, ret...) } diff --git a/light/odr_test.go b/light/odr_test.go index bd1e976e81..c0c5438fdb 100644 --- a/light/odr_test.go +++ b/light/odr_test.go @@ -180,7 +180,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain context := core.NewEVMContext(msg, header, chain, nil) vmenv := vm.NewEVM(context, st, config, vm.Config{}) gp := new(core.GasPool).AddGas(math.MaxBig256) - ret, _, _ := core.ApplyMessage(vmenv, msg, gp) + ret, _, _, _ := core.ApplyMessage(vmenv, msg, gp) res = append(res, ret...) if st.Error() != nil { return res, st.Error() diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 2bf940bab7..0eb85ab28e 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -156,7 +156,7 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config) error { gaspool := new(core.GasPool) gaspool.AddGas(block.GasLimit()) snapshot := statedb.Snapshot() - if _, _, err := core.ApplyMessage(evm, msg, gaspool); err != nil { + if _, _, _, err := core.ApplyMessage(evm, msg, gaspool); err != nil { statedb.RevertToSnapshot(snapshot) } if post.Logs != nil { From 79bf69b55687704429e083c22fb62ba931648e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Tue, 22 Aug 2017 18:30:46 +0300 Subject: [PATCH 04/19] tests: pull in new test suite, enable most block tests --- tests/block_test.go | 7 ++++--- tests/testdata | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/block_test.go b/tests/block_test.go index 6fc66b17cc..066f280349 100644 --- a/tests/block_test.go +++ b/tests/block_test.go @@ -33,10 +33,11 @@ func TestBlockchain(t *testing.T) { // Constantinople is not implemented yet. bt.skipLoad(`(?i)(constantinople)`) // Expected failures: - bt.fails("^TransitionTests/bcEIP158ToByzantium", "byzantium not supported") bt.fails(`^TransitionTests/bcHomesteadToDao/DaoTransactions(|_UncleExtradata|_EmptyTransactionAndForkBlocksAhead)\.json`, "issue in test") - bt.fails(`^bc(Exploit|Fork|Gas|Multi|Total|State|Random|Uncle|Valid|Wallet).*_Byzantium$`, "byzantium not supported") - bt.fails(`^bcBlockGasLimitTest/(BlockGasLimit2p63m1|TransactionGasHigherThanLimit2p63m1|SuicideTransaction|GasUsedHigherThanBlockGasLimitButNotWithRefundsSuicideFirst|TransactionGasHigherThanLimit2p63m1_2).*_Byzantium$`, "byzantium not supported") + + // Still failing tests + bt.skipLoad(`^bcWalletTest.*_Byzantium$`) + bt.skipLoad(`^bcStateTests/suicideCoinbase.json.*_Byzantium$`) bt.walk(t, blockTestDir, func(t *testing.T, name string, test *BlockTest) { if err := bt.checkFailure(t, name, test.Run()); err != nil { diff --git a/tests/testdata b/tests/testdata index 85f6d7cc01..70e5862eb2 160000 --- a/tests/testdata +++ b/tests/testdata @@ -1 +1 @@ -Subproject commit 85f6d7cc01b6bd04e071f5ba579fc675cfd2043b +Subproject commit 70e5862eb267226ca89fb9f395c97be1fdf6923a From 4ee92f2d193225e70c190194d005a6ce80e70236 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Wed, 23 Aug 2017 10:41:12 +0300 Subject: [PATCH 05/19] core/types: reject Metro receipts with > 0x01 status bytes --- core/types/receipt.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/core/types/receipt.go b/core/types/receipt.go index 9c49648b43..b54bd7b4f9 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -108,14 +108,21 @@ func (r *Receipt) DecodeRLP(s *rlp.Stream) error { } // Deserialize based on the first component type. switch { - case kind == rlp.Byte || kind == rlp.String && len(cnt) == 0: - // The first component of metropolis receipts is Byte - // or empty String(byte with 0x00 value). + case kind == rlp.Byte || (kind == rlp.String && len(cnt) == 0): + // The first component of metropolis receipts is Byte (0x01), or the empty + // string (0x80, decoded as a byte with 0x00 value). var metro metropolisReceiptRLP if err := rlp.DecodeBytes(raw, &metro); err != nil { return err } - r.Failed = metro.Status == receiptStatusFailed + switch metro.Status { + case receiptStatusSuccessful: + r.Failed = false + case receiptStatusFailed: + r.Failed = true + default: + return fmt.Errorf("invalid status byte: 0x%x", metro.Status) + } r.CumulativeGasUsed = metro.CumulativeGasUsed r.Bloom = metro.Bloom r.Logs = metro.Logs From 286ec5df40d3707a7a2c98d49c8d324372ed29c2 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Wed, 23 Aug 2017 13:37:18 +0200 Subject: [PATCH 06/19] cmd/evm, core/vm, internal/ethapi: Show error when exiting (#14985) * cmd/evm, core/vm, internal/ethapi: Add 'err' to tracer interface CaptureEnd * cmd/evm: fix nullpointer when there is no error --- cmd/evm/json_logger.go | 8 ++++++-- cmd/evm/runner.go | 8 ++++---- core/vm/logger.go | 7 +++++-- internal/ethapi/tracer.go | 2 +- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/cmd/evm/json_logger.go b/cmd/evm/json_logger.go index d61981062c..2cfeaa7952 100644 --- a/cmd/evm/json_logger.go +++ b/cmd/evm/json_logger.go @@ -57,11 +57,15 @@ func (l *JSONLogger) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cos } // CaptureEnd is triggered at end of execution. -func (l *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration) error { +func (l *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error { type endLog struct { Output string `json:"output"` GasUsed math.HexOrDecimal64 `json:"gasUsed"` Time time.Duration `json:"time"` + Err string `json:"error,omitempty"` } - return l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t}) + if err != nil { + return l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t, err.Error()}) + } + return l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t, ""}) } diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go index ae56781103..96de0c76ac 100644 --- a/cmd/evm/runner.go +++ b/cmd/evm/runner.go @@ -234,13 +234,13 @@ Gas used: %d `, execTime, mem.HeapObjects, mem.Alloc, mem.TotalAlloc, mem.NumGC, initialGas-leftOverGas) } if tracer != nil { - tracer.CaptureEnd(ret, initialGas-leftOverGas, execTime) + tracer.CaptureEnd(ret, initialGas-leftOverGas, execTime, err) } else { fmt.Printf("0x%x\n", ret) + if err != nil { + fmt.Printf(" error: %v\n", err) + } } - if err != nil { - fmt.Printf(" error: %v\n", err) - } return nil } diff --git a/core/vm/logger.go b/core/vm/logger.go index b73b13bd97..5ada310f0a 100644 --- a/core/vm/logger.go +++ b/core/vm/logger.go @@ -86,7 +86,7 @@ func (s *StructLog) OpName() string { // if you need to retain them beyond the current call. type Tracer interface { CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error - CaptureEnd(output []byte, gasUsed uint64, t time.Duration) error + CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error } // StructLogger is an EVM state logger and implements Tracer. @@ -183,8 +183,11 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui return nil } -func (l *StructLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration) error { +func (l *StructLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error { fmt.Printf("0x%x", output) + if err != nil { + fmt.Printf(" error: %v\n", err) + } return nil } diff --git a/internal/ethapi/tracer.go b/internal/ethapi/tracer.go index fc66839ea5..0516265270 100644 --- a/internal/ethapi/tracer.go +++ b/internal/ethapi/tracer.go @@ -346,7 +346,7 @@ func (jst *JavascriptTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, } // CaptureEnd is called after the call finishes -func (jst *JavascriptTracer) CaptureEnd(output []byte, gasUsed uint64, t time.Duration) error { +func (jst *JavascriptTracer) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error { //TODO! @Arachnid please figure out of there's anything we can use this method for return nil } From 63246e25426df51143d5fb06861d418753267ab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Thu, 24 Aug 2017 13:10:50 +0300 Subject: [PATCH 07/19] rlp: fix decoding long strings into RawValue types --- rlp/decode.go | 2 +- rlp/decode_test.go | 33 ++++++++++++++++++++++++--------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/rlp/decode.go b/rlp/decode.go index 78ccf6275e..60d9dab2b5 100644 --- a/rlp/decode.go +++ b/rlp/decode.go @@ -693,7 +693,7 @@ func (s *Stream) Raw() ([]byte, error) { return nil, err } if kind == String { - puthead(buf, 0x80, 0xB8, size) + puthead(buf, 0x80, 0xB7, size) } else { puthead(buf, 0xC0, 0xF7, size) } diff --git a/rlp/decode_test.go b/rlp/decode_test.go index d762e195d0..4d8abd0012 100644 --- a/rlp/decode_test.go +++ b/rlp/decode_test.go @@ -256,16 +256,31 @@ func TestStreamList(t *testing.T) { } func TestStreamRaw(t *testing.T) { - s := NewStream(bytes.NewReader(unhex("C58401010101")), 0) - s.List() - - want := unhex("8401010101") - raw, err := s.Raw() - if err != nil { - t.Fatal(err) + tests := []struct { + input string + output string + }{ + { + "C58401010101", + "8401010101", + }, + { + "F842B84001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101", + "B84001010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101", + }, } - if !bytes.Equal(want, raw) { - t.Errorf("raw mismatch: got %x, want %x", raw, want) + for i, tt := range tests { + s := NewStream(bytes.NewReader(unhex(tt.input)), 0) + s.List() + + want := unhex(tt.output) + raw, err := s.Raw() + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(want, raw) { + t.Errorf("test %d: raw mismatch: got %x, want %x", i, raw, want) + } } } From ff9a8682323648266d5c73f4f4bce545d91edccb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Thu, 24 Aug 2017 13:42:00 +0300 Subject: [PATCH 08/19] core/state: revert metro suicide map addition (#15024) --- core/state/journal.go | 5 --- core/state/statedb.go | 69 ++++++++++++++++------------------------- core/state_processor.go | 2 +- tests/block_test.go | 1 - 4 files changed, 28 insertions(+), 49 deletions(-) diff --git a/core/state/journal.go b/core/state/journal.go index b5c8ca9a21..ddb76f1a2e 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -91,11 +91,6 @@ func (ch suicideChange) undo(s *StateDB) { if obj != nil { obj.suicided = ch.prev obj.setBalance(ch.prevbalance) - // if the object wasn't suicided before, remove - // it from the list of destructed objects as well. - if !obj.suicided { - delete(s.stateObjectsDestructed, *ch.account) - } } } diff --git a/core/state/statedb.go b/core/state/statedb.go index 694374f822..002fa62496 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -46,9 +46,8 @@ type StateDB struct { trie Trie // This map holds 'live' objects, which will get modified while processing a state transition. - stateObjects map[common.Address]*stateObject - stateObjectsDirty map[common.Address]struct{} - stateObjectsDestructed map[common.Address]struct{} + stateObjects map[common.Address]*stateObject + stateObjectsDirty map[common.Address]struct{} // DB error. // State objects are used by the consensus core and VM which are @@ -83,14 +82,13 @@ func New(root common.Hash, db Database) (*StateDB, error) { return nil, err } return &StateDB{ - db: db, - trie: tr, - stateObjects: make(map[common.Address]*stateObject), - stateObjectsDirty: make(map[common.Address]struct{}), - stateObjectsDestructed: make(map[common.Address]struct{}), - refund: new(big.Int), - logs: make(map[common.Hash][]*types.Log), - preimages: make(map[common.Hash][]byte), + db: db, + trie: tr, + stateObjects: make(map[common.Address]*stateObject), + stateObjectsDirty: make(map[common.Address]struct{}), + refund: new(big.Int), + logs: make(map[common.Hash][]*types.Log), + preimages: make(map[common.Hash][]byte), }, nil } @@ -115,7 +113,6 @@ func (self *StateDB) Reset(root common.Hash) error { self.trie = tr self.stateObjects = make(map[common.Address]*stateObject) self.stateObjectsDirty = make(map[common.Address]struct{}) - self.stateObjectsDestructed = make(map[common.Address]struct{}) self.thash = common.Hash{} self.bhash = common.Hash{} self.txIndex = 0 @@ -323,7 +320,6 @@ func (self *StateDB) Suicide(addr common.Address) bool { }) stateObject.markSuicided() stateObject.data.Balance = new(big.Int) - self.stateObjectsDestructed[addr] = struct{}{} return true } @@ -456,23 +452,19 @@ func (self *StateDB) Copy() *StateDB { // Copy all the basic fields, initialize the memory ones state := &StateDB{ - db: self.db, - trie: self.trie, - stateObjects: make(map[common.Address]*stateObject, len(self.stateObjectsDirty)), - stateObjectsDirty: make(map[common.Address]struct{}, len(self.stateObjectsDirty)), - stateObjectsDestructed: make(map[common.Address]struct{}, len(self.stateObjectsDestructed)), - refund: new(big.Int).Set(self.refund), - logs: make(map[common.Hash][]*types.Log, len(self.logs)), - logSize: self.logSize, - preimages: make(map[common.Hash][]byte), + db: self.db, + trie: self.trie, + stateObjects: make(map[common.Address]*stateObject, len(self.stateObjectsDirty)), + stateObjectsDirty: make(map[common.Address]struct{}, len(self.stateObjectsDirty)), + refund: new(big.Int).Set(self.refund), + logs: make(map[common.Hash][]*types.Log, len(self.logs)), + logSize: self.logSize, + preimages: make(map[common.Hash][]byte), } // Copy the dirty states, logs, and preimages for addr := range self.stateObjectsDirty { state.stateObjects[addr] = self.stateObjects[addr].deepCopy(state, state.MarkStateObjectDirty) state.stateObjectsDirty[addr] = struct{}{} - if self.stateObjects[addr].suicided { - state.stateObjectsDestructed[addr] = struct{}{} - } } for hash, logs := range self.logs { state.logs[hash] = make([]*types.Log, len(logs)) @@ -520,10 +512,9 @@ func (self *StateDB) GetRefund() *big.Int { return self.refund } -// IntermediateRoot computes the current root hash of the state trie. -// It is called in between transactions to get the root hash that -// goes into transaction receipts. -func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { +// Finalise finalises the state by removing the self destructed objects +// and clears the journal as well as the refunds. +func (s *StateDB) Finalise(deleteEmptyObjects bool) { for addr := range s.stateObjectsDirty { stateObject := s.stateObjects[addr] if stateObject.suicided || (deleteEmptyObjects && stateObject.empty()) { @@ -535,6 +526,13 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { } // Invalidate journal because reverting across transactions is not allowed. s.clearJournalAndRefund() +} + +// IntermediateRoot computes the current root hash of the state trie. +// It is called in between transactions to get the root hash that +// goes into transaction receipts. +func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { + s.Finalise(deleteEmptyObjects) return s.trie.Hash() } @@ -546,19 +544,6 @@ func (self *StateDB) Prepare(thash, bhash common.Hash, ti int) { self.txIndex = ti } -// Finalise finalises the state by removing the self destructed objects -// in the current stateObjectsDestructed buffer and clears the journal -// as well as the refunds. -// -// Please note that Finalise is used by EIP#98 and is used instead of -// IntermediateRoot. -func (s *StateDB) Finalise() { - for addr := range s.stateObjectsDestructed { - s.deleteStateObject(s.stateObjects[addr]) - } - s.clearJournalAndRefund() -} - // DeleteSuicides flags the suicided objects for deletion so that it // won't be referenced again when called / queried up on. // diff --git a/core/state_processor.go b/core/state_processor.go index a4b554b10a..4115eab8cb 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -106,7 +106,7 @@ func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common // Update the state with pending changes var root []byte if config.IsMetropolis(header.Number) { - statedb.Finalise() + statedb.Finalise(true) } else { root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes() } diff --git a/tests/block_test.go b/tests/block_test.go index 066f280349..56e1e1e8da 100644 --- a/tests/block_test.go +++ b/tests/block_test.go @@ -37,7 +37,6 @@ func TestBlockchain(t *testing.T) { // Still failing tests bt.skipLoad(`^bcWalletTest.*_Byzantium$`) - bt.skipLoad(`^bcStateTests/suicideCoinbase.json.*_Byzantium$`) bt.walk(t, blockTestDir, func(t *testing.T, name string, test *BlockTest) { if err := bt.checkFailure(t, name, test.Run()); err != nil { From 68955ed2eb12165416411dc30b1ac4d74aa49307 Mon Sep 17 00:00:00 2001 From: nkbai Date: Thu, 24 Aug 2017 18:48:13 +0800 Subject: [PATCH 09/19] core/types: fix create indicator in Transaction.String (#15025) --- core/types/transaction.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/types/transaction.go b/core/types/transaction.go index 8e108b2a33..947fc85d60 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -300,7 +300,7 @@ func (tx *Transaction) String() string { Hex: %x `, tx.Hash(), - len(tx.data.Recipient) == 0, + tx.data.Recipient == nil, from, to, tx.data.AccountNonce, From b872961ec82ec88a7ac6ef331cfb3eb685ce2c00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Thu, 24 Aug 2017 12:26:06 +0300 Subject: [PATCH 10/19] consensus, core, tests: implement Metropolis EIP 649 --- consensus/ethash/consensus.go | 25 +++++++++++--- core/chain_makers.go | 2 +- core/vm/logger.go | 8 ++--- tests/gen_stlog.go | 61 ----------------------------------- tests/state_test_util.go | 56 ++++++-------------------------- tests/testdata | 2 +- tests/vm_test.go | 4 +++ tests/vm_test_util.go | 21 ++++++------ 8 files changed, 50 insertions(+), 129 deletions(-) delete mode 100644 tests/gen_stlog.go diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 01d97a470e..b714204458 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -36,8 +36,9 @@ import ( // Ethash proof-of-work protocol constants. var ( - blockReward *big.Int = big.NewInt(5e+18) // Block reward in wei for successfully mining a block - maxUncles = 2 // Maximum number of uncles allowed in a single block + frontierBlockReward *big.Int = big.NewInt(5e+18) // Block reward in wei for successfully mining a block + metropolisBlockReward *big.Int = big.NewInt(3e+18) // Block reward in wei for successfully mining a block upward from Metropolis + maxUncles = 2 // Maximum number of uncles allowed in a single block ) // Various error messages to mark blocks invalid. These should be private to @@ -306,6 +307,7 @@ var ( big9 = big.NewInt(9) big10 = big.NewInt(10) bigMinus99 = big.NewInt(-99) + big2999999 = big.NewInt(2999999) ) // calcDifficultyMetropolis is the difficulty adjustment algorithm. It returns @@ -346,8 +348,15 @@ func calcDifficultyMetropolis(time uint64, parent *types.Header) *big.Int { if x.Cmp(params.MinimumDifficulty) < 0 { x.Set(params.MinimumDifficulty) } + // calculate a fake block numer for the ice-age delay: + // https://github.com/ethereum/EIPs/pull/669 + // fake_block_number = min(0, block.number - 3_000_000 + fakeBlockNumber := new(big.Int) + if parent.Number.Cmp(big2999999) >= 0 { + fakeBlockNumber = fakeBlockNumber.Sub(parent.Number, big2999999) // Note, parent is 1 less than the actual block number + } // for the exponential factor - periodCount := new(big.Int).Add(parent.Number, big1) + periodCount := fakeBlockNumber periodCount.Div(periodCount, expDiffPeriod) // the exponential factor, commonly referred to as "the bomb" @@ -501,7 +510,7 @@ func (ethash *Ethash) Prepare(chain consensus.ChainReader, header *types.Header) // setting the final state and assembling the block. func (ethash *Ethash) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { // Accumulate any block and uncle rewards and commit the final state root - AccumulateRewards(state, header, uncles) + AccumulateRewards(chain.Config(), state, header, uncles) header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) // Header seems complete, assemble into a block and return @@ -518,7 +527,13 @@ var ( // reward. The total reward consists of the static block reward and rewards for // included uncles. The coinbase of each uncle block is also rewarded. // TODO (karalabe): Move the chain maker into this package and make this private! -func AccumulateRewards(state *state.StateDB, header *types.Header, uncles []*types.Header) { +func AccumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) { + // Select the correct block reward based on chain progression + blockReward := frontierBlockReward + if config.IsMetropolis(header.Number) { + blockReward = metropolisBlockReward + } + // Accumulate the rewards for the miner and any included uncles reward := new(big.Int).Set(blockReward) r := new(big.Int) for _, uncle := range uncles { diff --git a/core/chain_makers.go b/core/chain_makers.go index cb5825d187..dd3e2fb192 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -179,7 +179,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, db ethdb.Dat if gen != nil { gen(i, b) } - ethash.AccumulateRewards(statedb, h, b.uncles) + ethash.AccumulateRewards(config, statedb, h, b.uncles) root, err := statedb.CommitTo(db, config.IsEIP158(h.Number)) if err != nil { panic(fmt.Sprintf("state write error: %v", err)) diff --git a/core/vm/logger.go b/core/vm/logger.go index 5ada310f0a..623c0d5632 100644 --- a/core/vm/logger.go +++ b/core/vm/logger.go @@ -128,18 +128,14 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost ui } // capture SSTORE opcodes and determine the changed value and store - // it in the local storage container. NOTE: we do not need to do any - // range checks here because that's already handler prior to calling - // this function. - switch op { - case SSTORE: + // it in the local storage container. + if op == SSTORE && stack.len() >= 2 { var ( value = common.BigToHash(stack.data[stack.len()-2]) address = common.BigToHash(stack.data[stack.len()-1]) ) l.changedValues[contract.Address()][address] = value } - // copy a snapstot of the current memory state to a new buffer var mem []byte if !l.cfg.DisableMemory { diff --git a/tests/gen_stlog.go b/tests/gen_stlog.go deleted file mode 100644 index 4f7ebc9660..0000000000 --- a/tests/gen_stlog.go +++ /dev/null @@ -1,61 +0,0 @@ -// Code generated by github.com/fjl/gencodec. DO NOT EDIT. - -package tests - -import ( - "encoding/json" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" -) - -var _ = (*stLogMarshaling)(nil) - -func (s stLog) MarshalJSON() ([]byte, error) { - type stLog struct { - Address common.UnprefixedAddress `json:"address"` - Data hexutil.Bytes `json:"data"` - Topics []common.UnprefixedHash `json:"topics"` - Bloom string `json:"bloom"` - } - var enc stLog - enc.Address = common.UnprefixedAddress(s.Address) - enc.Data = s.Data - if s.Topics != nil { - enc.Topics = make([]common.UnprefixedHash, len(s.Topics)) - for k, v := range s.Topics { - enc.Topics[k] = common.UnprefixedHash(v) - } - } - enc.Bloom = s.Bloom - return json.Marshal(&enc) -} - -func (s *stLog) UnmarshalJSON(input []byte) error { - type stLog struct { - Address *common.UnprefixedAddress `json:"address"` - Data hexutil.Bytes `json:"data"` - Topics []common.UnprefixedHash `json:"topics"` - Bloom *string `json:"bloom"` - } - var dec stLog - if err := json.Unmarshal(input, &dec); err != nil { - return err - } - if dec.Address != nil { - s.Address = common.Address(*dec.Address) - } - if dec.Data != nil { - s.Data = dec.Data - } - if dec.Topics != nil { - s.Topics = make([]common.Hash, len(dec.Topics)) - for k, v := range dec.Topics { - s.Topics[k] = common.Hash(v) - } - } - if dec.Bloom != nil { - s.Bloom = *dec.Bloom - } - return nil -} diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 0eb85ab28e..ecaa6c6684 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -17,12 +17,10 @@ package tests import ( - "bytes" "encoding/hex" "encoding/json" "fmt" "math/big" - "reflect" "strings" "github.com/ethereum/go-ethereum/common" @@ -33,8 +31,10 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/crypto/sha3" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" ) // StateTest checks transaction processing without block context. @@ -63,7 +63,7 @@ type stJSON struct { type stPostState struct { Root common.UnprefixedHash `json:"hash"` - Logs *[]stLog `json:"logs"` + Logs common.UnprefixedHash `json:"logs"` Indexes struct { Data int `json:"data"` Gas int `json:"gas"` @@ -108,21 +108,6 @@ type stTransactionMarshaling struct { PrivateKey hexutil.Bytes } -//go:generate gencodec -type stLog -field-override stLogMarshaling -out gen_stlog.go - -type stLog struct { - Address common.Address `json:"address"` - Data []byte `json:"data"` - Topics []common.Hash `json:"topics"` - Bloom string `json:"bloom"` -} - -type stLogMarshaling struct { - Address common.UnprefixedAddress - Data hexutil.Bytes - Topics []common.UnprefixedHash -} - // Subtests returns all valid subtests of the test. func (t *StateTest) Subtests() []StateSubtest { var sub []StateSubtest @@ -159,10 +144,8 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config) error { if _, _, _, err := core.ApplyMessage(evm, msg, gaspool); err != nil { statedb.RevertToSnapshot(snapshot) } - if post.Logs != nil { - if err := checkLogs(statedb.Logs(), *post.Logs); err != nil { - return err - } + if logs := rlpHash(statedb.Logs()); logs != common.Hash(post.Logs) { + return fmt.Errorf("post state logs hash mismatch: got %x, want %x", logs, post.Logs) } root, _ := statedb.CommitTo(db, config.IsEIP158(block.Number())) if root != common.Hash(post.Root) { @@ -254,28 +237,9 @@ func (tx *stTransaction) toMessage(ps stPostState) (core.Message, error) { return msg, nil } -func checkLogs(have []*types.Log, want []stLog) error { - if len(have) != len(want) { - return fmt.Errorf("logs length mismatch: got %d, want %d", len(have), len(want)) - } - for i := range have { - if have[i].Address != want[i].Address { - return fmt.Errorf("log address %d: got %x, want %x", i, have[i].Address, want[i].Address) - } - if !bytes.Equal(have[i].Data, want[i].Data) { - return fmt.Errorf("log data %d: got %x, want %x", i, have[i].Data, want[i].Data) - } - if !reflect.DeepEqual(have[i].Topics, want[i].Topics) { - return fmt.Errorf("log topics %d:\ngot %x\nwant %x", i, have[i].Topics, want[i].Topics) - } - genBloom := math.PaddedBigBytes(types.LogsBloom([]*types.Log{have[i]}), 256) - var wantBloom types.Bloom - if err := hexutil.UnmarshalFixedUnprefixedText("Bloom", []byte(want[i].Bloom), wantBloom[:]); err != nil { - return fmt.Errorf("test log %d has invalid bloom: %v", i, err) - } - if !bytes.Equal(genBloom, wantBloom[:]) { - return fmt.Errorf("bloom mismatch") - } - } - return nil +func rlpHash(x interface{}) (h common.Hash) { + hw := sha3.NewKeccak256() + rlp.Encode(hw, x) + hw.Sum(h[:0]) + return h } diff --git a/tests/testdata b/tests/testdata index 70e5862eb2..cd2c3f1b3a 160000 --- a/tests/testdata +++ b/tests/testdata @@ -1 +1 @@ -Subproject commit 70e5862eb267226ca89fb9f395c97be1fdf6923a +Subproject commit cd2c3f1b3acb98c0d1501b06a4a54629d8794d79 diff --git a/tests/vm_test.go b/tests/vm_test.go index 5289ba3559..f35abeb110 100644 --- a/tests/vm_test.go +++ b/tests/vm_test.go @@ -26,6 +26,10 @@ func TestVM(t *testing.T) { t.Parallel() vmt := new(testMatcher) vmt.fails("^vmSystemOperationsTest.json/createNameRegistrator$", "fails without parallel execution") + + vmt.skipLoad(`^vmPerformanceTest.json`) // log format broken + vmt.skipLoad(`^vmInputLimits(Light)?.json`) // log format broken + vmt.skipShortMode("^vmPerformanceTest.json") vmt.skipShortMode("^vmInputLimits(Light)?.json") diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go index afdd896c35..0aa37955ce 100644 --- a/tests/vm_test_util.go +++ b/tests/vm_test_util.go @@ -44,14 +44,14 @@ func (t *VMTest) UnmarshalJSON(data []byte) error { } type vmJSON struct { - Env stEnv `json:"env"` - Exec vmExec `json:"exec"` - Logs []stLog `json:"logs"` - GasRemaining *math.HexOrDecimal64 `json:"gas"` - Out hexutil.Bytes `json:"out"` - Pre core.GenesisAlloc `json:"pre"` - Post core.GenesisAlloc `json:"post"` - PostStateRoot common.Hash `json:"postStateRoot"` + Env stEnv `json:"env"` + Exec vmExec `json:"exec"` + Logs common.UnprefixedHash `json:"logs"` + GasRemaining *math.HexOrDecimal64 `json:"gas"` + Out hexutil.Bytes `json:"out"` + Pre core.GenesisAlloc `json:"pre"` + Post core.GenesisAlloc `json:"post"` + PostStateRoot common.Hash `json:"postStateRoot"` } //go:generate gencodec -type vmExec -field-override vmExecMarshaling -out gen_vmexec.go @@ -109,7 +109,10 @@ func (t *VMTest) Run(vmconfig vm.Config) error { // if root := statedb.IntermediateRoot(false); root != t.json.PostStateRoot { // return fmt.Errorf("post state root mismatch, got %x, want %x", root, t.json.PostStateRoot) // } - return checkLogs(statedb.Logs(), t.json.Logs) + if logs := rlpHash(statedb.Logs()); logs != common.Hash(t.json.Logs) { + return fmt.Errorf("post state logs hash mismatch: got %x, want %x", logs, t.json.Logs) + } + return nil } func (t *VMTest) exec(statedb *state.StateDB, vmconfig vm.Config) ([]byte, uint64, error) { From ad16aeb0a2e79ef6e9db30667152d73565715391 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 24 Aug 2017 15:17:02 +0200 Subject: [PATCH 11/19] core/types: encode receipt status in PostState field This fixes a regression where the new Failed field in ReceiptForStorage rejected previously stored receipts. Fix it by removing the new field and store status in the PostState field. This also removes massive RLP hackery around the status field. --- core/database_util_test.go | 4 +- core/types/receipt.go | 143 ++++++++++++++++--------------------- 2 files changed, 63 insertions(+), 84 deletions(-) diff --git a/core/database_util_test.go b/core/database_util_test.go index 5c75d53d0d..e91f1b5930 100644 --- a/core/database_util_test.go +++ b/core/database_util_test.go @@ -340,7 +340,7 @@ func TestBlockReceiptStorage(t *testing.T) { db, _ := ethdb.NewMemDatabase() receipt1 := &types.Receipt{ - PostState: []byte{0x01}, + Failed: true, CumulativeGasUsed: big.NewInt(1), Logs: []*types.Log{ {Address: common.BytesToAddress([]byte{0x11})}, @@ -351,7 +351,7 @@ func TestBlockReceiptStorage(t *testing.T) { GasUsed: big.NewInt(111111), } receipt2 := &types.Receipt{ - PostState: []byte{0x02}, + PostState: common.Hash{2}.Bytes(), CumulativeGasUsed: big.NewInt(2), Logs: []*types.Log{ {Address: common.BytesToAddress([]byte{0x22})}, diff --git a/core/types/receipt.go b/core/types/receipt.go index b54bd7b4f9..4f3b7357ed 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -17,6 +17,7 @@ package types import ( + "bytes" "fmt" "io" "math/big" @@ -28,9 +29,9 @@ import ( //go:generate gencodec -type Receipt -field-override receiptMarshaling -out gen_receipt_json.go -const ( - receiptStatusSuccessful = byte(0x01) - receiptStatusFailed = byte(0x00) +var ( + receiptStatusFailed = []byte{} + receiptStatusSuccessful = []byte{0x01} ) // Receipt represents the results of a transaction. @@ -54,22 +55,22 @@ type receiptMarshaling struct { GasUsed *hexutil.Big } -// homesteadReceiptRLP contains the receipt's Homestead consensus fields, used -// during RLP serialization. -type homesteadReceiptRLP struct { - PostState []byte +// receiptRLP is the consensus encoding of a receipt. +type receiptRLP struct { + PostStateOrStatus []byte CumulativeGasUsed *big.Int Bloom Bloom Logs []*Log } -// metropolisReceiptRLP contains the receipt's Metropolis consensus fields, used -// during RLP serialization. -type metropolisReceiptRLP struct { - Status byte +type receiptStorageRLP struct { + PostStateOrStatus []byte CumulativeGasUsed *big.Int Bloom Bloom - Logs []*Log + TxHash common.Hash + ContractAddress common.Address + Logs []*LogForStorage + GasUsed *big.Int } // NewReceipt creates a barebone transaction receipt, copying the init fields. @@ -80,69 +81,46 @@ func NewReceipt(root []byte, failed bool, cumulativeGasUsed *big.Int) *Receipt { // EncodeRLP implements rlp.Encoder, and flattens the consensus fields of a receipt // into an RLP stream. If no post state is present, metropolis fork is assumed. func (r *Receipt) EncodeRLP(w io.Writer) error { - if r.PostState == nil { - status := receiptStatusSuccessful - if r.Failed { - status = receiptStatusFailed - } - return rlp.Encode(w, &metropolisReceiptRLP{status, r.CumulativeGasUsed, r.Bloom, r.Logs}) - } - return rlp.Encode(w, &homesteadReceiptRLP{r.PostState, r.CumulativeGasUsed, r.Bloom, r.Logs}) + return rlp.Encode(w, &receiptRLP{r.statusEncoding(), r.CumulativeGasUsed, r.Bloom, r.Logs}) } // DecodeRLP implements rlp.Decoder, and loads the consensus fields of a receipt // from an RLP stream. func (r *Receipt) DecodeRLP(s *rlp.Stream) error { - // Load the raw bytes since we have multiple possible formats - raw, err := s.Raw() - if err != nil { + var dec receiptRLP + if err := s.Decode(&dec); err != nil { return err } - content, _, err := rlp.SplitList(raw) - if err != nil { + if err := r.setStatus(dec.PostStateOrStatus); err != nil { return err } - kind, cnt, _, err := rlp.Split(content) - if err != nil { - return err - } - // Deserialize based on the first component type. + r.CumulativeGasUsed, r.Bloom, r.Logs = dec.CumulativeGasUsed, dec.Bloom, dec.Logs + return nil +} + +func (r *Receipt) setStatus(postStateOrStatus []byte) error { switch { - case kind == rlp.Byte || (kind == rlp.String && len(cnt) == 0): - // The first component of metropolis receipts is Byte (0x01), or the empty - // string (0x80, decoded as a byte with 0x00 value). - var metro metropolisReceiptRLP - if err := rlp.DecodeBytes(raw, &metro); err != nil { - return err - } - switch metro.Status { - case receiptStatusSuccessful: - r.Failed = false - case receiptStatusFailed: - r.Failed = true - default: - return fmt.Errorf("invalid status byte: 0x%x", metro.Status) - } - r.CumulativeGasUsed = metro.CumulativeGasUsed - r.Bloom = metro.Bloom - r.Logs = metro.Logs - return nil - - case kind == rlp.String: - // The first component of homestead receipts is non-empty String. - var home homesteadReceiptRLP - if err := rlp.DecodeBytes(raw, &home); err != nil { - return err - } - r.PostState = home.PostState[:] - r.CumulativeGasUsed = home.CumulativeGasUsed - r.Bloom = home.Bloom - r.Logs = home.Logs - return nil - + case bytes.Equal(postStateOrStatus, receiptStatusSuccessful): + r.Failed = false + case bytes.Equal(postStateOrStatus, receiptStatusFailed): + r.Failed = true + case len(postStateOrStatus) == len(common.Hash{}): + r.PostState = postStateOrStatus default: - return fmt.Errorf("invalid first receipt component: %v", kind) + return fmt.Errorf("invalid receipt status %x", postStateOrStatus) } + return nil +} + +func (r *Receipt) statusEncoding() []byte { + if len(r.PostState) == 0 { + if r.Failed { + return receiptStatusFailed + } else { + return receiptStatusSuccessful + } + } + return r.PostState } // String implements the Stringer interface. @@ -160,38 +138,39 @@ type ReceiptForStorage Receipt // EncodeRLP implements rlp.Encoder, and flattens all content fields of a receipt // into an RLP stream. func (r *ReceiptForStorage) EncodeRLP(w io.Writer) error { - logs := make([]*LogForStorage, len(r.Logs)) - for i, log := range r.Logs { - logs[i] = (*LogForStorage)(log) + enc := &receiptStorageRLP{ + PostStateOrStatus: (*Receipt)(r).statusEncoding(), + CumulativeGasUsed: r.CumulativeGasUsed, + Bloom: r.Bloom, + TxHash: r.TxHash, + ContractAddress: r.ContractAddress, + Logs: make([]*LogForStorage, len(r.Logs)), + GasUsed: r.GasUsed, } - return rlp.Encode(w, []interface{}{r.PostState, r.Failed, r.CumulativeGasUsed, r.Bloom, r.TxHash, r.ContractAddress, logs, r.GasUsed}) + for i, log := range r.Logs { + enc.Logs[i] = (*LogForStorage)(log) + } + return rlp.Encode(w, enc) } // DecodeRLP implements rlp.Decoder, and loads both consensus and implementation // fields of a receipt from an RLP stream. func (r *ReceiptForStorage) DecodeRLP(s *rlp.Stream) error { - var receipt struct { - PostState []byte - Failed bool - CumulativeGasUsed *big.Int - Bloom Bloom - TxHash common.Hash - ContractAddress common.Address - Logs []*LogForStorage - GasUsed *big.Int + var dec receiptStorageRLP + if err := s.Decode(&dec); err != nil { + return err } - if err := s.Decode(&receipt); err != nil { + if err := (*Receipt)(r).setStatus(dec.PostStateOrStatus); err != nil { return err } // Assign the consensus fields - r.PostState, r.Failed, r.CumulativeGasUsed, r.Bloom = receipt.PostState, receipt.Failed, receipt.CumulativeGasUsed, receipt.Bloom - r.Logs = make([]*Log, len(receipt.Logs)) - for i, log := range receipt.Logs { + r.CumulativeGasUsed, r.Bloom = dec.CumulativeGasUsed, dec.Bloom + r.Logs = make([]*Log, len(dec.Logs)) + for i, log := range dec.Logs { r.Logs[i] = (*Log)(log) } // Assign the implementation fields - r.TxHash, r.ContractAddress, r.GasUsed = receipt.TxHash, receipt.ContractAddress, receipt.GasUsed - + r.TxHash, r.ContractAddress, r.GasUsed = dec.TxHash, dec.ContractAddress, dec.GasUsed return nil } From 08f27428b4e97c339a220b7155ad13f4ef5a6767 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Fri, 25 Aug 2017 12:30:51 +0300 Subject: [PATCH 12/19] core, tests: implement Metropolis EIP 684 --- core/vm/errors.go | 11 ++++++----- core/vm/evm.go | 14 +++++++++++--- tests/state_test.go | 2 -- tests/testdata | 2 +- tests/vm_test.go | 1 - 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/core/vm/errors.go b/core/vm/errors.go index 69c7d6a98c..b19366be0e 100644 --- a/core/vm/errors.go +++ b/core/vm/errors.go @@ -19,9 +19,10 @@ package vm import "errors" var ( - ErrOutOfGas = errors.New("out of gas") - ErrCodeStoreOutOfGas = errors.New("contract creation code storage out of gas") - ErrDepth = errors.New("max call depth exceeded") - ErrTraceLimitReached = errors.New("the number of logs reached the specified limit") - ErrInsufficientBalance = errors.New("insufficient balance for transfer") + ErrOutOfGas = errors.New("out of gas") + ErrCodeStoreOutOfGas = errors.New("contract creation code storage out of gas") + ErrDepth = errors.New("max call depth exceeded") + ErrTraceLimitReached = errors.New("the number of logs reached the specified limit") + ErrInsufficientBalance = errors.New("insufficient balance for transfer") + ErrContractAddressCollision = errors.New("contract address collision") ) diff --git a/core/vm/evm.go b/core/vm/evm.go index 34933a1dc4..caf8b4507d 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -25,6 +25,10 @@ import ( "github.com/ethereum/go-ethereum/params" ) +// emptyCodeHash is used by create to ensure deployment is disallowed to already +// deployed contract addresses (relevant after the account abstraction). +var emptyCodeHash = crypto.Keccak256Hash(nil) + type ( CanTransferFunc func(StateDB, common.Address, *big.Int) bool TransferFunc func(StateDB, common.Address, common.Address, *big.Int) @@ -307,13 +311,17 @@ func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.I if !evm.CanTransfer(evm.StateDB, caller.Address(), value) { return nil, common.Address{}, gas, ErrInsufficientBalance } - - // Create a new account on the state + // Ensure there's no existing contract already at the designated address nonce := evm.StateDB.GetNonce(caller.Address()) evm.StateDB.SetNonce(caller.Address(), nonce+1) - snapshot := evm.StateDB.Snapshot() contractAddr = crypto.CreateAddress(caller.Address(), nonce) + contractHash := evm.StateDB.GetCodeHash(contractAddr) + if evm.StateDB.GetNonce(contractAddr) != 0 || (contractHash != (common.Hash{}) && contractHash != emptyCodeHash) { + return nil, common.Address{}, 0, ErrContractAddressCollision + } + // Create a new account on the state + snapshot := evm.StateDB.Snapshot() evm.StateDB.CreateAccount(contractAddr) if evm.ChainConfig().IsEIP158(evm.BlockNumber) { evm.StateDB.SetNonce(contractAddr, 1) diff --git a/tests/state_test.go b/tests/state_test.go index 00067c61ac..3d7b29012e 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -37,10 +37,8 @@ func TestState(t *testing.T) { // Expected failures: st.fails(`^stCodeSizeLimit/codesizeOOGInvalidSize\.json/(Frontier|Homestead|EIP150)`, "code size limit implementation is not conditional on fork") - st.fails(`^stRevertTest/RevertDepthCreateAddressCollision\.json/EIP15[08]/[67]`, "bug in test") st.fails(`^stRevertTest/RevertPrecompiledTouch\.json/EIP158`, "bug in test") st.fails(`^stRevertTest/RevertPrefoundEmptyOOG\.json/EIP158`, "bug in test") - st.fails(`^stRevertTest/RevertDepthCreateAddressCollision\.json/Byzantium/[67]`, "bug in test") st.fails(`^stRevertTest/RevertPrecompiledTouch\.json/Byzantium`, "bug in test") st.fails(`^stRevertTest/RevertPrefoundEmptyOOG\.json/Byzantium`, "bug in test") diff --git a/tests/testdata b/tests/testdata index cd2c3f1b3a..1d30b47956 160000 --- a/tests/testdata +++ b/tests/testdata @@ -1 +1 @@ -Subproject commit cd2c3f1b3acb98c0d1501b06a4a54629d8794d79 +Subproject commit 1d30b4795664f64b1b157971754e14a10cfd9115 diff --git a/tests/vm_test.go b/tests/vm_test.go index f35abeb110..c9f5e225e9 100644 --- a/tests/vm_test.go +++ b/tests/vm_test.go @@ -27,7 +27,6 @@ func TestVM(t *testing.T) { vmt := new(testMatcher) vmt.fails("^vmSystemOperationsTest.json/createNameRegistrator$", "fails without parallel execution") - vmt.skipLoad(`^vmPerformanceTest.json`) // log format broken vmt.skipLoad(`^vmInputLimits(Light)?.json`) // log format broken vmt.skipShortMode("^vmPerformanceTest.json") From ebf41d16a04420a3eba082cc0a1783c93caa1f86 Mon Sep 17 00:00:00 2001 From: Oli Bye Date: Fri, 25 Aug 2017 14:54:36 +0100 Subject: [PATCH 13/19] cmd/geth: fix --nousb typo (#15040) --- cmd/utils/flags.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index b257084719..37ccd06efb 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -120,7 +120,7 @@ var ( } NoUSBFlag = cli.BoolFlag{ Name: "nousb", - Usage: "Disables monitoring for and managine USB hardware wallets", + Usage: "Disables monitoring for and managing USB hardware wallets", } NetworkIdFlag = cli.Uint64Flag{ Name: "networkid", From bc2a5578c043f251387bb0b7200a7bf651cd7905 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Sun, 27 Aug 2017 14:00:32 +0200 Subject: [PATCH 14/19] core/vm: more benchmarks --- core/vm/contracts_test.go | 76 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/core/vm/contracts_test.go b/core/vm/contracts_test.go index 022070ab80..4ee8bbfd93 100644 --- a/core/vm/contracts_test.go +++ b/core/vm/contracts_test.go @@ -13,6 +13,7 @@ type precompiledTest struct { input, expected string gas uint64 name string + notForBenchmarking bool // Benchmark primarily the worst-cases } // modexpTests are the test and benchmark data for the modexp precompiled contract. @@ -182,6 +183,78 @@ var bn256ScalarMulTests = []precompiledTest{ input: "025a6f4181d2b4ea8b724290ffb40156eb0adb514c688556eb79cdea0752c2bb2eff3f31dea215f1eb86023a133a996eb6300b44da664d64251d05381bb8a02e183227397098d014dc2822db40c0ac2ecbc0b548b438e5469e10460b6c3e7ea3", expected: "14789d0d4a730b354403b5fac948113739e276c23e0258d8596ee72f9cd9d3230af18a63153e0ec25ff9f2951dd3fa90ed0197bfef6e2a1a62b5095b9d2b4a27", name: "chfast3", + },{ + input: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + expected: "2cde5879ba6f13c0b5aa4ef627f159a3347df9722efce88a9afbb20b763b4c411aa7e43076f6aee272755a7f9b84832e71559ba0d2e0b17d5f9f01755e5b0d11", + name : "cdetrio1", + },{ + input: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f630644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000", + expected: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe3163511ddc1c3f25d396745388200081287b3fd1472d8339d5fecb2eae0830451", + name : "cdetrio2", + notForBenchmarking:true, + },{ + input: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000100000000000000000000000000000000", + expected: "1051acb0700ec6d42a88215852d582efbaef31529b6fcbc3277b5c1b300f5cf0135b2394bb45ab04b8bd7611bd2dfe1de6a4e6e2ccea1ea1955f577cd66af85b", + name : "cdetrio3", + notForBenchmarking:true, + },{ + input: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000000000000000000000000000000000009", + expected: "1dbad7d39dbc56379f78fac1bca147dc8e66de1b9d183c7b167351bfe0aeab742cd757d51289cd8dbd0acf9e673ad67d0f0a89f912af47ed1be53664f5692575", + name : "cdetrio4", + notForBenchmarking:true, + },{ + input: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000000000000000000000000000000000001", + expected: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f6", + name : "cdetrio5", + notForBenchmarking:true, + },{ + input: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + expected: "29e587aadd7c06722aabba753017c093f70ba7eb1f1c0104ec0564e7e3e21f6022b1143f6a41008e7755c71c3d00b6b915d386de21783ef590486d8afa8453b1", + name : "cdetrio6", + },{ + input: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000", + expected: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa92e83f8d734803fc370eba25ed1f6b8768bd6d83887b87165fc2434fe11a830cb", + name : "cdetrio7", + notForBenchmarking:true, + },{ + input: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000100000000000000000000000000000000", + expected: "221a3577763877920d0d14a91cd59b9479f83b87a653bb41f82a3f6f120cea7c2752c7f64cdd7f0e494bff7b60419f242210f2026ed2ec70f89f78a4c56a1f15", + name : "cdetrio8", + notForBenchmarking:true, + },{ + input: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000000000000000000000000000000000009", + expected: "228e687a379ba154554040f8821f4e41ee2be287c201aa9c3bc02c9dd12f1e691e0fd6ee672d04cfd924ed8fdc7ba5f2d06c53c1edc30f65f2af5a5b97f0a76a", + name : "cdetrio9", + notForBenchmarking:true, + },{ + input: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000000000000000000000000000000000001", + expected: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c", + name : "cdetrio10", + notForBenchmarking:true, + },{ + input: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + expected: "00a1a234d08efaa2616607e31eca1980128b00b415c845ff25bba3afcb81dc00242077290ed33906aeb8e42fd98c41bcb9057ba03421af3f2d08cfc441186024", + name : "cdetrio11", + },{ + input: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d9830644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000", + expected: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b8692929ee761a352600f54921df9bf472e66217e7bb0cee9032e00acc86b3c8bfaf", + name : "cdetrio12", + notForBenchmarking:true, + },{ + input: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000100000000000000000000000000000000", + expected: "1071b63011e8c222c5a771dfa03c2e11aac9666dd097f2c620852c3951a4376a2f46fe2f73e1cf310a168d56baa5575a8319389d7bfa6b29ee2d908305791434", + name : "cdetrio13", + notForBenchmarking:true, + },{ + input: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000000000000000000000000000000000009", + expected: "19f75b9dd68c080a688774a6213f131e3052bd353a304a189d7a2ee367e3c2582612f545fb9fc89fde80fd81c68fc7dcb27fea5fc124eeda69433cf5c46d2d7f", + name : "cdetrio14", + notForBenchmarking:true, + },{ + input: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98000000000000000000000000000000000000000000000000000000000000000", + expected: "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + name : "cdetrio15", + notForBenchmarking:true, }, } @@ -262,6 +335,9 @@ func testPrecompiled(addr string, test precompiledTest, t *testing.T) { } func benchmarkPrecompiled(addr string, test precompiledTest, bench *testing.B) { + if test.notForBenchmarking{ + return + } p := PrecompiledContractsMetropolis[common.HexToAddress(addr)] in := common.Hex2Bytes(test.input) reqGas := p.RequiredGas(in) From a4df80f47f2ac6e70c0be242ccec54aef7777115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Mon, 28 Aug 2017 11:15:29 +0300 Subject: [PATCH 15/19] travis, appveyor: bump Go to 1.9 stable --- .travis.yml | 26 +++++++++++++++++++------- appveyor.yml | 4 ++-- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 703ed0cb1d..a972668c95 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,11 +15,23 @@ matrix: - go run build/ci.go install - go run build/ci.go test -coverage - # These are the latest Go versions. - os: linux dist: trusty sudo: required go: 1.8.3 + script: + - sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install fuse + - sudo modprobe fuse + - sudo chmod 666 /dev/fuse + - sudo chown root:$USER /etc/fuse.conf + - go run build/ci.go install + - go run build/ci.go test -coverage + + # These are the latest Go versions. + - os: linux + dist: trusty + sudo: required + go: 1.9.0 script: - sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install fuse - sudo modprobe fuse @@ -29,7 +41,7 @@ matrix: - go run build/ci.go test -coverage -misspell - os: osx - go: 1.8.3 + go: 1.9.0 sudo: required script: - brew update @@ -42,7 +54,7 @@ matrix: - os: linux dist: trusty sudo: required - go: 1.8.3 + go: 1.9.0 env: - ubuntu-ppa - azure-linux @@ -81,7 +93,7 @@ matrix: sudo: required services: - docker - go: 1.8.3 + go: 1.9.0 env: - azure-linux-mips script: @@ -121,7 +133,7 @@ matrix: - azure-android - maven-android before_install: - - curl https://storage.googleapis.com/golang/go1.8.3.linux-amd64.tar.gz | tar -xz + - curl https://storage.googleapis.com/golang/go1.9.linux-amd64.tar.gz | tar -xz - export PATH=`pwd`/go/bin:$PATH - export GOROOT=`pwd`/go - export GOPATH=$HOME/go @@ -138,7 +150,7 @@ matrix: # This builder does the OSX Azure, iOS CocoaPods and iOS Azure uploads - os: osx - go: 1.8.3 + go: 1.9.0 env: - azure-osx - azure-ios @@ -164,7 +176,7 @@ matrix: - os: linux dist: trusty sudo: required - go: 1.8.3 + go: 1.9.0 env: - azure-purge script: diff --git a/appveyor.yml b/appveyor.yml index 945cafaf2e..78b11fa9d6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -23,8 +23,8 @@ environment: install: - git submodule update --init - rmdir C:\go /s /q - - appveyor DownloadFile https://storage.googleapis.com/golang/go1.8.3.windows-%GETH_ARCH%.zip - - 7z x go1.8.3.windows-%GETH_ARCH%.zip -y -oC:\ > NUL + - appveyor DownloadFile https://storage.googleapis.com/golang/go1.9.windows-%GETH_ARCH%.zip + - 7z x go1.9.windows-%GETH_ARCH%.zip -y -oC:\ > NUL - go version - gcc --version From 64a3a3d23c745b934ca0d2a5dda98c826c7d064c Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Mon, 28 Aug 2017 13:30:26 +0200 Subject: [PATCH 16/19] core/vm: Fix testcase input for ecmul --- core/vm/contracts_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/vm/contracts_test.go b/core/vm/contracts_test.go index 4ee8bbfd93..0c6ae9ac6b 100644 --- a/core/vm/contracts_test.go +++ b/core/vm/contracts_test.go @@ -251,8 +251,8 @@ var bn256ScalarMulTests = []precompiledTest{ name : "cdetrio14", notForBenchmarking:true, },{ - input: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98000000000000000000000000000000000000000000000000000000000000000", - expected: "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + input: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000000000000000000000000000000000001", + expected: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98", name : "cdetrio15", notForBenchmarking:true, }, From 07635e43e28260b4523cc8e77006f54d237a8a8d Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Mon, 28 Aug 2017 13:33:24 +0200 Subject: [PATCH 17/19] core/vm: renamed struct member + go fmt --- core/vm/contracts_test.go | 142 +++++++++++++++++++------------------- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/core/vm/contracts_test.go b/core/vm/contracts_test.go index 0c6ae9ac6b..880d7324ae 100644 --- a/core/vm/contracts_test.go +++ b/core/vm/contracts_test.go @@ -13,7 +13,7 @@ type precompiledTest struct { input, expected string gas uint64 name string - notForBenchmarking bool // Benchmark primarily the worst-cases + noBenchmark bool // Benchmark primarily the worst-cases } // modexpTests are the test and benchmark data for the modexp precompiled contract. @@ -183,78 +183,78 @@ var bn256ScalarMulTests = []precompiledTest{ input: "025a6f4181d2b4ea8b724290ffb40156eb0adb514c688556eb79cdea0752c2bb2eff3f31dea215f1eb86023a133a996eb6300b44da664d64251d05381bb8a02e183227397098d014dc2822db40c0ac2ecbc0b548b438e5469e10460b6c3e7ea3", expected: "14789d0d4a730b354403b5fac948113739e276c23e0258d8596ee72f9cd9d3230af18a63153e0ec25ff9f2951dd3fa90ed0197bfef6e2a1a62b5095b9d2b4a27", name: "chfast3", - },{ - input: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + }, { + input: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", expected: "2cde5879ba6f13c0b5aa4ef627f159a3347df9722efce88a9afbb20b763b4c411aa7e43076f6aee272755a7f9b84832e71559ba0d2e0b17d5f9f01755e5b0d11", - name : "cdetrio1", - },{ - input: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f630644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000", - expected: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe3163511ddc1c3f25d396745388200081287b3fd1472d8339d5fecb2eae0830451", - name : "cdetrio2", - notForBenchmarking:true, - },{ - input: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000100000000000000000000000000000000", - expected: "1051acb0700ec6d42a88215852d582efbaef31529b6fcbc3277b5c1b300f5cf0135b2394bb45ab04b8bd7611bd2dfe1de6a4e6e2ccea1ea1955f577cd66af85b", - name : "cdetrio3", - notForBenchmarking:true, - },{ - input: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000000000000000000000000000000000009", - expected: "1dbad7d39dbc56379f78fac1bca147dc8e66de1b9d183c7b167351bfe0aeab742cd757d51289cd8dbd0acf9e673ad67d0f0a89f912af47ed1be53664f5692575", - name : "cdetrio4", - notForBenchmarking:true, - },{ - input: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000000000000000000000000000000000001", - expected: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f6", - name : "cdetrio5", - notForBenchmarking:true, - },{ - input: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + name: "cdetrio1", + }, { + input: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f630644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000", + expected: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe3163511ddc1c3f25d396745388200081287b3fd1472d8339d5fecb2eae0830451", + name: "cdetrio2", + noBenchmark: true, + }, { + input: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000100000000000000000000000000000000", + expected: "1051acb0700ec6d42a88215852d582efbaef31529b6fcbc3277b5c1b300f5cf0135b2394bb45ab04b8bd7611bd2dfe1de6a4e6e2ccea1ea1955f577cd66af85b", + name: "cdetrio3", + noBenchmark: true, + }, { + input: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000000000000000000000000000000000009", + expected: "1dbad7d39dbc56379f78fac1bca147dc8e66de1b9d183c7b167351bfe0aeab742cd757d51289cd8dbd0acf9e673ad67d0f0a89f912af47ed1be53664f5692575", + name: "cdetrio4", + noBenchmark: true, + }, { + input: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000000000000000000000000000000000001", + expected: "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f6", + name: "cdetrio5", + noBenchmark: true, + }, { + input: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", expected: "29e587aadd7c06722aabba753017c093f70ba7eb1f1c0104ec0564e7e3e21f6022b1143f6a41008e7755c71c3d00b6b915d386de21783ef590486d8afa8453b1", - name : "cdetrio6", - },{ - input: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000", - expected: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa92e83f8d734803fc370eba25ed1f6b8768bd6d83887b87165fc2434fe11a830cb", - name : "cdetrio7", - notForBenchmarking:true, - },{ - input: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000100000000000000000000000000000000", - expected: "221a3577763877920d0d14a91cd59b9479f83b87a653bb41f82a3f6f120cea7c2752c7f64cdd7f0e494bff7b60419f242210f2026ed2ec70f89f78a4c56a1f15", - name : "cdetrio8", - notForBenchmarking:true, - },{ - input: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000000000000000000000000000000000009", - expected: "228e687a379ba154554040f8821f4e41ee2be287c201aa9c3bc02c9dd12f1e691e0fd6ee672d04cfd924ed8fdc7ba5f2d06c53c1edc30f65f2af5a5b97f0a76a", - name : "cdetrio9", - notForBenchmarking:true, - },{ - input: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000000000000000000000000000000000001", - expected: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c", - name : "cdetrio10", - notForBenchmarking:true, - },{ - input: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + name: "cdetrio6", + }, { + input: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000", + expected: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa92e83f8d734803fc370eba25ed1f6b8768bd6d83887b87165fc2434fe11a830cb", + name: "cdetrio7", + noBenchmark: true, + }, { + input: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000100000000000000000000000000000000", + expected: "221a3577763877920d0d14a91cd59b9479f83b87a653bb41f82a3f6f120cea7c2752c7f64cdd7f0e494bff7b60419f242210f2026ed2ec70f89f78a4c56a1f15", + name: "cdetrio8", + noBenchmark: true, + }, { + input: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000000000000000000000000000000000009", + expected: "228e687a379ba154554040f8821f4e41ee2be287c201aa9c3bc02c9dd12f1e691e0fd6ee672d04cfd924ed8fdc7ba5f2d06c53c1edc30f65f2af5a5b97f0a76a", + name: "cdetrio9", + noBenchmark: true, + }, { + input: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000000000000000000000000000000000001", + expected: "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c", + name: "cdetrio10", + noBenchmark: true, + }, { + input: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", expected: "00a1a234d08efaa2616607e31eca1980128b00b415c845ff25bba3afcb81dc00242077290ed33906aeb8e42fd98c41bcb9057ba03421af3f2d08cfc441186024", - name : "cdetrio11", - },{ - input: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d9830644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000", - expected: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b8692929ee761a352600f54921df9bf472e66217e7bb0cee9032e00acc86b3c8bfaf", - name : "cdetrio12", - notForBenchmarking:true, - },{ - input: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000100000000000000000000000000000000", - expected: "1071b63011e8c222c5a771dfa03c2e11aac9666dd097f2c620852c3951a4376a2f46fe2f73e1cf310a168d56baa5575a8319389d7bfa6b29ee2d908305791434", - name : "cdetrio13", - notForBenchmarking:true, - },{ - input: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000000000000000000000000000000000009", - expected: "19f75b9dd68c080a688774a6213f131e3052bd353a304a189d7a2ee367e3c2582612f545fb9fc89fde80fd81c68fc7dcb27fea5fc124eeda69433cf5c46d2d7f", - name : "cdetrio14", - notForBenchmarking:true, - },{ - input: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000000000000000000000000000000000001", - expected: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98", - name : "cdetrio15", - notForBenchmarking:true, + name: "cdetrio11", + }, { + input: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d9830644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000", + expected: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b8692929ee761a352600f54921df9bf472e66217e7bb0cee9032e00acc86b3c8bfaf", + name: "cdetrio12", + noBenchmark: true, + }, { + input: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000100000000000000000000000000000000", + expected: "1071b63011e8c222c5a771dfa03c2e11aac9666dd097f2c620852c3951a4376a2f46fe2f73e1cf310a168d56baa5575a8319389d7bfa6b29ee2d908305791434", + name: "cdetrio13", + noBenchmark: true, + }, { + input: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000000000000000000000000000000000009", + expected: "19f75b9dd68c080a688774a6213f131e3052bd353a304a189d7a2ee367e3c2582612f545fb9fc89fde80fd81c68fc7dcb27fea5fc124eeda69433cf5c46d2d7f", + name: "cdetrio14", + noBenchmark: true, + }, { + input: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000000000000000000000000000000000001", + expected: "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98", + name: "cdetrio15", + noBenchmark: true, }, } @@ -335,7 +335,7 @@ func testPrecompiled(addr string, test precompiledTest, t *testing.T) { } func benchmarkPrecompiled(addr string, test precompiledTest, bench *testing.B) { - if test.notForBenchmarking{ + if test.noBenchmark { return } p := PrecompiledContractsMetropolis[common.HexToAddress(addr)] From d2735955d98c6d9317711c0d789b2d6a35294639 Mon Sep 17 00:00:00 2001 From: nkbai Date: Fri, 1 Sep 2017 16:37:26 +0800 Subject: [PATCH 18/19] accounts/abi: on windows,empty filename always generate error: "Failed to generate ABI binding: The filename, directory name, or volume label syntax is incorrect." because package imports need to get filename's path. --- accounts/abi/bind/bind.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index 73e95e02a1..f587580884 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -122,7 +122,7 @@ func Bind(types []string, abis []string, bytecodes []string, pkg string, lang La } // For Go bindings pass the code through goimports to clean it up and double check if lang == LangGo { - code, err := imports.Process("", buffer.Bytes(), nil) + code, err := imports.Process(".", buffer.Bytes(), nil) if err != nil { return "", fmt.Errorf("%v\n%s", err, buffer) } From 08df44159100b4e4da4e19623af124e89e15d471 Mon Sep 17 00:00:00 2001 From: nkbai Date: Tue, 5 Sep 2017 21:30:24 +0800 Subject: [PATCH 19/19] accounts/abi: binding test always failure on windows because of wrong arguments of imports.Process. --- accounts/abi/bind/bind_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index 8ea3eca415..43ed53b922 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -459,7 +459,7 @@ func TestBindings(t *testing.T) { } // Skip the test if the go-ethereum sources are symlinked (https://github.com/golang/go/issues/14845) linkTestCode := fmt.Sprintf("package linktest\nfunc CheckSymlinks(){\nfmt.Println(backends.NewSimulatedBackend(nil))\n}") - linkTestDeps, err := imports.Process("", []byte(linkTestCode), nil) + linkTestDeps, err := imports.Process(os.TempDir(), []byte(linkTestCode), nil) if err != nil { t.Fatalf("failed check for goimports symlink bug: %v", err) }