Skip to content

Commit

Permalink
Merge pull request ethereum#100 from multi-geth/sp-update-upstream-20…
Browse files Browse the repository at this point in the history
…190611

Update upstream to HEAD 2b54666
  • Loading branch information
sorpaas authored Jun 11, 2019
2 parents 6148a5d + 18c5098 commit f9b25e0
Show file tree
Hide file tree
Showing 811 changed files with 35,989 additions and 133,392 deletions.
10 changes: 3 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,8 @@ matrix:
# These are the latest Go versions.
- os: linux
dist: xenial
sudo: required
go: 1.11.x
go: 1.12.x
script:
- sudo modprobe fuse
- sudo chmod 666 /dev/fuse
- sudo chown root:$USER /etc/fuse.conf
- go run build/ci.go install
- travis_wait 60 go run build/ci.go test
before_deploy:
Expand All @@ -30,7 +26,7 @@ matrix:
tag_name: "$TRAVIS_TAG"

- os: osx
go: 1.11.x
go: 1.12.x
script:
- echo "Increase the maximum number of open file descriptors on macOS"
- NOFILE=20480
Expand Down Expand Up @@ -60,7 +56,7 @@ matrix:
# This builder only tests code linters on latest version of Go
- os: linux
dist: xenial
go: 1.11.x
go: 1.12.x
env:
- lint
git:
Expand Down
10 changes: 1 addition & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# with Go source code. If you know what GOPATH is then you probably
# don't need to bother with make.

.PHONY: geth android ios geth-cross swarm evm all test clean
.PHONY: geth android ios geth-cross evm all test clean
.PHONY: geth-linux geth-linux-386 geth-linux-amd64 geth-linux-mips64 geth-linux-mips64le
.PHONY: geth-linux-arm geth-linux-arm-5 geth-linux-arm-6 geth-linux-arm-7 geth-linux-arm64
.PHONY: geth-darwin geth-darwin-386 geth-darwin-amd64
Expand All @@ -16,11 +16,6 @@ geth:
@echo "Done building."
@echo "Run \"$(GOBIN)/geth\" to launch geth."

swarm:
build/env.sh go run build/ci.go install ./cmd/swarm
@echo "Done building."
@echo "Run \"$(GOBIN)/swarm\" to launch swarm."

all:
build/env.sh go run build/ci.go install

Expand Down Expand Up @@ -57,9 +52,6 @@ devtools:
@type "solc" 2> /dev/null || echo 'Please install solc'
@type "protoc" 2> /dev/null || echo 'Please install protoc'

swarm-devtools:
env GOBIN= go install ./cmd/swarm/mimegen

# Cross Compilation Targets (xgo)

geth-cross: geth-linux geth-darwin geth-windows geth-android geth-ios
Expand Down
42 changes: 35 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ The go-ethereum project comes with several wrappers/executables found in the `cm
| `evm` | Developer utility version of the EVM (Ethereum Virtual Machine) that is capable of running bytecode snippets within a configurable environment and execution mode. Its purpose is to allow isolated, fine-grained debugging of EVM opcodes (e.g. `evm --code 60ff60ff --debug`). |
| `gethrpctest` | Developer utility tool to support our [ethereum/rpc-test](https://github.com/ethereum/rpc-tests) test suite which validates baseline conformity to the [Ethereum JSON RPC](https://github.com/ethereum/wiki/wiki/JSON-RPC) specs. Please see the [test suite's readme](https://github.com/ethereum/rpc-tests/blob/master/README.md) for details. |
| `rlpdump` | Developer utility tool to convert binary RLP ([Recursive Length Prefix](https://github.com/ethereum/wiki/wiki/RLP)) dumps (data encoding used by the Ethereum protocol both network as well as consensus wise) to user-friendlier hierarchical representation (e.g. `rlpdump --hex CE0183FFFFFFC4C304050583616263`). |
| `swarm` | Swarm daemon and tools. This is the entry point for the Swarm network. `swarm --help` for command line options and subcommands. See [Swarm README](https://github.com/ethereum/go-ethereum/tree/master/swarm) for more information. |
| `puppeth` | a CLI wizard that aids in creating a new Ethereum network. |


## Running geth

Going through all the possible command line flags is out of scope here (please consult our
Expand Down Expand Up @@ -133,12 +133,40 @@ This command will:
(via the trailing `console` subcommand) through which you can invoke all official [`web3` methods](https://github.com/ethereum/wiki/wiki/JavaScript-API)
as well as Geth's own [management APIs](https://github.com/ethereum/go-ethereum/wiki/Management-APIs).
This tool is optional and if you leave it out you can always attach to an already running Geth instance
with `geth attach`.
> To keep the shell clear of event logs while interacting with the JS console, you
> can append `2> stderr.log`, which will redirect the normal stderr log lines to a file for later reference, while
> keeping the console and it's output (on stdout) visible in the shell.
### Full archive node on an Ethereum network
with `geth attach`.

### A Full node on the Ethereum test network

Transitioning towards developers, if you'd like to play around with creating Ethereum contracts, you
almost certainly would like to do that without any real money involved until you get the hang of the
entire system. In other words, instead of attaching to the main network, you want to join the **test**
network with your node, which is fully equivalent to the main network, but with play-Ether only.

```
$ geth --testnet console
```

The `console` subcommand has the exact same meaning as above and they are equally useful on the
testnet too. Please see above for their explanations if you've skipped here.

Specifying the `--testnet` flag, however, will reconfigure your Geth instance a bit:

* Instead of using the default data directory (`~/.ethereum` on Linux for example), Geth will nest
itself one level deeper into a `testnet` subfolder (`~/.ethereum/testnet` on Linux). Note, on OSX
and Linux this also means that attaching to a running testnet node requires the use of a custom
endpoint since `geth attach` will try to attach to a production node endpoint by default. E.g.
`geth attach <datadir>/testnet/geth.ipc`. Windows users are not affected by this.
* Instead of connecting the main Ethereum network, the client will connect to the test network,
which uses different P2P bootnodes, different network IDs and genesis states.

*Note: Although there are some internal protective measures to prevent transactions from crossing
over between the main network and test network, you should make sure to always use separate accounts
for play-money and real-money. Unless you manually move accounts, Geth will by default correctly
separate the two networks and will not make any accounts available between them.*

### Full node on the Rinkeby test network

The above test network is a cross-client one based on the ethash proof-of-work consensus algorithm. As such, it has certain extra overhead and is more susceptible to reorganization attacks due to the network's low difficulty/security. Go Ethereum also supports connecting to a proof-of-authority based test network called [*Rinkeby*](https://www.rinkeby.io) (operated by members of the community). This network is lighter, more secure, but is only supported by go-ethereum.

```
$ geth [|--<chain>] --syncmode=full --gcmode=archive
Expand Down
2 changes: 1 addition & 1 deletion accounts/abi/abi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,7 @@ func TestUnpackMethodIntoMap(t *testing.T) {
if err = abi.UnpackIntoMap(getMap, "get", data); err != nil {
t.Error(err)
}
if len(sendMap) != 1 {
if len(getMap) != 1 {
t.Error("unpacked `get` map expected to have length 1")
}
expectedBytes := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 88, 0}
Expand Down
19 changes: 19 additions & 0 deletions accounts/abi/bind/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"io"
"io/ioutil"

"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
Expand All @@ -42,6 +43,24 @@ func NewTransactor(keyin io.Reader, passphrase string) (*TransactOpts, error) {
return NewKeyedTransactor(key.PrivateKey), nil
}

// NewTransactor is a utility method to easily create a transaction signer from
// an decrypted key from a keystore
func NewTransactorFromKeyStore(keystore *keystore.KeyStore, account accounts.Account) (*TransactOpts, error) {
return &TransactOpts{
From: account.Address,
Signer: func(signer types.Signer, address common.Address, tx *types.Transaction) (*types.Transaction, error) {
if address != account.Address {
return nil, errors.New("not authorized to sign this account")
}
signature, err := keystore.SignHash(account, signer.Hash(tx).Bytes())
if err != nil {
return nil, err
}
return tx.WithSignature(signer, signature)
},
}, nil
}

// NewKeyedTransactor is a utility method to easily create a transaction signer
// from a single private key.
func NewKeyedTransactor(key *ecdsa.PrivateKey) *TransactOpts {
Expand Down
2 changes: 1 addition & 1 deletion accounts/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ type Account struct {
}

const (
MimetypeTextWithValidator = "text/validator"
MimetypeDataWithValidator = "data/validator"
MimetypeTypedData = "data/typed"
MimetypeClique = "application/x-clique-header"
MimetypeTextPlain = "text/plain"
Expand Down
2 changes: 1 addition & 1 deletion accounts/keystore/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

// +build darwin,!ios freebsd linux,!arm64 netbsd solaris
// +build darwin,!ios,cgo freebsd linux,!arm64 netbsd solaris

package keystore

Expand Down
2 changes: 1 addition & 1 deletion accounts/keystore/watch_fallback.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

// +build ios linux,arm64 windows !darwin,!freebsd,!linux,!netbsd,!solaris
// +build darwin,!cgo ios linux,arm64 windows !darwin,!freebsd,!linux,!netbsd,!solaris

// This is the fallback implementation of directory watching.
// It is used on unsupported platforms.
Expand Down
20 changes: 10 additions & 10 deletions accounts/scwallet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@
Start `geth` with the `console` command. You will notice the following warning:

```
WARN [04-09|16:58:38.898] Failed to open wallet url=pcsc://044def09 err="smartcard: pairing password needed"
WARN [04-09|16:58:38.898] Failed to open wallet url=keycard://044def09 err="smartcard: pairing password needed"
```

Write down the URL (`pcsc://044def09` in this example). Then ask `geth` to open the wallet:
Write down the URL (`keycard://044def09` in this example). Then ask `geth` to open the wallet:

```
> personal.openWallet("pcsc://044def09")
> personal.openWallet("keycard://044def09")
Please enter the pairing password:
```

Expand All @@ -42,12 +42,12 @@

```
> personal
WARN [04-09|17:02:07.330] Smartcard wallet account derivation failed url=pcsc://044def09 err="Unexpected response status Cla=0x80, Ins=0xd1, Sw=0x6985"
WARN [04-09|17:02:07.330] Smartcard wallet account derivation failed url=keycard://044def09 err="Unexpected response status Cla=0x80, Ins=0xd1, Sw=0x6985"
{
listAccounts: [],
listWallets: [{
status: "Empty, waiting for initialization",
url: "pcsc://044def09"
url: "keycard://044def09"
}],
...
}
Expand All @@ -56,7 +56,7 @@
So the communication with the card is working, but there is no key associated with this wallet. Let's create it:

```
> personal.initializeWallet("pcsc://044def09")
> personal.initializeWallet("keycard://044def09")
"tilt ... impact"
```

Expand All @@ -67,10 +67,10 @@
[{
accounts: [{
address: "0x678b7cd55c61917defb23546a41803c5bfefbc7a",
url: "pcsc://044d/m/44'/60'/0'/0/0"
url: "keycard://044d/m/44'/60'/0'/0/0"
}],
status: "Online",
url: "pcsc://044def09"
url: "keycard://044def09"
}]
```

Expand All @@ -84,14 +84,14 @@
```
listWallets: [{
status: "Online, can derive public keys",
url: "pcsc://a4d73015"
url: "keycard://a4d73015"
}]
```

3. Open the wallet, you will be prompted for your pairing password, then PIN:

```
personal.openWallet("pcsc://a4d73015")
personal.openWallet("keycard://a4d73015")
```

4. Check that creation was successful by typing e.g. `personal`. Then use it like a regular wallet.
Expand Down
6 changes: 3 additions & 3 deletions accounts/scwallet/hub.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import (
)

// Scheme is the URI prefix for smartcard wallets.
const Scheme = "pcsc"
const Scheme = "keycard"

// refreshCycle is the maximum time between wallet refreshes (if USB hotplug
// notifications don't work).
Expand Down Expand Up @@ -152,8 +152,8 @@ func (hub *Hub) setPairing(wallet *Wallet, pairing *smartcardPairing) error {
}

// NewHub creates a new hardware wallet manager for smartcards.
func NewHub(scheme string, datadir string) (*Hub, error) {
context, err := pcsc.EstablishContext(pcsc.ScopeSystem)
func NewHub(daemonPath string, scheme string, datadir string) (*Hub, error) {
context, err := pcsc.EstablishContext(daemonPath, pcsc.ScopeSystem)
if err != nil {
return nil, err
}
Expand Down
50 changes: 25 additions & 25 deletions accounts/scwallet/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"errors"
"fmt"
"math/big"
"regexp"
"sort"
"strings"
"sync"
Expand All @@ -37,7 +38,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
"github.com/ethereum/go-ethereum/log"
pcsc "github.com/gballet/go-libpcsclite"
"github.com/status-im/keycard-go/derivationpath"
Expand Down Expand Up @@ -311,8 +311,10 @@ func (w *Wallet) Status() (string, error) {
return fmt.Sprintf("Failed: %v", err), err
}
switch {
case !w.session.verified && status.PinRetryCount == 0 && status.PukRetryCount == 0:
return fmt.Sprintf("Bricked, waiting for full wipe"), nil
case !w.session.verified && status.PinRetryCount == 0:
return fmt.Sprintf("Blocked, waiting for PUK and new PIN"), nil
return fmt.Sprintf("Blocked, waiting for PUK (%d attempts left) and new PIN", status.PukRetryCount), nil
case !w.session.verified:
return fmt.Sprintf("Locked, waiting for PIN (%d attempts left)", status.PinRetryCount), nil
case !status.Initialized:
Expand Down Expand Up @@ -378,10 +380,18 @@ func (w *Wallet) Open(passphrase string) error {
case passphrase == "":
return ErrPINUnblockNeeded
case status.PinRetryCount > 0:
if !regexp.MustCompile(`^[0-9]{6,}$`).MatchString(passphrase) {
w.log.Error("PIN needs to be at least 6 digits")
return ErrPINNeeded
}
if err := w.session.verifyPin([]byte(passphrase)); err != nil {
return err
}
default:
if !regexp.MustCompile(`^[0-9]{12,}$`).MatchString(passphrase) {
w.log.Error("PUK needs to be at least 12 digits")
return ErrPINUnblockNeeded
}
if err := w.session.unblockPin([]byte(passphrase)); err != nil {
return err
}
Expand Down Expand Up @@ -972,12 +982,10 @@ func (s *Session) derive(path accounts.DerivationPath) (accounts.Account, error)
copy(sig[32-len(rbytes):32], rbytes)
copy(sig[64-len(sbytes):64], sbytes)

pubkey, err := determinePublicKey(sig, sigdata.PublicKey)
if err != nil {
if err := confirmPublicKey(sig, sigdata.PublicKey); err != nil {
return accounts.Account{}, err
}

pub, err := crypto.UnmarshalPubkey(pubkey)
pub, err := crypto.UnmarshalPubkey(sigdata.PublicKey)
if err != nil {
return accounts.Account{}, err
}
Expand Down Expand Up @@ -1047,36 +1055,28 @@ func (s *Session) sign(path accounts.DerivationPath, hash []byte) ([]byte, error
return sig, nil
}

// determinePublicKey uses a signature and the X component of a public key to
// recover the entire public key.
func determinePublicKey(sig, pubkeyX []byte) ([]byte, error) {
for v := 0; v < 2; v++ {
sig[64] = byte(v)
pubkey, err := crypto.Ecrecover(DerivationSignatureHash[:], sig)
if err == nil {
if bytes.Equal(pubkey, pubkeyX) {
return pubkey, nil
}
} else if v == 1 || err != secp256k1.ErrRecoverFailed {
return nil, err
}
}
return nil, ErrPubkeyMismatch
// confirmPublicKey confirms that the given signature belongs to the specified key.
func confirmPublicKey(sig, pubkey []byte) error {
_, err := makeRecoverableSignature(DerivationSignatureHash[:], sig, pubkey)
return err
}

// makeRecoverableSignature uses a signature and an expected public key to
// recover the v value and produce a recoverable signature.
func makeRecoverableSignature(hash, sig, expectedPubkey []byte) ([]byte, error) {
var libraryError error
for v := 0; v < 2; v++ {
sig[64] = byte(v)
pubkey, err := crypto.Ecrecover(hash, sig)
if err == nil {
if pubkey, err := crypto.Ecrecover(hash, sig); err == nil {
if bytes.Equal(pubkey, expectedPubkey) {
return sig, nil
}
} else if v == 1 || err != secp256k1.ErrRecoverFailed {
return nil, err
} else {
libraryError = err
}
}
if libraryError != nil {
return nil, libraryError
}
return nil, ErrPubkeyMismatch
}
Loading

0 comments on commit f9b25e0

Please sign in to comment.