diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index a332b815d094..72dee4361bae 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -2,7 +2,7 @@
Before you do a feature request please check and make sure that it isn't possible
through some other means. The JavaScript enabled console is a powerful feature
-in the right hands. Please check our [Bitchin' tricks](https://github.com/ethereum/go-ethereum/wiki/bitchin-tricks) wiki page for more info
+in the right hands. Please check our [Bitchin' tricks](https://github.com/teamnsrg/ethereum-p2p/wiki/bitchin-tricks) wiki page for more info
and help.
## Contributing
@@ -11,6 +11,6 @@ If you'd like to contribute to go-ethereum please fork, fix, commit and
send a pull request. Commits which do not comply with the coding standards
are ignored (use gofmt!).
-See [Developers' Guide](https://github.com/ethereum/go-ethereum/wiki/Developers'-Guide)
+See [Developers' Guide](https://github.com/teamnsrg/ethereum-p2p/wiki/Developers'-Guide)
for more details on configuring your environment, testing, and
dependency management.
diff --git a/.travis.yml b/.travis.yml
index 1bd69da347af..7eab1b1e217a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,210 +1,85 @@
language: go
-go_import_path: github.com/ethereum/go-ethereum
+go_import_path: github.com/teamnsrg/ethereum-p2p
sudo: false
matrix:
include:
- - os: linux
- dist: trusty
- sudo: required
- go: 1.7.x
- 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
-
- - os: linux
- dist: trusty
- sudo: required
- go: 1.8.x
- 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.x
- 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
-
- - os: osx
- go: 1.9.x
- sudo: required
- script:
- - brew update
- - brew install caskroom/cask/brew-cask
- - brew cask install osxfuse
- - go run build/ci.go install
- - go run build/ci.go test -coverage
-
- # This builder only tests code linters on latest version of Go
- - os: linux
- dist: trusty
- sudo: required
- go: 1.9.x
- env:
- - lint
- 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 lint
-
- # This builder does the Ubuntu PPA and Linux Azure uploads
- - os: linux
- dist: trusty
- sudo: required
- go: 1.9.x
- env:
- - ubuntu-ppa
- - azure-linux
- addons:
- apt:
- packages:
- - devscripts
- - debhelper
- - dput
- - gcc-multilib
- - fakeroot
- script:
- # Build for the primary platforms that Trusty can manage
- - go run build/ci.go debsrc -signer "Go Ethereum Linux Builder " -upload ppa:ethereum/ethereum
- - go run build/ci.go install
- - go run build/ci.go archive -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
- - go run build/ci.go install -arch 386
- - go run build/ci.go archive -arch 386 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
-
- # Switch over GCC to cross compilation (breaks 386, hence why do it here only)
- - sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install gcc-arm-linux-gnueabi libc6-dev-armel-cross gcc-arm-linux-gnueabihf libc6-dev-armhf-cross gcc-aarch64-linux-gnu libc6-dev-arm64-cross
- - sudo ln -s /usr/include/asm-generic /usr/include/asm
-
- - GOARM=5 CC=arm-linux-gnueabi-gcc go run build/ci.go install -arch arm
- - GOARM=5 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
- - GOARM=6 CC=arm-linux-gnueabi-gcc go run build/ci.go install -arch arm
- - GOARM=6 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
- - GOARM=7 CC=arm-linux-gnueabihf-gcc go run build/ci.go install -arch arm
- - GOARM=7 go run build/ci.go archive -arch arm -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
- - CC=aarch64-linux-gnu-gcc go run build/ci.go install -arch arm64
- - go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
-
- # This builder does the Linux Azure MIPS xgo uploads
- - os: linux
- dist: trusty
- sudo: required
- services:
- - docker
- go: 1.9.x
- env:
- - azure-linux-mips
- script:
- - go run build/ci.go xgo --alltools -- --targets=linux/mips --ldflags '-extldflags "-static"' -v
- - for bin in build/bin/*-linux-mips; do mv -f "${bin}" "${bin/-linux-mips/}"; done
- - go run build/ci.go archive -arch mips -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
-
- - go run build/ci.go xgo --alltools -- --targets=linux/mipsle --ldflags '-extldflags "-static"' -v
- - for bin in build/bin/*-linux-mipsle; do mv -f "${bin}" "${bin/-linux-mipsle/}"; done
- - go run build/ci.go archive -arch mipsle -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
-
- - go run build/ci.go xgo --alltools -- --targets=linux/mips64 --ldflags '-extldflags "-static"' -v
- - for bin in build/bin/*-linux-mips64; do mv -f "${bin}" "${bin/-linux-mips64/}"; done
- - go run build/ci.go archive -arch mips64 -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
-
- - go run build/ci.go xgo --alltools -- --targets=linux/mips64le --ldflags '-extldflags "-static"' -v
- - for bin in build/bin/*-linux-mips64le; do mv -f "${bin}" "${bin/-linux-mips64le/}"; done
- - go run build/ci.go archive -arch mips64le -type tar -signer LINUX_SIGNING_KEY -upload gethstore/builds
-
- # This builder does the Android Maven and Azure uploads
- - os: linux
- dist: precise # Needed for the android tools
- addons:
- apt:
- packages:
- - oracle-java8-installer
- - oracle-java8-set-default
- language: android
- android:
- components:
- - platform-tools
- - tools
- - android-15
- - android-19
- - android-24
- env:
- - azure-android
- - maven-android
- before_install:
- - curl https://storage.googleapis.com/golang/go1.9.2.linux-amd64.tar.gz | tar -xz
- - export PATH=`pwd`/go/bin:$PATH
- - export GOROOT=`pwd`/go
- - export GOPATH=$HOME/go
- script:
- # Build the Android archive and upload it to Maven Central and Azure
- - curl https://dl.google.com/android/repository/android-ndk-r15c-linux-x86_64.zip -o android-ndk-r15c.zip
- - unzip -q android-ndk-r15c.zip && rm android-ndk-r15c.zip
- - mv android-ndk-r15c $HOME
- - export ANDROID_NDK=$HOME/android-ndk-r15c
-
- - mkdir -p $GOPATH/src/github.com/ethereum
- - ln -s `pwd` $GOPATH/src/github.com/ethereum
- - go run build/ci.go aar -signer ANDROID_SIGNING_KEY -deploy https://oss.sonatype.org -upload gethstore/builds
-
- # This builder does the OSX Azure, iOS CocoaPods and iOS Azure uploads
- - os: osx
- go: 1.9.x
- env:
- - azure-osx
- - azure-ios
- - cocoapods-ios
- script:
- - go run build/ci.go install
- - go run build/ci.go archive -type tar -signer OSX_SIGNING_KEY -upload gethstore/builds
-
- # Build the iOS framework and upload it to CocoaPods and Azure
- - gem uninstall cocoapods -a -x
- - gem install cocoapods
-
- - mv ~/.cocoapods/repos/master ~/.cocoapods/repos/master.bak
- - sed -i '.bak' 's/repo.join/!repo.join/g' $(dirname `gem which cocoapods`)/cocoapods/sources_manager.rb
- - if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then git clone --depth=1 https://github.com/CocoaPods/Specs.git ~/.cocoapods/repos/master && pod setup --verbose; fi
-
- - xctool -version
- - xcrun simctl list
-
- - go run build/ci.go xcode -signer IOS_SIGNING_KEY -deploy trunk -upload gethstore/builds
-
- # This builder does the Azure archive purges to avoid accumulating junk
- - os: linux
- dist: trusty
- sudo: required
- go: 1.9.x
- env:
- - azure-purge
- script:
- - go run build/ci.go purge -store gethstore/builds -days 14
-
+ - os: linux
+ dist: trusty
+ sudo: required
+ go: 1.7.x
+ 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
+ - os: linux
+ dist: trusty
+ sudo: required
+ go: 1.8.x
+ 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
+ - os: linux
+ dist: trusty
+ sudo: required
+ go: 1.9.x
+ 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
+ - os: linux
+ dist: trusty
+ sudo: required
+ go: "1.10"
+ 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
+ - os: osx
+ go: 1.9.x
+ sudo: required
+ script:
+ - brew update
+ - brew install caskroom/cask/brew-cask
+ - brew cask install osxfuse
+ - go run build/ci.go install
+ - go run build/ci.go test -coverage
+ - os: linux
+ dist: trusty
+ sudo: required
+ go: "1.10"
+ env:
+ - lint
+ 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 lint
install:
- - go get golang.org/x/tools/cmd/cover
+- go get golang.org/x/tools/cmd/cover
script:
- - go run build/ci.go install
- - go run build/ci.go test -coverage
-
+- go run build/ci.go install
+- go run build/ci.go test -coverage
notifications:
- webhooks:
- urls:
- - https://webhooks.gitter.im/e/e09ccdce1048c5e03445
- on_success: change
- on_failure: always
+ slack:
+ rooms:
+ # - secure: l+fwBLQrE3UL6/iRBpH66g7w3zQJ9HqT7sbSUQenyP9Oi45JmbzwH5zr1TcUCqsoHBGTRnkMbmocjkN7KH7Nj1e8HgyccqGhheGdcW/LFKZKYt0cmyvzH24ygW0U6mEpg2Lpd8rKZAtN3Tfm6lmzERJOw8nsA2wFIAgj+90acAnzwqCQ9Sv25tn4NhubxRFtWvJ/cM7Ym0eVb2qH229rffqSpvC2NpaeBQMCcYrJrQeC4rtR5fP0LD/X0SuDNLJk70MatE3PXI6yBrEI1BiiybccoR6I/re85YaKCSgPvAjzjUs2LOYX86XGhrBR8kUy61gDrCJab4NMBng/ik6ZCudkqBNYN3uZKK7gPb9f1B3tK36ctsYBu5HrUdhKMKfdk5lv4FMqZlB9viMoLnsgUZ97ysTYX3ZEoR5SPdJ4retC8T8QqXyoZB0/UwH1YuThMSI4tWfy5Lczvre2HaDDq3m4HFA4GOu0xZoUVYBXTLncTqV7DiiftaMwruB/ZwjhAoj/WL8MDZzWtdkAs7VmEcg030gmc9zQjhDcE3g7b4yf4Y/HOqtNN/I/CmrUhxMOh3cQ7P32E3eoIFp7ZAooywuQ/3LVljX4tWEHNvv/SBUj/WLDzXi0Y7QYZO577gWYcDQnFpZXlOGEtIvZ9USlvCdLjy6kGQh7nh4henwvIA8= # sprai#ethereum-p2p
+ - secure: dMserCwUtaOTdEh4/fpqNUU22UjwsvoH2Bq1mXJriBzbLABqIkZfyVJQHzTJUGLaW3muf4mtcATqZQ2G3QPp7TnOqFiZBJSoQlkNj1+k7pGVWJVU/W/VzsbRD2wdUtERRNUw3BAgvHJ8f1FEKHLc735Mb/QxhN5rmTETtGryGV00DEBKsS89sY2AcSbA0V4PTHFrlce8zGEv2rCjx07WI4oWJQdyV6X6Kv5rupJGVHb6Gz4Z6kIN6EYizJBG0JE/Y8yvb0WkJhhed8CkKS8LdOkIFE4PZyJBN1m5Pl/jTomRxNsOqLz8aVLWpKJVItWCEAsBQhPFziziXy72JN3oarxW2md628tCMMeaHPg6D43ZKOA9BygxkYqkF7xLCpyy+dLer7uZ0z1Ed5MUfXDsglJY4qPKvPY0OC1rW8fB3TaHeC9p17WYyfrEkeOsu/6hr6NypSmEKZfIvX0wb8Cradk93muVW8WSIVxf2N2MEO2PDeowemLhde6cMizq3vegHSaBRMheVBFREHmHpwq6IttL13oIjKvFUVrDh1VbqQcs2pWptDmRX+wfo7g6VQBky+GyYpqyH7PbTPMq9DWsQu0fdjPLJfEga0GZHdBzSA0QBqyXvhbKgilLjcDemp+bVSkrEFdeeqCGBZfKqwe/MggvP/J3ZCw9cXFLQHUWjM8= # teamnsrg#simonsk
+ on_success: always # default: always
+ on_failure: always # default: always
+ on_cancel: always # default: always
+ on_error: always # default: always
+ on_pull_requests: true
diff --git a/README.md b/README.md
index 61e36afec4bc..5e068301dc3a 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@ Official golang implementation of the Ethereum protocol.
[![API Reference](
https://camo.githubusercontent.com/915b7be44ada53c290eb157634330494ebe3e30a/68747470733a2f2f676f646f632e6f72672f6769746875622e636f6d2f676f6c616e672f6764646f3f7374617475732e737667
-)](https://godoc.org/github.com/ethereum/go-ethereum)
+)](https://godoc.org/github.com/teamnsrg/ethereum-p2p)
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ethereum/go-ethereum?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
Automated builds are available for stable releases and the unstable master branch.
@@ -13,7 +13,7 @@ Binary archives are published at https://geth.ethereum.org/downloads/.
## Building the source
For prerequisites and detailed build instructions please read the
-[Installation Instructions](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum)
+[Installation Instructions](https://github.com/teamnsrg/ethereum-p2p/wiki/Building-Ethereum)
on the wiki.
Building geth requires both a Go (version 1.7 or later) and a C compiler.
@@ -32,8 +32,8 @@ The go-ethereum project comes with several wrappers/executables found in the `cm
| Command | Description |
|:----------:|-------------|
-| **`geth`** | Our main Ethereum CLI client. It is the entry point into the Ethereum network (main-, test- or private net), capable of running as a full node (default) archive node (retaining all historical state) or a light node (retrieving data live). It can be used by other processes as a gateway into the Ethereum network via JSON RPC endpoints exposed on top of HTTP, WebSocket and/or IPC transports. `geth --help` and the [CLI Wiki page](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options) for command line options. |
-| `abigen` | Source code generator to convert Ethereum contract definitions into easy to use, compile-time type-safe Go packages. It operates on plain [Ethereum contract ABIs](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) with expanded functionality if the contract bytecode is also available. However it also accepts Solidity source files, making development much more streamlined. Please see our [Native DApps](https://github.com/ethereum/go-ethereum/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts) wiki page for details. |
+| **`geth`** | Our main Ethereum CLI client. It is the entry point into the Ethereum network (main-, test- or private net), capable of running as a full node (default) archive node (retaining all historical state) or a light node (retrieving data live). It can be used by other processes as a gateway into the Ethereum network via JSON RPC endpoints exposed on top of HTTP, WebSocket and/or IPC transports. `geth --help` and the [CLI Wiki page](https://github.com/teamnsrg/ethereum-p2p/wiki/Command-Line-Options) for command line options. |
+| `abigen` | Source code generator to convert Ethereum contract definitions into easy to use, compile-time type-safe Go packages. It operates on plain [Ethereum contract ABIs](https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI) with expanded functionality if the contract bytecode is also available. However it also accepts Solidity source files, making development much more streamlined. Please see our [Native DApps](https://github.com/teamnsrg/ethereum-p2p/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts) wiki page for details. |
| `bootnode` | Stripped down version of our Ethereum client implementation that only takes part in the network node discovery protocol, but does not run any of the higher level application protocols. It can be used as a lightweight bootstrap node to aid in finding peers in private networks. |
| `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. |
@@ -44,7 +44,7 @@ The go-ethereum project comes with several wrappers/executables found in the `cm
## Running geth
Going through all the possible command line flags is out of scope here (please consult our
-[CLI Wiki page](https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options)), but we've
+[CLI Wiki page](https://github.com/teamnsrg/ethereum-p2p/wiki/Command-Line-Options)), but we've
enumerated a few common parameter combos to get you up to speed quickly on how you can run your
own Geth instance.
@@ -66,9 +66,9 @@ This command will:
* Bump the memory allowance of the database to 512MB (`--cache=512`), which can help significantly in
sync times especially for HDD users. This flag is optional and you can set it as high or as low as
you'd like, though we'd recommend the 512MB - 2GB range.
- * Start up Geth's built-in interactive [JavaScript console](https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console),
+ * Start up Geth's built-in interactive [JavaScript console](https://github.com/teamnsrg/ethereum-p2p/wiki/JavaScript-Console),
(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).
+ as well as Geth's own [management APIs](https://github.com/teamnsrg/ethereum-p2p/wiki/Management-APIs).
This too is optional and if you leave it out you can always attach to an already running Geth instance
with `geth attach`.
@@ -137,7 +137,7 @@ Do not forget `--rpcaddr 0.0.0.0`, if you want to access RPC from other containe
As a developer, sooner rather than later you'll want to start interacting with Geth and the Ethereum
network via your own programs and not manually through the console. To aid this, Geth has built in
support for a JSON-RPC based APIs ([standard APIs](https://github.com/ethereum/wiki/wiki/JSON-RPC) and
-[Geth specific APIs](https://github.com/ethereum/go-ethereum/wiki/Management-APIs)). These can be
+[Geth specific APIs](https://github.com/teamnsrg/ethereum-p2p/wiki/Management-APIs)). These can be
exposed via HTTP, WebSockets and IPC (unix sockets on unix based platforms, and named pipes on Windows).
The IPC interface is enabled by default and exposes all the APIs supported by Geth, whereas the HTTP
@@ -290,7 +290,7 @@ Please make sure your contributions adhere to our coding guidelines:
* Commit messages should be prefixed with the package(s) they modify.
* E.g. "eth, rpc: make trace configs optional"
-Please see the [Developers' Guide](https://github.com/ethereum/go-ethereum/wiki/Developers'-Guide)
+Please see the [Developers' Guide](https://github.com/teamnsrg/ethereum-p2p/wiki/Developers'-Guide)
for more details on configuring your environment, managing project dependencies and testing procedures.
## License
diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go
index 79c4d4a16364..6fbe81025c08 100644
--- a/accounts/abi/abi_test.go
+++ b/accounts/abi/abi_test.go
@@ -25,8 +25,8 @@ import (
"strings"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
const jsondata = `
diff --git a/accounts/abi/bind/auth.go b/accounts/abi/bind/auth.go
index e6bb0c3b5286..9cc15b2a610a 100644
--- a/accounts/abi/bind/auth.go
+++ b/accounts/abi/bind/auth.go
@@ -22,10 +22,10 @@ import (
"io"
"io/ioutil"
- "github.com/ethereum/go-ethereum/accounts/keystore"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/accounts/keystore"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
// NewTransactor is a utility method to easily create a transaction signer from
diff --git a/accounts/abi/bind/backend.go b/accounts/abi/bind/backend.go
index 25b61928e121..760cc3f3deec 100644
--- a/accounts/abi/bind/backend.go
+++ b/accounts/abi/bind/backend.go
@@ -21,9 +21,9 @@ import (
"errors"
"math/big"
- "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/teamnsrg/ethereum-p2p"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
)
var (
diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go
index 09288d401ec5..76c674668471 100644
--- a/accounts/abi/bind/backends/simulated.go
+++ b/accounts/abi/bind/backends/simulated.go
@@ -24,17 +24,17 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi/bind"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/consensus/ethash"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
// This nil assignment ensures compile time that SimulatedBackend implements bind.ContractBackend.
diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go
index b40bd65e802d..72e1ecd575e4 100644
--- a/accounts/abi/bind/base.go
+++ b/accounts/abi/bind/base.go
@@ -22,11 +22,11 @@ import (
"fmt"
"math/big"
- "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
// SignerFn is a signer function callback when a contract requires a method to
diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go
index f5875808841b..36431fe028a5 100644
--- a/accounts/abi/bind/bind.go
+++ b/accounts/abi/bind/bind.go
@@ -17,7 +17,7 @@
// Package bind generates Ethereum contract Go bindings.
//
// Detailed usage document and tutorial available on the go-ethereum Wiki page:
-// https://github.com/ethereum/go-ethereum/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts
+// https://github.com/teamnsrg/ethereum-p2p/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts
package bind
import (
@@ -28,7 +28,7 @@ import (
"text/template"
"unicode"
- "github.com/ethereum/go-ethereum/accounts/abi"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi"
"golang.org/x/tools/imports"
)
diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go
deleted file mode 100644
index 43ed53b922d7..000000000000
--- a/accounts/abi/bind/bind_test.go
+++ /dev/null
@@ -1,506 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package bind
-
-import (
- "fmt"
- "io/ioutil"
- "os"
- "os/exec"
- "path/filepath"
- "runtime"
- "strings"
- "testing"
-
- "github.com/ethereum/go-ethereum/common"
- "golang.org/x/tools/imports"
-)
-
-var bindTests = []struct {
- name string
- contract string
- bytecode string
- abi string
- tester string
-}{
- // Test that the binding is available in combined and separate forms too
- {
- `Empty`,
- `contract NilContract {}`,
- `606060405260068060106000396000f3606060405200`,
- `[]`,
- `
- if b, err := NewEmpty(common.Address{}, nil); b == nil || err != nil {
- t.Fatalf("combined binding (%v) nil or error (%v) not nil", b, nil)
- }
- if b, err := NewEmptyCaller(common.Address{}, nil); b == nil || err != nil {
- t.Fatalf("caller binding (%v) nil or error (%v) not nil", b, nil)
- }
- if b, err := NewEmptyTransactor(common.Address{}, nil); b == nil || err != nil {
- t.Fatalf("transactor binding (%v) nil or error (%v) not nil", b, nil)
- }
- `,
- },
- // Test that all the official sample contracts bind correctly
- {
- `Token`,
- `https://ethereum.org/token`,
- `60606040526040516107fd3803806107fd83398101604052805160805160a05160c051929391820192909101600160a060020a0333166000908152600360209081526040822086905581548551838052601f6002600019610100600186161502019093169290920482018390047f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56390810193919290918801908390106100e857805160ff19168380011785555b506101189291505b8082111561017157600081556001016100b4565b50506002805460ff19168317905550505050610658806101a56000396000f35b828001600101855582156100ac579182015b828111156100ac5782518260005055916020019190600101906100fa565b50508060016000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017557805160ff19168380011785555b506100c89291506100b4565b5090565b82800160010185558215610165579182015b8281111561016557825182600050559160200191906001019061018756606060405236156100775760e060020a600035046306fdde03811461007f57806323b872dd146100dc578063313ce5671461010e57806370a082311461011a57806395d89b4114610132578063a9059cbb1461018e578063cae9ca51146101bd578063dc3080f21461031c578063dd62ed3e14610341575b610365610002565b61036760008054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156104eb5780601f106104c0576101008083540402835291602001916104eb565b6103d5600435602435604435600160a060020a038316600090815260036020526040812054829010156104f357610002565b6103e760025460ff1681565b6103d560043560036020526000908152604090205481565b610367600180546020600282841615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156104eb5780601f106104c0576101008083540402835291602001916104eb565b610365600435602435600160a060020a033316600090815260036020526040902054819010156103f157610002565b60806020604435600481810135601f8101849004909302840160405260608381526103d5948235946024803595606494939101919081908382808284375094965050505050505060006000836004600050600033600160a060020a03168152602001908152602001600020600050600087600160a060020a031681526020019081526020016000206000508190555084905080600160a060020a0316638f4ffcb1338630876040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a03168152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156102f25780820380516001836020036101000a031916815260200191505b50955050505050506000604051808303816000876161da5a03f11561000257505050509392505050565b6005602090815260043560009081526040808220909252602435815220546103d59081565b60046020818152903560009081526040808220909252602435815220546103d59081565b005b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156103c75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60408051918252519081900360200190f35b6060908152602090f35b600160a060020a03821660009081526040902054808201101561041357610002565b806003600050600033600160a060020a03168152602001908152602001600020600082828250540392505081905550806003600050600084600160a060020a0316815260200190815260200160002060008282825054019250508190555081600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b820191906000526020600020905b8154815290600101906020018083116104ce57829003601f168201915b505050505081565b600160a060020a03831681526040812054808301101561051257610002565b600160a060020a0380851680835260046020908152604080852033949094168086529382528085205492855260058252808520938552929052908220548301111561055c57610002565b816003600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816003600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816005600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054019250508190555082600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3939250505056`,
- `[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"},{"name":"_extraData","type":"bytes"}],"name":"approveAndCall","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"spentAllowance","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"inputs":[{"name":"initialSupply","type":"uint256"},{"name":"tokenName","type":"string"},{"name":"decimalUnits","type":"uint8"},{"name":"tokenSymbol","type":"string"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]`,
- `
- if b, err := NewToken(common.Address{}, nil); b == nil || err != nil {
- t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil)
- }
- `,
- },
- {
- `Crowdsale`,
- `https://ethereum.org/crowdsale`,
- `606060408190526007805460ff1916905560a0806105a883396101006040529051608051915160c05160e05160008054600160a060020a03199081169095178155670de0b6b3a7640000958602600155603c9093024201600355930260045560058054909216909217905561052f90819061007990396000f36060604052361561006c5760e060020a600035046301cb3b20811461008257806329dcb0cf1461014457806338af3eed1461014d5780636e66f6e91461015f5780637a3a0e84146101715780637b3e5e7b1461017a578063a035b1fe14610183578063dc0d3dff1461018c575b61020060075460009060ff161561032357610002565b61020060035460009042106103205760025460015490106103cb576002548154600160a060020a0316908290606082818181858883f150915460025460408051600160a060020a039390931683526020830191909152818101869052517fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf6945090819003909201919050a15b60405160008054600160a060020a039081169230909116319082818181858883f150506007805460ff1916600117905550505050565b6103a160035481565b6103ab600054600160a060020a031681565b6103ab600554600160a060020a031681565b6103a160015481565b6103a160025481565b6103a160045481565b6103be60043560068054829081101561000257506000526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f8101547ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d409190910154600160a060020a03919091169082565b005b505050815481101561000257906000526020600020906002020160005060008201518160000160006101000a815481600160a060020a030219169083021790555060208201518160010160005055905050806002600082828250540192505081905550600560009054906101000a9004600160a060020a0316600160a060020a031663a9059cbb3360046000505484046040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506000604051808303816000876161da5a03f11561000257505060408051600160a060020a03331681526020810184905260018183015290517fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf692509081900360600190a15b50565b5060a0604052336060908152346080819052600680546001810180835592939282908280158290116102025760020281600202836000526020600020918201910161020291905b8082111561039d57805473ffffffffffffffffffffffffffffffffffffffff19168155600060019190910190815561036a565b5090565b6060908152602090f35b600160a060020a03166060908152602090f35b6060918252608052604090f35b5b60065481101561010e576006805482908110156100025760009182526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0190600680549254600160a060020a0316928490811015610002576002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40015460405190915082818181858883f19350505050507fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf660066000508281548110156100025760008290526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01548154600160a060020a039190911691908490811015610002576002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40015460408051600160a060020a0394909416845260208401919091526000838201525191829003606001919050a16001016103cc56`,
- `[{"constant":false,"inputs":[],"name":"checkGoalReached","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"deadline","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"beneficiary","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"tokenReward","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"fundingGoal","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"amountRaised","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"price","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"funders","outputs":[{"name":"addr","type":"address"},{"name":"amount","type":"uint256"}],"type":"function"},{"inputs":[{"name":"ifSuccessfulSendTo","type":"address"},{"name":"fundingGoalInEthers","type":"uint256"},{"name":"durationInMinutes","type":"uint256"},{"name":"etherCostOfEachToken","type":"uint256"},{"name":"addressOfTokenUsedAsReward","type":"address"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"backer","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"isContribution","type":"bool"}],"name":"FundTransfer","type":"event"}]`,
- `
- if b, err := NewCrowdsale(common.Address{}, nil); b == nil || err != nil {
- t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil)
- }
- `,
- },
- {
- `DAO`,
- `https://ethereum.org/dao`,
- `606060405260405160808061145f833960e06040529051905160a05160c05160008054600160a060020a03191633179055600184815560028490556003839055600780549182018082558280158290116100b8576003028160030283600052602060002091820191016100b891906101c8565b50506060919091015160029190910155600160a060020a0381166000146100a65760008054600160a060020a031916821790555b505050506111f18061026e6000396000f35b505060408051608081018252600080825260208281018290528351908101845281815292820192909252426060820152600780549194509250811015610002579081527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6889050815181546020848101517401000000000000000000000000000000000000000002600160a060020a03199290921690921760a060020a60ff021916178255604083015180516001848101805460008281528690209195600293821615610100026000190190911692909204601f9081018390048201949192919091019083901061023e57805160ff19168380011785555b50610072929150610226565b5050600060028201556001015b8082111561023a578054600160a860020a031916815560018181018054600080835592600290821615610100026000190190911604601f81901061020c57506101bb565b601f0160209004906000526020600020908101906101bb91905b8082111561023a5760008155600101610226565b5090565b828001600101855582156101af579182015b828111156101af57825182600050559160200191906001019061025056606060405236156100b95760e060020a6000350463013cf08b81146100bb578063237e9492146101285780633910682114610281578063400e3949146102995780635daf08ca146102a257806369bd34361461032f5780638160f0b5146103385780638da5cb5b146103415780639644fcbd14610353578063aa02a90f146103be578063b1050da5146103c7578063bcca1fd3146104b5578063d3c0715b146104dc578063eceb29451461058d578063f2fde38b1461067b575b005b61069c6004356004805482908110156100025790600052602060002090600a02016000506005810154815460018301546003840154600485015460068601546007870154600160a060020a03959095169750929560020194919360ff828116946101009093041692919089565b60408051602060248035600481810135601f81018590048502860185019096528585526107759581359591946044949293909201918190840183828082843750949650505050505050600060006004600050848154811015610002575090527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19e600a8402908101547f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b909101904210806101e65750600481015460ff165b8061026757508060000160009054906101000a9004600160a060020a03168160010160005054846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020816007016000505414155b8061027757506001546005820154105b1561109257610002565b61077560043560066020526000908152604090205481565b61077560055481565b61078760043560078054829081101561000257506000526003026000805160206111d18339815191528101547fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a820154600160a060020a0382169260a060020a90920460ff16917fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c689019084565b61077560025481565b61077560015481565b610830600054600160a060020a031681565b604080516020604435600481810135601f81018490048402850184019095528484526100b9948135946024803595939460649492939101918190840183828082843750949650505050505050600080548190600160a060020a03908116339091161461084d57610002565b61077560035481565b604080516020604435600481810135601f8101849004840285018401909552848452610775948135946024803595939460649492939101918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976084979196506024909101945090925082915084018382808284375094965050505050505033600160a060020a031660009081526006602052604081205481908114806104ab5750604081205460078054909190811015610002579082526003026000805160206111d1833981519152015460a060020a900460ff16155b15610ce557610002565b6100b960043560243560443560005433600160a060020a03908116911614610b1857610002565b604080516020604435600481810135601f810184900484028501840190955284845261077594813594602480359593946064949293910191819084018382808284375094965050505050505033600160a060020a031660009081526006602052604081205481908114806105835750604081205460078054909190811015610002579082526003026000805160206111d18339815191520181505460a060020a900460ff16155b15610f1d57610002565b604080516020606435600481810135601f81018490048402850184019095528484526107759481359460248035956044359560849492019190819084018382808284375094965050505050505060006000600460005086815481101561000257908252600a027f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b01815090508484846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160070160005054149150610cdc565b6100b960043560005433600160a060020a03908116911614610f0857610002565b604051808a600160a060020a031681526020018981526020018060200188815260200187815260200186815260200185815260200184815260200183815260200182810382528981815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561075e5780601f106107335761010080835404028352916020019161075e565b820191906000526020600020905b81548152906001019060200180831161074157829003601f168201915b50509a505050505050505050505060405180910390f35b60408051918252519081900360200190f35b60408051600160a060020a038616815260208101859052606081018390526080918101828152845460026001821615610100026000190190911604928201839052909160a08301908590801561081e5780601f106107f35761010080835404028352916020019161081e565b820191906000526020600020905b81548152906001019060200180831161080157829003601f168201915b50509550505050505060405180910390f35b60408051600160a060020a03929092168252519081900360200190f35b600160a060020a03851660009081526006602052604081205414156108a957604060002060078054918290556001820180825582801582901161095c5760030281600302836000526020600020918201910161095c9190610a4f565b600160a060020a03851660009081526006602052604090205460078054919350908390811015610002575060005250600381026000805160206111d183398151915201805474ff0000000000000000000000000000000000000000191660a060020a85021781555b60408051600160a060020a03871681526020810186905281517f27b022af4a8347100c7a041ce5ccf8e14d644ff05de696315196faae8cd50c9b929181900390910190a15050505050565b505050915081506080604051908101604052808681526020018581526020018481526020014281526020015060076000508381548110156100025790600052602060002090600302016000508151815460208481015160a060020a02600160a060020a03199290921690921774ff00000000000000000000000000000000000000001916178255604083015180516001848101805460008281528690209195600293821615610100026000190190911692909204601f90810183900482019491929190910190839010610ad357805160ff19168380011785555b50610b03929150610abb565b5050600060028201556001015b80821115610acf57805474ffffffffffffffffffffffffffffffffffffffffff1916815560018181018054600080835592600290821615610100026000190190911604601f819010610aa15750610a42565b601f016020900490600052602060002090810190610a4291905b80821115610acf5760008155600101610abb565b5090565b82800160010185558215610a36579182015b82811115610a36578251826000505591602001919060010190610ae5565b50506060919091015160029190910155610911565b600183905560028290556003819055604080518481526020810184905280820183905290517fa439d3fa452be5e0e1e24a8145e715f4fd8b9c08c96a42fd82a855a85e5d57de9181900360600190a1505050565b50508585846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160070160005081905550600260005054603c024201816003016000508190555060008160040160006101000a81548160ff0219169083021790555060008160040160016101000a81548160ff02191690830217905550600081600501600050819055507f646fec02522b41e7125cfc859a64fd4f4cefd5dc3b6237ca0abe251ded1fa881828787876040518085815260200184600160a060020a03168152602001838152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015610cc45780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a1600182016005555b50949350505050565b6004805460018101808355909190828015829011610d1c57600a0281600a028360005260206000209182019101610d1c9190610db8565b505060048054929450918491508110156100025790600052602060002090600a02016000508054600160a060020a031916871781556001818101879055855160028381018054600082815260209081902096975091959481161561010002600019011691909104601f90810182900484019391890190839010610ed857805160ff19168380011785555b50610b6c929150610abb565b50506001015b80821115610acf578054600160a060020a03191681556000600182810182905560028381018054848255909281161561010002600019011604601f819010610e9c57505b5060006003830181905560048301805461ffff191690556005830181905560068301819055600783018190556008830180548282559082526020909120610db2916002028101905b80821115610acf57805474ffffffffffffffffffffffffffffffffffffffffff1916815560018181018054600080835592600290821615610100026000190190911604601f819010610eba57505b5050600101610e44565b601f016020900490600052602060002090810190610dfc9190610abb565b601f016020900490600052602060002090810190610e929190610abb565b82800160010185558215610da6579182015b82811115610da6578251826000505591602001919060010190610eea565b60008054600160a060020a0319168217905550565b600480548690811015610002576000918252600a027f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b01905033600160a060020a0316600090815260098201602052604090205490915060ff1660011415610f8457610002565b33600160a060020a031660009081526009820160205260409020805460ff1916600190811790915560058201805490910190558315610fcd576006810180546001019055610fda565b6006810180546000190190555b7fc34f869b7ff431b034b7b9aea9822dac189a685e0b015c7d1be3add3f89128e8858533866040518085815260200184815260200183600160a060020a03168152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561107a5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a1509392505050565b6006810154600354901315611158578060000160009054906101000a9004600160a060020a0316600160a060020a03168160010160005054670de0b6b3a76400000284604051808280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156111225780820380516001836020036101000a031916815260200191505b5091505060006040518083038185876185025a03f15050505060048101805460ff191660011761ff00191661010017905561116d565b60048101805460ff191660011761ff00191690555b60068101546005820154600483015460408051888152602081019490945283810192909252610100900460ff166060830152517fd220b7272a8b6d0d7d6bcdace67b936a8f175e6d5c1b3ee438b72256b32ab3af9181900360800190a1509291505056a66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688`,
- `[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"proposals","outputs":[{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"},{"name":"description","type":"string"},{"name":"votingDeadline","type":"uint256"},{"name":"executed","type":"bool"},{"name":"proposalPassed","type":"bool"},{"name":"numberOfVotes","type":"uint256"},{"name":"currentResult","type":"int256"},{"name":"proposalHash","type":"bytes32"}],"type":"function"},{"constant":false,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"transactionBytecode","type":"bytes"}],"name":"executeProposal","outputs":[{"name":"result","type":"int256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"memberId","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"numProposals","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"members","outputs":[{"name":"member","type":"address"},{"name":"canVote","type":"bool"},{"name":"name","type":"string"},{"name":"memberSince","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"debatingPeriodInMinutes","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"minimumQuorum","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"targetMember","type":"address"},{"name":"canVote","type":"bool"},{"name":"memberName","type":"string"}],"name":"changeMembership","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"majorityMargin","outputs":[{"name":"","type":"int256"}],"type":"function"},{"constant":false,"inputs":[{"name":"beneficiary","type":"address"},{"name":"etherAmount","type":"uint256"},{"name":"JobDescription","type":"string"},{"name":"transactionBytecode","type":"bytes"}],"name":"newProposal","outputs":[{"name":"proposalID","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"minimumQuorumForProposals","type":"uint256"},{"name":"minutesForDebate","type":"uint256"},{"name":"marginOfVotesForMajority","type":"int256"}],"name":"changeVotingRules","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"supportsProposal","type":"bool"},{"name":"justificationText","type":"string"}],"name":"vote","outputs":[{"name":"voteID","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"beneficiary","type":"address"},{"name":"etherAmount","type":"uint256"},{"name":"transactionBytecode","type":"bytes"}],"name":"checkProposalCode","outputs":[{"name":"codeChecksOut","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"type":"function"},{"inputs":[{"name":"minimumQuorumForProposals","type":"uint256"},{"name":"minutesForDebate","type":"uint256"},{"name":"marginOfVotesForMajority","type":"int256"},{"name":"congressLeader","type":"address"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"recipient","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"description","type":"string"}],"name":"ProposalAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"position","type":"bool"},{"indexed":false,"name":"voter","type":"address"},{"indexed":false,"name":"justification","type":"string"}],"name":"Voted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"result","type":"int256"},{"indexed":false,"name":"quorum","type":"uint256"},{"indexed":false,"name":"active","type":"bool"}],"name":"ProposalTallied","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"member","type":"address"},{"indexed":false,"name":"isMember","type":"bool"}],"name":"MembershipChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"minimumQuorum","type":"uint256"},{"indexed":false,"name":"debatingPeriodInMinutes","type":"uint256"},{"indexed":false,"name":"majorityMargin","type":"int256"}],"name":"ChangeOfRules","type":"event"}]`,
- `
- if b, err := NewDAO(common.Address{}, nil); b == nil || err != nil {
- t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil)
- }
- `,
- },
- // Test that named and anonymous inputs are handled correctly
- {
- `InputChecker`, ``, ``,
- `
- [
- {"type":"function","name":"noInput","constant":true,"inputs":[],"outputs":[]},
- {"type":"function","name":"namedInput","constant":true,"inputs":[{"name":"str","type":"string"}],"outputs":[]},
- {"type":"function","name":"anonInput","constant":true,"inputs":[{"name":"","type":"string"}],"outputs":[]},
- {"type":"function","name":"namedInputs","constant":true,"inputs":[{"name":"str1","type":"string"},{"name":"str2","type":"string"}],"outputs":[]},
- {"type":"function","name":"anonInputs","constant":true,"inputs":[{"name":"","type":"string"},{"name":"","type":"string"}],"outputs":[]},
- {"type":"function","name":"mixedInputs","constant":true,"inputs":[{"name":"","type":"string"},{"name":"str","type":"string"}],"outputs":[]}
- ]
- `,
- `if b, err := NewInputChecker(common.Address{}, nil); b == nil || err != nil {
- t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil)
- } else if false { // Don't run, just compile and test types
- var err error
-
- err = b.NoInput(nil)
- err = b.NamedInput(nil, "")
- err = b.AnonInput(nil, "")
- err = b.NamedInputs(nil, "", "")
- err = b.AnonInputs(nil, "", "")
- err = b.MixedInputs(nil, "", "")
-
- fmt.Println(err)
- }`,
- },
- // Test that named and anonymous outputs are handled correctly
- {
- `OutputChecker`, ``, ``,
- `
- [
- {"type":"function","name":"noOutput","constant":true,"inputs":[],"outputs":[]},
- {"type":"function","name":"namedOutput","constant":true,"inputs":[],"outputs":[{"name":"str","type":"string"}]},
- {"type":"function","name":"anonOutput","constant":true,"inputs":[],"outputs":[{"name":"","type":"string"}]},
- {"type":"function","name":"namedOutputs","constant":true,"inputs":[],"outputs":[{"name":"str1","type":"string"},{"name":"str2","type":"string"}]},
- {"type":"function","name":"anonOutputs","constant":true,"inputs":[],"outputs":[{"name":"","type":"string"},{"name":"","type":"string"}]},
- {"type":"function","name":"mixedOutputs","constant":true,"inputs":[],"outputs":[{"name":"","type":"string"},{"name":"str","type":"string"}]}
- ]
- `,
- `if b, err := NewOutputChecker(common.Address{}, nil); b == nil || err != nil {
- t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil)
- } else if false { // Don't run, just compile and test types
- var str1, str2 string
- var err error
-
- err = b.NoOutput(nil)
- str1, err = b.NamedOutput(nil)
- str1, err = b.AnonOutput(nil)
- res, _ := b.NamedOutputs(nil)
- str1, str2, err = b.AnonOutputs(nil)
- str1, str2, err = b.MixedOutputs(nil)
-
- fmt.Println(str1, str2, res.Str1, res.Str2, err)
- }`,
- },
- // Test that contract interactions (deploy, transact and call) generate working code
- {
- `Interactor`,
- `
- contract Interactor {
- string public deployString;
- string public transactString;
-
- function Interactor(string str) {
- deployString = str;
- }
-
- function transact(string str) {
- transactString = str;
- }
- }
- `,
- `6060604052604051610328380380610328833981016040528051018060006000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10608d57805160ff19168380011785555b50607c9291505b8082111560ba57838155600101606b565b50505061026a806100be6000396000f35b828001600101855582156064579182015b828111156064578251826000505591602001919060010190609e565b509056606060405260e060020a60003504630d86a0e181146100315780636874e8091461008d578063d736c513146100ea575b005b610190600180546020600282841615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156102295780601f106101fe57610100808354040283529160200191610229565b61019060008054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156102295780601f106101fe57610100808354040283529160200191610229565b60206004803580820135601f81018490049093026080908101604052606084815261002f946024939192918401918190838280828437509496505050505050508060016000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061023157805160ff19168380011785555b506102619291505b808211156102665760008155830161017d565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156101f05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b820191906000526020600020905b81548152906001019060200180831161020c57829003601f168201915b505050505081565b82800160010185558215610175579182015b82811115610175578251826000505591602001919060010190610243565b505050565b509056`,
- `[{"constant":true,"inputs":[],"name":"transactString","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":true,"inputs":[],"name":"deployString","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"str","type":"string"}],"name":"transact","outputs":[],"type":"function"},{"inputs":[{"name":"str","type":"string"}],"type":"constructor"}]`,
- `
- // Generate a new random account and a funded simulator
- key, _ := crypto.GenerateKey()
- auth := bind.NewKeyedTransactor(key)
- sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}})
-
- // Deploy an interaction tester contract and call a transaction on it
- _, _, interactor, err := DeployInteractor(auth, sim, "Deploy string")
- if err != nil {
- t.Fatalf("Failed to deploy interactor contract: %v", err)
- }
- if _, err := interactor.Transact(auth, "Transact string"); err != nil {
- t.Fatalf("Failed to transact with interactor contract: %v", err)
- }
- // Commit all pending transactions in the simulator and check the contract state
- sim.Commit()
-
- if str, err := interactor.DeployString(nil); err != nil {
- t.Fatalf("Failed to retrieve deploy string: %v", err)
- } else if str != "Deploy string" {
- t.Fatalf("Deploy string mismatch: have '%s', want 'Deploy string'", str)
- }
- if str, err := interactor.TransactString(nil); err != nil {
- t.Fatalf("Failed to retrieve transact string: %v", err)
- } else if str != "Transact string" {
- t.Fatalf("Transact string mismatch: have '%s', want 'Transact string'", str)
- }
- `,
- },
- // Tests that plain values can be properly returned and deserialized
- {
- `Getter`,
- `
- contract Getter {
- function getter() constant returns (string, int, bytes32) {
- return ("Hi", 1, sha3(""));
- }
- }
- `,
- `606060405260dc8060106000396000f3606060405260e060020a6000350463993a04b78114601a575b005b600060605260c0604052600260809081527f486900000000000000000000000000000000000000000000000000000000000060a05260017fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060e0829052610100819052606060c0908152600261012081905281906101409060a09080838184600060046012f1505081517fffff000000000000000000000000000000000000000000000000000000000000169091525050604051610160819003945092505050f3`,
- `[{"constant":true,"inputs":[],"name":"getter","outputs":[{"name":"","type":"string"},{"name":"","type":"int256"},{"name":"","type":"bytes32"}],"type":"function"}]`,
- `
- // Generate a new random account and a funded simulator
- key, _ := crypto.GenerateKey()
- auth := bind.NewKeyedTransactor(key)
- sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}})
-
- // Deploy a tuple tester contract and execute a structured call on it
- _, _, getter, err := DeployGetter(auth, sim)
- if err != nil {
- t.Fatalf("Failed to deploy getter contract: %v", err)
- }
- sim.Commit()
-
- if str, num, _, err := getter.Getter(nil); err != nil {
- t.Fatalf("Failed to call anonymous field retriever: %v", err)
- } else if str != "Hi" || num.Cmp(big.NewInt(1)) != 0 {
- t.Fatalf("Retrieved value mismatch: have %v/%v, want %v/%v", str, num, "Hi", 1)
- }
- `,
- },
- // Tests that tuples can be properly returned and deserialized
- {
- `Tupler`,
- `
- contract Tupler {
- function tuple() constant returns (string a, int b, bytes32 c) {
- return ("Hi", 1, sha3(""));
- }
- }
- `,
- `606060405260dc8060106000396000f3606060405260e060020a60003504633175aae28114601a575b005b600060605260c0604052600260809081527f486900000000000000000000000000000000000000000000000000000000000060a05260017fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060e0829052610100819052606060c0908152600261012081905281906101409060a09080838184600060046012f1505081517fffff000000000000000000000000000000000000000000000000000000000000169091525050604051610160819003945092505050f3`,
- `[{"constant":true,"inputs":[],"name":"tuple","outputs":[{"name":"a","type":"string"},{"name":"b","type":"int256"},{"name":"c","type":"bytes32"}],"type":"function"}]`,
- `
- // Generate a new random account and a funded simulator
- key, _ := crypto.GenerateKey()
- auth := bind.NewKeyedTransactor(key)
- sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}})
-
- // Deploy a tuple tester contract and execute a structured call on it
- _, _, tupler, err := DeployTupler(auth, sim)
- if err != nil {
- t.Fatalf("Failed to deploy tupler contract: %v", err)
- }
- sim.Commit()
-
- if res, err := tupler.Tuple(nil); err != nil {
- t.Fatalf("Failed to call structure retriever: %v", err)
- } else if res.A != "Hi" || res.B.Cmp(big.NewInt(1)) != 0 {
- t.Fatalf("Retrieved value mismatch: have %v/%v, want %v/%v", res.A, res.B, "Hi", 1)
- }
- `,
- },
- // Tests that arrays/slices can be properly returned and deserialized.
- // Only addresses are tested, remainder just compiled to keep the test small.
- {
- `Slicer`,
- `
- contract Slicer {
- function echoAddresses(address[] input) constant returns (address[] output) {
- return input;
- }
- function echoInts(int[] input) constant returns (int[] output) {
- return input;
- }
- function echoFancyInts(uint24[23] input) constant returns (uint24[23] output) {
- return input;
- }
- function echoBools(bool[] input) constant returns (bool[] output) {
- return input;
- }
- }
- `,
- `606060405261015c806100126000396000f3606060405260e060020a6000350463be1127a3811461003c578063d88becc014610092578063e15a3db71461003c578063f637e5891461003c575b005b604080516020600480358082013583810285810185019096528085526100ee959294602494909392850192829185019084908082843750949650505050505050604080516020810190915260009052805b919050565b604080516102e0818101909252610138916004916102e491839060179083908390808284375090955050505050506102e0604051908101604052806017905b60008152602001906001900390816100d15790505081905061008d565b60405180806020018281038252838181518152602001915080519060200190602002808383829060006004602084601f0104600f02600301f1509050019250505060405180910390f35b60405180826102e0808381846000600461015cf15090500191505060405180910390f3`,
- `[{"constant":true,"inputs":[{"name":"input","type":"address[]"}],"name":"echoAddresses","outputs":[{"name":"output","type":"address[]"}],"type":"function"},{"constant":true,"inputs":[{"name":"input","type":"uint24[23]"}],"name":"echoFancyInts","outputs":[{"name":"output","type":"uint24[23]"}],"type":"function"},{"constant":true,"inputs":[{"name":"input","type":"int256[]"}],"name":"echoInts","outputs":[{"name":"output","type":"int256[]"}],"type":"function"},{"constant":true,"inputs":[{"name":"input","type":"bool[]"}],"name":"echoBools","outputs":[{"name":"output","type":"bool[]"}],"type":"function"}]`,
- `
- // Generate a new random account and a funded simulator
- key, _ := crypto.GenerateKey()
- auth := bind.NewKeyedTransactor(key)
- sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}})
-
- // Deploy a slice tester contract and execute a n array call on it
- _, _, slicer, err := DeploySlicer(auth, sim)
- if err != nil {
- t.Fatalf("Failed to deploy slicer contract: %v", err)
- }
- sim.Commit()
-
- if out, err := slicer.EchoAddresses(nil, []common.Address{auth.From, common.Address{}}); err != nil {
- t.Fatalf("Failed to call slice echoer: %v", err)
- } else if !reflect.DeepEqual(out, []common.Address{auth.From, common.Address{}}) {
- t.Fatalf("Slice return mismatch: have %v, want %v", out, []common.Address{auth.From, common.Address{}})
- }
- `,
- },
- // Tests that anonymous default methods can be correctly invoked
- {
- `Defaulter`,
- `
- contract Defaulter {
- address public caller;
-
- function() {
- caller = msg.sender;
- }
- }
- `,
- `6060604052606a8060106000396000f360606040523615601d5760e060020a6000350463fc9c8d3981146040575b605e6000805473ffffffffffffffffffffffffffffffffffffffff191633179055565b606060005473ffffffffffffffffffffffffffffffffffffffff1681565b005b6060908152602090f3`,
- `[{"constant":true,"inputs":[],"name":"caller","outputs":[{"name":"","type":"address"}],"type":"function"}]`,
- `
- // Generate a new random account and a funded simulator
- key, _ := crypto.GenerateKey()
- auth := bind.NewKeyedTransactor(key)
- sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}})
-
- // Deploy a default method invoker contract and execute its default method
- _, _, defaulter, err := DeployDefaulter(auth, sim)
- if err != nil {
- t.Fatalf("Failed to deploy defaulter contract: %v", err)
- }
- if _, err := (&DefaulterRaw{defaulter}).Transfer(auth); err != nil {
- t.Fatalf("Failed to invoke default method: %v", err)
- }
- sim.Commit()
-
- if caller, err := defaulter.Caller(nil); err != nil {
- t.Fatalf("Failed to call address retriever: %v", err)
- } else if (caller != auth.From) {
- t.Fatalf("Address mismatch: have %v, want %v", caller, auth.From)
- }
- `,
- },
- // Tests that non-existent contracts are reported as such (though only simulator test)
- {
- `NonExistent`,
- `
- contract NonExistent {
- function String() constant returns(string) {
- return "I don't exist";
- }
- }
- `,
- `6060604052609f8060106000396000f3606060405260e060020a6000350463f97a60058114601a575b005b600060605260c0604052600d60809081527f4920646f6e27742065786973740000000000000000000000000000000000000060a052602060c0908152600d60e081905281906101009060a09080838184600060046012f15050815172ffffffffffffffffffffffffffffffffffffff1916909152505060405161012081900392509050f3`,
- `[{"constant":true,"inputs":[],"name":"String","outputs":[{"name":"","type":"string"}],"type":"function"}]`,
- `
- // Create a simulator and wrap a non-deployed contract
- sim := backends.NewSimulatedBackend(nil)
-
- nonexistent, err := NewNonExistent(common.Address{}, sim)
- if err != nil {
- t.Fatalf("Failed to access non-existent contract: %v", err)
- }
- // Ensure that contract calls fail with the appropriate error
- if res, err := nonexistent.String(nil); err == nil {
- t.Fatalf("Call succeeded on non-existent contract: %v", res)
- } else if (err != bind.ErrNoCode) {
- t.Fatalf("Error mismatch: have %v, want %v", err, bind.ErrNoCode)
- }
- `,
- },
- // Tests that gas estimation works for contracts with weird gas mechanics too.
- {
- `FunkyGasPattern`,
- `
- contract FunkyGasPattern {
- string public field;
-
- function SetField(string value) {
- // This check will screw gas estimation! Good, good!
- if (msg.gas < 100000) {
- throw;
- }
- field = value;
- }
- }
- `,
- `606060405261021c806100126000396000f3606060405260e060020a600035046323fcf32a81146100265780634f28bf0e1461007b575b005b6040805160206004803580820135601f8101849004840285018401909552848452610024949193602493909291840191908190840183828082843750949650505050505050620186a05a101561014e57610002565b6100db60008054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281529291908301828280156102145780601f106101e957610100808354040283529160200191610214565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561013b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b505050565b8060006000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106101b557805160ff19168380011785555b506101499291505b808211156101e557600081556001016101a1565b82800160010185558215610199579182015b828111156101995782518260005055916020019190600101906101c7565b5090565b820191906000526020600020905b8154815290600101906020018083116101f757829003601f168201915b50505050508156`,
- `[{"constant":false,"inputs":[{"name":"value","type":"string"}],"name":"SetField","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"field","outputs":[{"name":"","type":"string"}],"type":"function"}]`,
- `
- // Generate a new random account and a funded simulator
- key, _ := crypto.GenerateKey()
- auth := bind.NewKeyedTransactor(key)
- sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}})
-
- // Deploy a funky gas pattern contract
- _, _, limiter, err := DeployFunkyGasPattern(auth, sim)
- if err != nil {
- t.Fatalf("Failed to deploy funky contract: %v", err)
- }
- sim.Commit()
-
- // Set the field with automatic estimation and check that it succeeds
- auth.GasLimit = nil
- if _, err := limiter.SetField(auth, "automatic"); err != nil {
- t.Fatalf("Failed to call automatically gased transaction: %v", err)
- }
- sim.Commit()
-
- if field, _ := limiter.Field(nil); field != "automatic" {
- t.Fatalf("Field mismatch: have %v, want %v", field, "automatic")
- }
- `,
- },
- // Test that constant functions can be called from an (optional) specified address
- {
- `CallFrom`,
- `
- contract CallFrom {
- function callFrom() constant returns(address) {
- return msg.sender;
- }
- }
- `, `6060604052346000575b6086806100176000396000f300606060405263ffffffff60e060020a60003504166349f8e98281146022575b6000565b34600057602c6055565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b335b905600a165627a7a72305820aef6b7685c0fa24ba6027e4870404a57df701473fe4107741805c19f5138417c0029`,
- `[{"constant":true,"inputs":[],"name":"callFrom","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"}]`,
- `
- // Generate a new random account and a funded simulator
- key, _ := crypto.GenerateKey()
- auth := bind.NewKeyedTransactor(key)
- sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}})
-
- // Deploy a sender tester contract and execute a structured call on it
- _, _, callfrom, err := DeployCallFrom(auth, sim)
- if err != nil {
- t.Fatalf("Failed to deploy sender contract: %v", err)
- }
- sim.Commit()
-
- if res, err := callfrom.CallFrom(nil); err != nil {
- t.Errorf("Failed to call constant function: %v", err)
- } else if res != (common.Address{}) {
- t.Errorf("Invalid address returned, want: %x, got: %x", (common.Address{}), res)
- }
-
- for _, addr := range []common.Address{common.Address{}, common.Address{1}, common.Address{2}} {
- if res, err := callfrom.CallFrom(&bind.CallOpts{From: addr}); err != nil {
- t.Fatalf("Failed to call constant function: %v", err)
- } else if res != addr {
- t.Fatalf("Invalid address returned, want: %x, got: %x", addr, res)
- }
- }
- `,
- },
-}
-
-// Tests that packages generated by the binder can be successfully compiled and
-// the requested tester run against it.
-func TestBindings(t *testing.T) {
- // Skip the test if no Go command can be found
- gocmd := runtime.GOROOT() + "/bin/go"
- if !common.FileExist(gocmd) {
- t.Skip("go sdk not found for testing")
- }
- // 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(os.TempDir(), []byte(linkTestCode), nil)
- if err != nil {
- t.Fatalf("failed check for goimports symlink bug: %v", err)
- }
- if !strings.Contains(string(linkTestDeps), "go-ethereum") {
- t.Skip("symlinked environment doesn't support bind (https://github.com/golang/go/issues/14845)")
- }
- // Create a temporary workspace for the test suite
- ws, err := ioutil.TempDir("", "")
- if err != nil {
- t.Fatalf("failed to create temporary workspace: %v", err)
- }
- defer os.RemoveAll(ws)
-
- pkg := filepath.Join(ws, "bindtest")
- if err = os.MkdirAll(pkg, 0700); err != nil {
- t.Fatalf("failed to create package: %v", err)
- }
- // Generate the test suite for all the contracts
- for i, tt := range bindTests {
- // Generate the binding and create a Go source file in the workspace
- bind, err := Bind([]string{tt.name}, []string{tt.abi}, []string{tt.bytecode}, "bindtest", LangGo)
- if err != nil {
- t.Fatalf("test %d: failed to generate binding: %v", i, err)
- }
- if err = ioutil.WriteFile(filepath.Join(pkg, strings.ToLower(tt.name)+".go"), []byte(bind), 0600); err != nil {
- t.Fatalf("test %d: failed to write binding: %v", i, err)
- }
- // Generate the test file with the injected test code
- code := fmt.Sprintf("package bindtest\nimport \"testing\"\nfunc Test%s(t *testing.T){\n%s\n}", tt.name, tt.tester)
- blob, err := imports.Process("", []byte(code), nil)
- if err != nil {
- t.Fatalf("test %d: failed to generate tests: %v", i, err)
- }
- if err := ioutil.WriteFile(filepath.Join(pkg, strings.ToLower(tt.name)+"_test.go"), blob, 0600); err != nil {
- t.Fatalf("test %d: failed to write tests: %v", i, err)
- }
- }
- // Test the entire package and report any failures
- cmd := exec.Command(gocmd, "test", "-v")
- cmd.Dir = pkg
- if out, err := cmd.CombinedOutput(); err != nil {
- t.Fatalf("failed to run binding test: %v\n%s", err, out)
- }
-}
diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go
index d07610e7c24d..e6dcad91063e 100644
--- a/accounts/abi/bind/template.go
+++ b/accounts/abi/bind/template.go
@@ -16,7 +16,7 @@
package bind
-import "github.com/ethereum/go-ethereum/accounts/abi"
+import "github.com/teamnsrg/ethereum-p2p/accounts/abi"
// tmplData is the data structure required to fill the binding template.
type tmplData struct {
diff --git a/accounts/abi/bind/util.go b/accounts/abi/bind/util.go
index d129993ca12f..d8517361c854 100644
--- a/accounts/abi/bind/util.go
+++ b/accounts/abi/bind/util.go
@@ -21,9 +21,9 @@ import (
"fmt"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// WaitMined waits for tx to be mined on the blockchain.
diff --git a/accounts/abi/bind/util_test.go b/accounts/abi/bind/util_test.go
index d24aa721e579..9db05884f13d 100644
--- a/accounts/abi/bind/util_test.go
+++ b/accounts/abi/bind/util_test.go
@@ -22,12 +22,12 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi/bind"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi/bind/backends"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
diff --git a/accounts/abi/event.go b/accounts/abi/event.go
index 44ed7b8df256..640e976b79fc 100644
--- a/accounts/abi/event.go
+++ b/accounts/abi/event.go
@@ -21,8 +21,8 @@ import (
"reflect"
"strings"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
// Event is an event potentially triggered by the EVM's LOG mechanism. The Event
diff --git a/accounts/abi/event_test.go b/accounts/abi/event_test.go
index 7e2f13f76320..5b210080cfa5 100644
--- a/accounts/abi/event_test.go
+++ b/accounts/abi/event_test.go
@@ -20,8 +20,8 @@ import (
"strings"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
func TestEventId(t *testing.T) {
diff --git a/accounts/abi/method.go b/accounts/abi/method.go
index d8838e9ed68f..d8d0f350fc40 100644
--- a/accounts/abi/method.go
+++ b/accounts/abi/method.go
@@ -21,7 +21,7 @@ import (
"reflect"
"strings"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
// Callable method given a `Name` and whether the method is a constant.
diff --git a/accounts/abi/numbers.go b/accounts/abi/numbers.go
index 9ad99f90d29f..4d68923c8991 100644
--- a/accounts/abi/numbers.go
+++ b/accounts/abi/numbers.go
@@ -20,8 +20,8 @@ import (
"math/big"
"reflect"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
)
var (
diff --git a/accounts/abi/pack.go b/accounts/abi/pack.go
index 072e805368d1..a13e9ba4c2f2 100644
--- a/accounts/abi/pack.go
+++ b/accounts/abi/pack.go
@@ -20,8 +20,8 @@ import (
"math/big"
"reflect"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
)
// packBytesSlice packs the given bytes as [L, V] as the canonical representation
diff --git a/accounts/abi/pack_test.go b/accounts/abi/pack_test.go
index 36401ee677c1..e605d08163ff 100644
--- a/accounts/abi/pack_test.go
+++ b/accounts/abi/pack_test.go
@@ -24,7 +24,7 @@ import (
"strings"
"testing"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
func TestPack(t *testing.T) {
diff --git a/accounts/abi/type_test.go b/accounts/abi/type_test.go
index e55af1293951..22379f43957f 100644
--- a/accounts/abi/type_test.go
+++ b/accounts/abi/type_test.go
@@ -22,7 +22,7 @@ import (
"testing"
"github.com/davecgh/go-spew/spew"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
// typeWithoutStringer is a alias for the Type type which simply doesn't implement
diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go
index 57732797b6e1..c526b1269cce 100644
--- a/accounts/abi/unpack.go
+++ b/accounts/abi/unpack.go
@@ -22,7 +22,7 @@ import (
"math/big"
"reflect"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
// unpacker is a utility interface that enables us to have
diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go
index 294908378815..795b7f1e3723 100644
--- a/accounts/abi/unpack_test.go
+++ b/accounts/abi/unpack_test.go
@@ -25,7 +25,7 @@ import (
"strings"
"testing"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
type unpackTest struct {
diff --git a/accounts/accounts.go b/accounts/accounts.go
index 76951e1a42a6..4d1002c3273a 100644
--- a/accounts/accounts.go
+++ b/accounts/accounts.go
@@ -20,10 +20,10 @@ package accounts
import (
"math/big"
- ethereum "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/event"
+ ethereum "github.com/teamnsrg/ethereum-p2p"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/event"
)
// Account represents an Ethereum account located at a specific location defined
diff --git a/accounts/keystore/account_cache.go b/accounts/keystore/account_cache.go
index 71f698ece71a..04097e4e2c43 100644
--- a/accounts/keystore/account_cache.go
+++ b/accounts/keystore/account_cache.go
@@ -27,9 +27,9 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/log"
"gopkg.in/fatih/set.v0"
)
diff --git a/accounts/keystore/account_cache_test.go b/accounts/keystore/account_cache_test.go
index e3dc3106568b..0a65b127a006 100644
--- a/accounts/keystore/account_cache_test.go
+++ b/accounts/keystore/account_cache_test.go
@@ -29,8 +29,8 @@ import (
"github.com/cespare/cp"
"github.com/davecgh/go-spew/spew"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
var (
diff --git a/accounts/keystore/file_cache.go b/accounts/keystore/file_cache.go
index c91b7b7b6104..1e6e6a9134d9 100644
--- a/accounts/keystore/file_cache.go
+++ b/accounts/keystore/file_cache.go
@@ -24,7 +24,7 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
set "gopkg.in/fatih/set.v0"
)
diff --git a/accounts/keystore/key.go b/accounts/keystore/key.go
index 211fa863d7bd..1aed3ec74510 100644
--- a/accounts/keystore/key.go
+++ b/accounts/keystore/key.go
@@ -29,10 +29,10 @@ import (
"strings"
"time"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
"github.com/pborman/uuid"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
const (
diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go
index 80ccd37419f9..d53509d99198 100644
--- a/accounts/keystore/keystore.go
+++ b/accounts/keystore/keystore.go
@@ -33,11 +33,11 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/event"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/event"
)
var (
diff --git a/accounts/keystore/keystore_passphrase.go b/accounts/keystore/keystore_passphrase.go
index eaec39f7df28..5f452e3b1edd 100644
--- a/accounts/keystore/keystore_passphrase.go
+++ b/accounts/keystore/keystore_passphrase.go
@@ -36,11 +36,11 @@ import (
"io/ioutil"
"path/filepath"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/randentropy"
"github.com/pborman/uuid"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/crypto/randentropy"
"golang.org/x/crypto/pbkdf2"
"golang.org/x/crypto/scrypt"
)
diff --git a/accounts/keystore/keystore_passphrase_test.go b/accounts/keystore/keystore_passphrase_test.go
index 630682cebdb1..fe0ef5929c95 100644
--- a/accounts/keystore/keystore_passphrase_test.go
+++ b/accounts/keystore/keystore_passphrase_test.go
@@ -20,7 +20,7 @@ import (
"io/ioutil"
"testing"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
const (
diff --git a/accounts/keystore/keystore_plain.go b/accounts/keystore/keystore_plain.go
index b490ca72b826..9ead1f1ec825 100644
--- a/accounts/keystore/keystore_plain.go
+++ b/accounts/keystore/keystore_plain.go
@@ -22,7 +22,7 @@ import (
"os"
"path/filepath"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
type keyStorePlain struct {
diff --git a/accounts/keystore/keystore_plain_test.go b/accounts/keystore/keystore_plain_test.go
index a1c3bc4b6cd1..825475f681f5 100644
--- a/accounts/keystore/keystore_plain_test.go
+++ b/accounts/keystore/keystore_plain_test.go
@@ -27,8 +27,8 @@ import (
"strings"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
func tmpKeyStoreIface(t *testing.T, encrypted bool) (dir string, ks keyStore) {
diff --git a/accounts/keystore/keystore_test.go b/accounts/keystore/keystore_test.go
index 6fb0a7808870..e17474558ceb 100644
--- a/accounts/keystore/keystore_test.go
+++ b/accounts/keystore/keystore_test.go
@@ -26,9 +26,9 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/event"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/event"
)
var testSigData = make([]byte, 32)
diff --git a/accounts/keystore/keystore_wallet.go b/accounts/keystore/keystore_wallet.go
index 758fdfe36438..df38c092caa1 100644
--- a/accounts/keystore/keystore_wallet.go
+++ b/accounts/keystore/keystore_wallet.go
@@ -19,9 +19,9 @@ package keystore
import (
"math/big"
- ethereum "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/core/types"
+ ethereum "github.com/teamnsrg/ethereum-p2p"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
)
// keystoreWallet implements the accounts.Wallet interface for the original
diff --git a/accounts/keystore/presale.go b/accounts/keystore/presale.go
index ed900ad085e9..26769bb0653d 100644
--- a/accounts/keystore/presale.go
+++ b/accounts/keystore/presale.go
@@ -25,9 +25,9 @@ import (
"errors"
"fmt"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/crypto"
"github.com/pborman/uuid"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
"golang.org/x/crypto/pbkdf2"
)
diff --git a/accounts/keystore/watch.go b/accounts/keystore/watch.go
index bbcfb99257ad..325a6ed8da16 100644
--- a/accounts/keystore/watch.go
+++ b/accounts/keystore/watch.go
@@ -21,8 +21,8 @@ package keystore
import (
"time"
- "github.com/ethereum/go-ethereum/log"
"github.com/rjeczalik/notify"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
type watcher struct {
diff --git a/accounts/manager.go b/accounts/manager.go
index 96ca298fc5df..e8a49e164a0b 100644
--- a/accounts/manager.go
+++ b/accounts/manager.go
@@ -21,7 +21,7 @@ import (
"sort"
"sync"
- "github.com/ethereum/go-ethereum/event"
+ "github.com/teamnsrg/ethereum-p2p/event"
)
// Manager is an overarching account manager that can communicate with various
diff --git a/accounts/usbwallet/hub.go b/accounts/usbwallet/hub.go
index 61fc98ccc80e..338a3be0799c 100644
--- a/accounts/usbwallet/hub.go
+++ b/accounts/usbwallet/hub.go
@@ -22,10 +22,10 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
"github.com/karalabe/hid"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// LedgerScheme is the protocol scheme prefixing account and wallet URLs.
diff --git a/accounts/usbwallet/ledger.go b/accounts/usbwallet/ledger.go
index f5def61d235c..099e81c18bed 100644
--- a/accounts/usbwallet/ledger.go
+++ b/accounts/usbwallet/ledger.go
@@ -28,12 +28,12 @@ import (
"io"
"math/big"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
// ledgerOpcode is an enumeration encoding the supported Ledger opcodes.
diff --git a/accounts/usbwallet/trezor.go b/accounts/usbwallet/trezor.go
index 159cb2ea9702..7a36997a825f 100644
--- a/accounts/usbwallet/trezor.go
+++ b/accounts/usbwallet/trezor.go
@@ -27,13 +27,13 @@ import (
"io"
"math/big"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/accounts/usbwallet/internal/trezor"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/log"
"github.com/golang/protobuf/proto"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/accounts/usbwallet/internal/trezor"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// ErrTrezorPINNeeded is returned if opening the trezor requires a PIN code. In
diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go
index 8b3b5a522402..d6e95cc844c5 100644
--- a/accounts/usbwallet/wallet.go
+++ b/accounts/usbwallet/wallet.go
@@ -25,12 +25,12 @@ import (
"sync"
"time"
- ethereum "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/log"
"github.com/karalabe/hid"
+ ethereum "github.com/teamnsrg/ethereum-p2p"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// Maximum time between wallet health checks to detect USB unplugs.
diff --git a/appveyor.yml b/appveyor.yml
index 78b11fa9d660..b7c8d64b137e 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,7 +1,7 @@
os: Visual Studio 2015
# Clone directly into GOPATH.
-clone_folder: C:\gopath\src\github.com\ethereum\go-ethereum
+clone_folder: C:\gopath\src\github.com\teamnsrg\ethereum-p2p
clone_depth: 5
version: "{branch}.{build}"
environment:
diff --git a/bmt/bmt_test.go b/bmt/bmt_test.go
index 57df83060ab0..59d6b6111f19 100644
--- a/bmt/bmt_test.go
+++ b/bmt/bmt_test.go
@@ -28,7 +28,7 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/crypto/sha3"
+ "github.com/teamnsrg/ethereum-p2p/crypto/sha3"
)
const (
diff --git a/build/ci.go b/build/ci.go
index 0c825ef31e61..f248cd4e0196 100644
--- a/build/ci.go
+++ b/build/ci.go
@@ -58,7 +58,7 @@ import (
"strings"
"time"
- "github.com/ethereum/go-ethereum/internal/build"
+ "github.com/teamnsrg/ethereum-p2p/internal/build"
)
var (
@@ -179,11 +179,17 @@ func doInstall(cmdline []string) {
// Check Go version. People regularly open issues about compilation
// failure with outdated Go. This should save them the trouble.
- if runtime.Version() < "go1.7" && !strings.Contains(runtime.Version(), "devel") {
- log.Println("You have Go version", runtime.Version())
- log.Println("go-ethereum requires at least Go version 1.7 and cannot")
- log.Println("be compiled with an earlier version. Please upgrade your Go installation.")
- os.Exit(1)
+ if !strings.Contains(runtime.Version(), "devel") {
+ // Figure out the minor version number since we can't textually compare (1.10 < 1.7)
+ var minor int
+ fmt.Sscanf(strings.TrimPrefix(runtime.Version(), "go1."), "%d", &minor)
+
+ if minor < 7 {
+ log.Println("You have Go version", runtime.Version())
+ log.Println("go-ethereum requires at least Go version 1.7 and cannot")
+ log.Println("be compiled with an earlier version. Please upgrade your Go installation.")
+ os.Exit(1)
+ }
}
// Compile packages given as arguments, or everything if there are no arguments.
packages := []string{"./..."}
@@ -297,6 +303,9 @@ func doTest(cmdline []string) {
// Run analysis tools before the tests.
build.MustRun(goTool("vet", packages...))
+ // Exclude packages
+ packages = build.FilterPackages(packages)
+
// Run the actual tests.
gotest := goTool("test", buildFlags(env)...)
// Test a single package at a time. CI builders are slow
@@ -716,7 +725,7 @@ func doAndroidArchive(cmdline []string) {
// Build the Android archive and Maven resources
build.MustRun(goTool("get", "golang.org/x/mobile/cmd/gomobile"))
build.MustRun(gomobileTool("init", "--ndk", os.Getenv("ANDROID_NDK")))
- build.MustRun(gomobileTool("bind", "--target", "android", "--javapkg", "org.ethereum", "-v", "github.com/ethereum/go-ethereum/mobile"))
+ build.MustRun(gomobileTool("bind", "--target", "android", "--javapkg", "org.ethereum", "-v", "github.com/teamnsrg/ethereum-p2p/mobile"))
if *local {
// If we're building locally, copy bundle to build dir and skip Maven
@@ -836,7 +845,7 @@ func doXCodeFramework(cmdline []string) {
// Build the iOS XCode framework
build.MustRun(goTool("get", "golang.org/x/mobile/cmd/gomobile"))
build.MustRun(gomobileTool("init"))
- bind := gomobileTool("bind", "--target", "ios", "--tags", "ios", "-v", "github.com/ethereum/go-ethereum/mobile")
+ bind := gomobileTool("bind", "--target", "ios", "--tags", "ios", "-v", "github.com/teamnsrg/ethereum-p2p/mobile")
if *local {
// If we're building locally, use the build folder and stop afterwards
diff --git a/build/deb.control b/build/deb.control
index 5c9ce6705c25..961ff6df8403 100644
--- a/build/deb.control
+++ b/build/deb.control
@@ -5,8 +5,8 @@ Maintainer: {{.Author}}
Build-Depends: debhelper (>= 8.0.0), golang-1.9
Standards-Version: 3.9.5
Homepage: https://ethereum.org
-Vcs-Git: git://github.com/ethereum/go-ethereum.git
-Vcs-Browser: https://github.com/ethereum/go-ethereum
+Vcs-Git: git://github.com/teamnsrg/ethereum-p2p.git
+Vcs-Browser: https://github.com/teamnsrg/ethereum-p2p
Package: {{.Name}}
Architecture: any
diff --git a/build/env.sh b/build/env.sh
index 3914555d1bbd..15d79776f37c 100755
--- a/build/env.sh
+++ b/build/env.sh
@@ -10,11 +10,11 @@ fi
# Create fake Go workspace if it doesn't exist yet.
workspace="$PWD/build/_workspace"
root="$PWD"
-ethdir="$workspace/src/github.com/ethereum"
-if [ ! -L "$ethdir/go-ethereum" ]; then
+ethdir="$workspace/src/github.com/teamnsrg"
+if [ ! -L "$ethdir/ethereum-p2p" ]; then
mkdir -p "$ethdir"
cd "$ethdir"
- ln -s ../../../../../. go-ethereum
+ ln -s ../../../../../. ethereum-p2p
cd "$root"
fi
@@ -23,8 +23,8 @@ GOPATH="$workspace"
export GOPATH
# Run the command inside the workspace.
-cd "$ethdir/go-ethereum"
-PWD="$ethdir/go-ethereum"
+cd "$ethdir/ethereum-p2p"
+PWD="$ethdir/ethereum-p2p"
# Launch the arguments with the configured environment.
exec "$@"
diff --git a/build/mvn.pom b/build/mvn.pom
index 7670246ba9f1..ce47f07a6dbc 100644
--- a/build/mvn.pom
+++ b/build/mvn.pom
@@ -11,7 +11,7 @@
Android Ethereum Client
Android port of the go-ethereum libraries and node
- https://github.com/ethereum/go-ethereum
+ https://github.com/teamnsrg/ethereum-p2p
2015
@@ -48,10 +48,10 @@
GitHub Issues
- https://github.com/ethereum/go-ethereum/issues/
+ https://github.com/teamnsrg/ethereum-p2p/issues/
- https://github.com/ethereum/go-ethereum
+ https://github.com/teamnsrg/ethereum-p2p
diff --git a/build/nsis.install.nsh b/build/nsis.install.nsh
index 57ef5a37c6a4..54474114450c 100644
--- a/build/nsis.install.nsh
+++ b/build/nsis.install.nsh
@@ -3,9 +3,9 @@ InstallDir "$InstDir"
OutFile "${OUTPUTFILE}" # set through command line arguments
# Links for "Add/Remove Programs"
-!define HELPURL "https://github.com/ethereum/go-ethereum/issues"
-!define UPDATEURL "https://github.com/ethereum/go-ethereum/releases"
-!define ABOUTURL "https://github.com/ethereum/go-ethereum#ethereum-go"
+!define HELPURL "https://github.com/teamnsrg/ethereum-p2p/issues"
+!define UPDATEURL "https://github.com/teamnsrg/ethereum-p2p/releases"
+!define ABOUTURL "https://github.com/teamnsrg/ethereum-p2p#ethereum-go"
!define /date NOW "%Y%m%d"
PageEx license
diff --git a/build/pod.podspec b/build/pod.podspec
index 2c14c280c7c9..513ce513f1c8 100644
--- a/build/pod.podspec
+++ b/build/pod.podspec
@@ -2,12 +2,12 @@ Pod::Spec.new do |spec|
spec.name = 'Geth'
spec.version = '{{.Version}}'
spec.license = { :type => 'GNU Lesser General Public License, Version 3.0' }
- spec.homepage = 'https://github.com/ethereum/go-ethereum'
+ spec.homepage = 'https://github.com/teamnsrg/ethereum-p2p'
spec.authors = { {{range .Contributors}}
'{{.Name}}' => '{{.Email}}',{{end}}
}
spec.summary = 'iOS Ethereum Client'
- spec.source = { :git => 'https://github.com/ethereum/go-ethereum.git', :commit => '{{.Commit}}' }
+ spec.source = { :git => 'https://github.com/teamnsrg/ethereum-p2p.git', :commit => '{{.Commit}}' }
spec.platform = :ios
spec.ios.deployment_target = '9.0'
diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go
index 3a1ae6f4c319..80e4ad2ad378 100644
--- a/cmd/abigen/main.go
+++ b/cmd/abigen/main.go
@@ -24,8 +24,8 @@ import (
"os"
"strings"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common/compiler"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi/bind"
+ "github.com/teamnsrg/ethereum-p2p/common/compiler"
)
var (
diff --git a/cmd/bootnode/main.go b/cmd/bootnode/main.go
index e1734d89ac81..c62cf7a560e7 100644
--- a/cmd/bootnode/main.go
+++ b/cmd/bootnode/main.go
@@ -23,13 +23,13 @@ import (
"fmt"
"os"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/p2p/discv5"
- "github.com/ethereum/go-ethereum/p2p/nat"
- "github.com/ethereum/go-ethereum/p2p/netutil"
+ "github.com/teamnsrg/ethereum-p2p/cmd/utils"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discv5"
+ "github.com/teamnsrg/ethereum-p2p/p2p/nat"
+ "github.com/teamnsrg/ethereum-p2p/p2p/netutil"
)
func main() {
@@ -101,7 +101,7 @@ func main() {
utils.Fatalf("%v", err)
}
} else {
- if _, err := discover.ListenUDP(nodeKey, *listenAddr, natm, "", restrictList); err != nil {
+ if _, _, err := discover.ListenUDP(nodeKey, *listenAddr, natm, "", restrictList, nil); err != nil {
utils.Fatalf("%v", err)
}
}
diff --git a/cmd/evm/compiler.go b/cmd/evm/compiler.go
index c019a2fe70b7..c5486a91b79e 100644
--- a/cmd/evm/compiler.go
+++ b/cmd/evm/compiler.go
@@ -21,7 +21,7 @@ import (
"fmt"
"io/ioutil"
- "github.com/ethereum/go-ethereum/cmd/evm/internal/compiler"
+ "github.com/teamnsrg/ethereum-p2p/cmd/evm/internal/compiler"
cli "gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/evm/disasm.go b/cmd/evm/disasm.go
index 4a442cf78445..1bba543ad394 100644
--- a/cmd/evm/disasm.go
+++ b/cmd/evm/disasm.go
@@ -22,7 +22,7 @@ import (
"io/ioutil"
"strings"
- "github.com/ethereum/go-ethereum/core/asm"
+ "github.com/teamnsrg/ethereum-p2p/core/asm"
cli "gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/evm/internal/compiler/compiler.go b/cmd/evm/internal/compiler/compiler.go
index 753ca62264ef..613ee643b661 100644
--- a/cmd/evm/internal/compiler/compiler.go
+++ b/cmd/evm/internal/compiler/compiler.go
@@ -20,7 +20,7 @@ import (
"errors"
"fmt"
- "github.com/ethereum/go-ethereum/core/asm"
+ "github.com/teamnsrg/ethereum-p2p/core/asm"
)
func Compile(fn string, src []byte, debug bool) (string, error) {
diff --git a/cmd/evm/json_logger.go b/cmd/evm/json_logger.go
index eb7b0c46600e..09e2ad808701 100644
--- a/cmd/evm/json_logger.go
+++ b/cmd/evm/json_logger.go
@@ -21,9 +21,9 @@ import (
"io"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
)
type JSONLogger struct {
diff --git a/cmd/evm/main.go b/cmd/evm/main.go
index 6c39cf8b8870..0edce3fd630f 100644
--- a/cmd/evm/main.go
+++ b/cmd/evm/main.go
@@ -22,7 +22,7 @@ import (
"math/big"
"os"
- "github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/teamnsrg/ethereum-p2p/cmd/utils"
"gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go
index 96de0c76ac7c..2295053281a3 100644
--- a/cmd/evm/runner.go
+++ b/cmd/evm/runner.go
@@ -27,16 +27,16 @@ import (
goruntime "runtime"
- "github.com/ethereum/go-ethereum/cmd/evm/internal/compiler"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/core/vm/runtime"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/cmd/evm/internal/compiler"
+ "github.com/teamnsrg/ethereum-p2p/cmd/utils"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/core/vm/runtime"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/params"
cli "gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/evm/staterunner.go b/cmd/evm/staterunner.go
index 071ea94ad059..e1be30456db9 100644
--- a/cmd/evm/staterunner.go
+++ b/cmd/evm/staterunner.go
@@ -23,10 +23,10 @@ import (
"io/ioutil"
"os"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/tests"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/tests"
cli "gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/faucet/faucet.go b/cmd/faucet/faucet.go
index 72098e68d284..36ad2fc97676 100644
--- a/cmd/faucet/faucet.go
+++ b/cmd/faucet/faucet.go
@@ -41,23 +41,23 @@ import (
"sync"
"time"
- "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"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/ethclient"
- "github.com/ethereum/go-ethereum/ethstats"
- "github.com/ethereum/go-ethereum/les"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/p2p/discv5"
- "github.com/ethereum/go-ethereum/p2p/nat"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/accounts/keystore"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/eth"
+ "github.com/teamnsrg/ethereum-p2p/eth/downloader"
+ "github.com/teamnsrg/ethereum-p2p/ethclient"
+ "github.com/teamnsrg/ethereum-p2p/ethstats"
+ "github.com/teamnsrg/ethereum-p2p/les"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/node"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discv5"
+ "github.com/teamnsrg/ethereum-p2p/p2p/nat"
+ "github.com/teamnsrg/ethereum-p2p/params"
"golang.org/x/net/websocket"
)
@@ -443,7 +443,7 @@ func (f *faucet) apiHandler(conn *websocket.Conn) {
case strings.HasPrefix(msg.URL, "https://www.facebook.com/"):
username, avatar, address, err = authFacebook(msg.URL)
default:
- err = errors.New("Something funky happened, please open an issue at https://github.com/ethereum/go-ethereum/issues")
+ err = errors.New("Something funky happened, please open an issue at https://github.com/teamnsrg/ethereum-p2p/issues")
}
if err != nil {
if err = sendError(conn, err); err != nil {
diff --git a/cmd/geth/accountcmd.go b/cmd/geth/accountcmd.go
index 0db5c4ce0f8e..6a1282b21f15 100644
--- a/cmd/geth/accountcmd.go
+++ b/cmd/geth/accountcmd.go
@@ -20,12 +20,12 @@ import (
"fmt"
"io/ioutil"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/accounts/keystore"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/console"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/accounts/keystore"
+ "github.com/teamnsrg/ethereum-p2p/cmd/utils"
+ "github.com/teamnsrg/ethereum-p2p/console"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/log"
"gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/geth/accountcmd_test.go b/cmd/geth/accountcmd_test.go
index 3ea22ccfab60..1740c85126b9 100644
--- a/cmd/geth/accountcmd_test.go
+++ b/cmd/geth/accountcmd_test.go
@@ -173,7 +173,7 @@ Fatal: Failed to unlock account f466859ead1932d743d622cb74fc058882e8648a (could
`)
}
-// https://github.com/ethereum/go-ethereum/issues/1785
+// https://github.com/teamnsrg/ethereum-p2p/issues/1785
func TestUnlockFlagMultiIndex(t *testing.T) {
datadir := tmpDatadirWithKeystore(t)
geth := runGeth(t,
diff --git a/cmd/geth/bugcmd.go b/cmd/geth/bugcmd.go
index ce9dbe6c0a75..d069e9fcb9ce 100644
--- a/cmd/geth/bugcmd.go
+++ b/cmd/geth/bugcmd.go
@@ -26,10 +26,10 @@ import (
"runtime"
"strings"
- "github.com/ethereum/go-ethereum/cmd/internal/browser"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/cmd/internal/browser"
+ "github.com/teamnsrg/ethereum-p2p/params"
- "github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/teamnsrg/ethereum-p2p/cmd/utils"
cli "gopkg.in/urfave/cli.v1"
)
@@ -41,7 +41,7 @@ var bugCommand = cli.Command{
Category: "MISCELLANEOUS COMMANDS",
}
-const issueUrl = "https://github.com/ethereum/go-ethereum/issues/new"
+const issueUrl = "https://github.com/teamnsrg/ethereum-p2p/issues/new"
// reportBug reports a bug by opening a new URL to the go-ethereum GH issue
// tracker and setting default values as the issue body.
diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go
index 4a9a7b11b5e7..9c472550b358 100644
--- a/cmd/geth/chaincmd.go
+++ b/cmd/geth/chaincmd.go
@@ -25,18 +25,18 @@ import (
"sync/atomic"
"time"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/console"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/trie"
"github.com/syndtr/goleveldb/leveldb/util"
+ "github.com/teamnsrg/ethereum-p2p/cmd/utils"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/console"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/eth/downloader"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/trie"
"gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/geth/config.go b/cmd/geth/config.go
index 27490c40486f..47f9c38c84d1 100644
--- a/cmd/geth/config.go
+++ b/cmd/geth/config.go
@@ -28,14 +28,13 @@ import (
cli "gopkg.in/urfave/cli.v1"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/contracts/release"
- "github.com/ethereum/go-ethereum/dashboard"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/params"
- whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
"github.com/naoina/toml"
+ "github.com/teamnsrg/ethereum-p2p/cmd/utils"
+ "github.com/teamnsrg/ethereum-p2p/contracts/release"
+ "github.com/teamnsrg/ethereum-p2p/dashboard"
+ "github.com/teamnsrg/ethereum-p2p/eth"
+ "github.com/teamnsrg/ethereum-p2p/node"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
var (
@@ -44,7 +43,7 @@ var (
Name: "dumpconfig",
Usage: "Show configuration values",
ArgsUsage: "",
- Flags: append(append(nodeFlags, rpcFlags...), whisperFlags...),
+ Flags: append(nodeFlags, rpcFlags...),
Category: "MISCELLANEOUS COMMANDS",
Description: `The dumpconfig command shows configuration values.`,
}
@@ -78,7 +77,6 @@ type ethstatsConfig struct {
type gethConfig struct {
Eth eth.Config
- Shh whisper.Config
Node node.Config
Ethstats ethstatsConfig
Dashboard dashboard.Config
@@ -103,9 +101,9 @@ func defaultNodeConfig() node.Config {
cfg := node.DefaultConfig
cfg.Name = clientIdentifier
cfg.Version = params.VersionWithCommit(gitCommit)
- cfg.HTTPModules = append(cfg.HTTPModules, "eth", "shh")
- cfg.WSModules = append(cfg.WSModules, "eth", "shh")
- cfg.IPCPath = "geth.ipc"
+ cfg.HTTPModules = append(cfg.HTTPModules, "eth")
+ cfg.WSModules = append(cfg.WSModules, "eth")
+ cfg.IPCPath = clientIdentifier + ".ipc"
return cfg
}
@@ -113,7 +111,6 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) {
// Load defaults.
cfg := gethConfig{
Eth: eth.DefaultConfig,
- Shh: whisper.DefaultConfig,
Node: defaultNodeConfig(),
Dashboard: dashboard.DefaultConfig,
}
@@ -126,6 +123,10 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) {
}
// Apply flags.
+ if ctx.GlobalBool(utils.LogToFileFlag.Name) {
+ cfg.Node.LogToFile = true
+ cfg.Node.InstanceDirLock = instanceDirLock // should have been set during initial setup
+ }
utils.SetNodeConfig(ctx, &cfg.Node)
stack, err := node.New(&cfg.Node)
if err != nil {
@@ -136,22 +137,11 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) {
cfg.Ethstats.URL = ctx.GlobalString(utils.EthStatsURLFlag.Name)
}
- utils.SetShhConfig(ctx, stack, &cfg.Shh)
utils.SetDashboardConfig(ctx, &cfg.Dashboard)
return stack, cfg
}
-// enableWhisper returns true in case one of the whisper flags is set.
-func enableWhisper(ctx *cli.Context) bool {
- for _, flag := range whisperFlags {
- if ctx.GlobalIsSet(flag.GetName()) {
- return true
- }
- }
- return false
-}
-
func makeFullNode(ctx *cli.Context) *node.Node {
stack, cfg := makeConfigNode(ctx)
@@ -160,18 +150,6 @@ func makeFullNode(ctx *cli.Context) *node.Node {
if ctx.GlobalBool(utils.DashboardEnabledFlag.Name) {
utils.RegisterDashboardService(stack, &cfg.Dashboard)
}
- // Whisper must be explicitly enabled by specifying at least 1 whisper flag or in dev mode
- shhEnabled := enableWhisper(ctx)
- shhAutoEnabled := !ctx.GlobalIsSet(utils.WhisperEnabledFlag.Name) && ctx.GlobalIsSet(utils.DeveloperFlag.Name)
- if shhEnabled || shhAutoEnabled {
- if ctx.GlobalIsSet(utils.WhisperMaxMessageSizeFlag.Name) {
- cfg.Shh.MaxMessageSize = uint32(ctx.Int(utils.WhisperMaxMessageSizeFlag.Name))
- }
- if ctx.GlobalIsSet(utils.WhisperMinPOWFlag.Name) {
- cfg.Shh.MinimumAcceptedPOW = ctx.Float64(utils.WhisperMinPOWFlag.Name)
- }
- utils.RegisterShhService(stack, &cfg.Shh)
- }
// Add the Ethereum Stats daemon if requested.
if cfg.Ethstats.URL != "" {
diff --git a/cmd/geth/consolecmd.go b/cmd/geth/consolecmd.go
index 2bb452d73611..a4499162f84d 100644
--- a/cmd/geth/consolecmd.go
+++ b/cmd/geth/consolecmd.go
@@ -21,10 +21,10 @@ import (
"os/signal"
"strings"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/console"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/cmd/utils"
+ "github.com/teamnsrg/ethereum-p2p/console"
+ "github.com/teamnsrg/ethereum-p2p/node"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
"gopkg.in/urfave/cli.v1"
)
@@ -35,12 +35,12 @@ var (
Action: utils.MigrateFlags(localConsole),
Name: "console",
Usage: "Start an interactive JavaScript environment",
- Flags: append(append(append(nodeFlags, rpcFlags...), consoleFlags...), whisperFlags...),
+ Flags: append(append(nodeFlags, rpcFlags...), consoleFlags...),
Category: "CONSOLE COMMANDS",
Description: `
The Geth console is an interactive shell for the JavaScript runtime environment
which exposes a node admin interface as well as the Ðapp JavaScript API.
-See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console.`,
+See https://github.com/teamnsrg/ethereum-p2p/wiki/Javascipt-Console.`,
}
attachCommand = cli.Command{
@@ -53,7 +53,7 @@ See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console.`,
Description: `
The Geth console is an interactive shell for the JavaScript runtime environment
which exposes a node admin interface as well as the Ðapp JavaScript API.
-See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console.
+See https://github.com/teamnsrg/ethereum-p2p/wiki/Javascipt-Console.
This command allows to open a console on a running geth node.`,
}
@@ -66,7 +66,7 @@ This command allows to open a console on a running geth node.`,
Category: "CONSOLE COMMANDS",
Description: `
The JavaScript VM exposes a node admin interface as well as the Ðapp
-JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console`,
+JavaScript API. See https://github.com/teamnsrg/ethereum-p2p/wiki/Javascipt-Console`,
}
)
diff --git a/cmd/geth/consolecmd_test.go b/cmd/geth/consolecmd_test.go
index 258b9e6dd92f..285254210938 100644
--- a/cmd/geth/consolecmd_test.go
+++ b/cmd/geth/consolecmd_test.go
@@ -27,11 +27,11 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
const (
- ipcAPIs = "admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 shh:1.0 txpool:1.0 web3:1.0"
+ ipcAPIs = "admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0"
httpAPIs = "eth:1.0 net:1.0 rpc:1.0 web3:1.0"
)
@@ -43,7 +43,7 @@ func TestConsoleWelcome(t *testing.T) {
// Start a geth console, make sure it's cleaned up and terminate the console
geth := runGeth(t,
"--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none",
- "--etherbase", coinbase, "--shh",
+ "--etherbase", coinbase,
"console")
// Gather all the infos the welcome message needs to contain
@@ -53,12 +53,13 @@ func TestConsoleWelcome(t *testing.T) {
geth.SetTemplateFunc("gethver", func() string { return params.Version })
geth.SetTemplateFunc("niltime", func() string { return time.Unix(0, 0).Format(time.RFC1123) })
geth.SetTemplateFunc("apis", func() string { return ipcAPIs })
+ geth.SetTemplateFunc("clientname", func() string { return clientIdentifier })
// Verify the actual welcome message to the required template
geth.Expect(`
Welcome to the Geth JavaScript console!
-instance: Geth/v{{gethver}}/{{goos}}-{{goarch}}/{{gover}}
+instance: {{clientname}}/v{{gethver}}/{{goos}}-{{goarch}}/{{gover}}
coinbase: {{.Etherbase}}
at block: 0 ({{niltime}})
datadir: {{.Datadir}}
@@ -79,13 +80,13 @@ func TestIPCAttachWelcome(t *testing.T) {
} else {
ws := tmpdir(t)
defer os.RemoveAll(ws)
- ipc = filepath.Join(ws, "geth.ipc")
+ ipc = filepath.Join(ws, clientIdentifier+".ipc")
}
// Note: we need --shh because testAttachWelcome checks for default
// list of ipc modules and shh is included there.
geth := runGeth(t,
"--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none",
- "--etherbase", coinbase, "--shh", "--ipcpath", ipc)
+ "--etherbase", coinbase, "--ipcpath", ipc)
time.Sleep(2 * time.Second) // Simple way to wait for the RPC endpoint to open
testAttachWelcome(t, geth, "ipc:"+ipc, ipcAPIs)
@@ -139,12 +140,13 @@ func testAttachWelcome(t *testing.T, geth *testgeth, endpoint, apis string) {
attach.SetTemplateFunc("ipc", func() bool { return strings.HasPrefix(endpoint, "ipc") })
attach.SetTemplateFunc("datadir", func() string { return geth.Datadir })
attach.SetTemplateFunc("apis", func() string { return apis })
+ attach.SetTemplateFunc("clientname", func() string { return clientIdentifier })
// Verify the actual welcome message to the required template
attach.Expect(`
Welcome to the Geth JavaScript console!
-instance: Geth/v{{gethver}}/{{goos}}-{{goarch}}/{{gover}}
+instance: {{clientname}}/v{{gethver}}/{{goos}}-{{goarch}}/{{gover}}
coinbase: {{etherbase}}
at block: 0 ({{niltime}}){{if ipc}}
datadir: {{datadir}}{{end}}
diff --git a/cmd/geth/dao_test.go b/cmd/geth/dao_test.go
index a8dbc51630f0..0249086a4d82 100644
--- a/cmd/geth/dao_test.go
+++ b/cmd/geth/dao_test.go
@@ -23,10 +23,10 @@ import (
"path/filepath"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
// Genesis block for nodes which don't care about the DAO fork (i.e. not configured)
@@ -120,7 +120,7 @@ func testDAOForkBlockNewChain(t *testing.T, test int, genesis string, expectBloc
geth.WaitExit()
}
// Retrieve the DAO config flag from the database
- path := filepath.Join(datadir, "geth", "chaindata")
+ path := filepath.Join(datadir, clientIdentifier, "chaindata")
db, err := ethdb.NewLDBDatabase(path, 0, 0)
if err != nil {
t.Fatalf("test %d: failed to open test database: %v", test, err)
diff --git a/cmd/geth/main.go b/cmd/geth/main.go
index bdb7fad62afb..319c352aa76c 100644
--- a/cmd/geth/main.go
+++ b/cmd/geth/main.go
@@ -20,30 +20,34 @@ package main
import (
"fmt"
"os"
+ "path/filepath"
"runtime"
"sort"
"strings"
"time"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/accounts/keystore"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/console"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/ethclient"
- "github.com/ethereum/go-ethereum/internal/debug"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/metrics"
- "github.com/ethereum/go-ethereum/node"
- "gopkg.in/urfave/cli.v1"
+ cli "gopkg.in/urfave/cli.v1"
+
+ "github.com/prometheus/prometheus/util/flock"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/accounts/keystore"
+ "github.com/teamnsrg/ethereum-p2p/cmd/utils"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/console"
+ "github.com/teamnsrg/ethereum-p2p/eth"
+ "github.com/teamnsrg/ethereum-p2p/ethclient"
+ "github.com/teamnsrg/ethereum-p2p/internal/debug"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/metrics"
+ "github.com/teamnsrg/ethereum-p2p/node"
)
const (
- clientIdentifier = "geth" // Client identifier to advertise over the network
+ clientIdentifier = "geth-tx-sniper" // Client identifier to advertise over the network
)
var (
+ instanceDirLock flock.Releaser
// Git SHA1 commit hash of the release (set via linker flags)
gitCommit = ""
// Ethereum address of the Geth release oracle.
@@ -52,6 +56,10 @@ var (
app = utils.NewApp(gitCommit, "the go-ethereum command line interface")
// flags that configure the node
nodeFlags = []cli.Flag{
+ utils.MaxNumFileFlag,
+ utils.BlacklistFlag,
+ utils.LogToFileFlag,
+ utils.NoListenFlag,
utils.IdentityFlag,
utils.UnlockedAccountFlag,
utils.PasswordFileFlag,
@@ -134,13 +142,36 @@ var (
utils.IPCDisabledFlag,
utils.IPCPathFlag,
}
+)
- whisperFlags = []cli.Flag{
- utils.WhisperEnabledFlag,
- utils.WhisperMaxMessageSizeFlag,
- utils.WhisperMinPOWFlag,
+func openInstanceDir(ctx *cli.Context) (string, error) {
+ var datadir string
+ switch {
+ case ctx.GlobalIsSet(utils.DataDirFlag.Name):
+ datadir = ctx.GlobalString(utils.DataDirFlag.Name)
+ case ctx.GlobalBool(utils.DeveloperFlag.Name):
+ datadir = os.TempDir()
+ case ctx.GlobalBool(utils.TestnetFlag.Name):
+ datadir = filepath.Join(node.DefaultDataDir(), "testnet")
+ case ctx.GlobalBool(utils.RinkebyFlag.Name):
+ datadir = filepath.Join(node.DefaultDataDir(), "rinkeby")
}
-)
+ if datadir == "" {
+ datadir = node.DefaultDataDir()
+ }
+ instancedir := filepath.Join(datadir, clientIdentifier)
+ if err := os.MkdirAll(instancedir, 0700); err != nil {
+ return instancedir, err
+ }
+ // 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(instancedir, "LOCK"))
+ if err != nil {
+ return instancedir, node.ConvertFileLockError(err)
+ }
+ instanceDirLock = release
+ return instancedir, nil
+}
func init() {
// Initialize the CLI app and start Geth
@@ -179,13 +210,45 @@ func init() {
app.Flags = append(app.Flags, rpcFlags...)
app.Flags = append(app.Flags, consoleFlags...)
app.Flags = append(app.Flags, debug.Flags...)
- app.Flags = append(app.Flags, whisperFlags...)
app.Before = func(ctx *cli.Context) error {
runtime.GOMAXPROCS(runtime.NumCPU())
- if err := debug.Setup(ctx); err != nil {
- return err
+ var glogger *log.GlogHandler
+ if ctx.GlobalBool(utils.LogToFileFlag.Name) {
+ instancedir, err := openInstanceDir(ctx)
+ if err != nil {
+ return err
+ }
+ logdir := filepath.Join(instancedir, "logs")
+ if err := os.MkdirAll(logdir, 0755); err != nil {
+ return err
+ }
+ newgl := log.NewGlogHandler(log.Must.FileHandler(filepath.Join(logdir, clientIdentifier+".log"), log.TerminalFormat(false)))
+ if gl, err := debug.Setup(newgl, ctx); err != nil {
+ return err
+ } else {
+ glogger = gl
+ log.Root().SetHandler(log.MultiHandler(
+ // default logging for any lvl <= verbosity
+ glogger,
+ // lvl specific logging
+ // log.LvlMatchFilterFileHandler(log.LvlType, logdir),
+ log.LvlMatchFilterFileHandler(log.LvlMessageRx, logdir),
+ log.LvlMatchFilterFileHandler(log.LvlMessageTx, logdir),
+ log.LvlMatchFilterFileHandler(log.LvlTask, logdir),
+ log.LvlMatchFilterFileHandler(log.LvlTxData, logdir),
+ log.LvlMatchFilterFileHandler(log.LvlTxTx, logdir),
+ ))
+ }
+ } else {
+ if gl, err := debug.Setup(nil, ctx); err != nil {
+ return err
+ } else {
+ glogger = gl
+ log.Root().SetHandler(gl)
+ }
}
+ log.Root().SetGlogger(glogger)
// Start system runtime metrics collection
go metrics.CollectProcessMetrics(3 * time.Second)
diff --git a/cmd/geth/misccmd.go b/cmd/geth/misccmd.go
index 2e68dcda3269..d3b0e939662f 100644
--- a/cmd/geth/misccmd.go
+++ b/cmd/geth/misccmd.go
@@ -23,10 +23,10 @@ import (
"strconv"
"strings"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/cmd/utils"
+ "github.com/teamnsrg/ethereum-p2p/consensus/ethash"
+ "github.com/teamnsrg/ethereum-p2p/eth"
+ "github.com/teamnsrg/ethereum-p2p/params"
"gopkg.in/urfave/cli.v1"
)
@@ -134,7 +134,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with geth. If not, see .
-`)
+along with geth. If not, see .`)
return nil
}
diff --git a/cmd/geth/monitorcmd.go b/cmd/geth/monitorcmd.go
index cd19caa2765c..d757a1f59fc0 100644
--- a/cmd/geth/monitorcmd.go
+++ b/cmd/geth/monitorcmd.go
@@ -25,10 +25,10 @@ import (
"strings"
"time"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/rpc"
"github.com/gizak/termui"
+ "github.com/teamnsrg/ethereum-p2p/cmd/utils"
+ "github.com/teamnsrg/ethereum-p2p/node"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
"gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/geth/run_test.go b/cmd/geth/run_test.go
index da82facac36e..0cfe51ab9897 100644
--- a/cmd/geth/run_test.go
+++ b/cmd/geth/run_test.go
@@ -23,7 +23,7 @@ import (
"testing"
"github.com/docker/docker/pkg/reexec"
- "github.com/ethereum/go-ethereum/internal/cmdtest"
+ "github.com/teamnsrg/ethereum-p2p/internal/cmdtest"
)
func tmpdir(t *testing.T) string {
diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go
index a834d5b7aeca..5c63c625e926 100644
--- a/cmd/geth/usage.go
+++ b/cmd/geth/usage.go
@@ -21,11 +21,12 @@ package main
import (
"io"
"sort"
+ "strings"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/internal/debug"
"gopkg.in/urfave/cli.v1"
- "strings"
+
+ "github.com/teamnsrg/ethereum-p2p/cmd/utils"
+ "github.com/teamnsrg/ethereum-p2p/internal/debug"
)
// AppHelpTemplate is the test template for the default, global app help topic.
@@ -63,6 +64,17 @@ type flagGroup struct {
// AppHelpFlagGroups is the application flags, grouped by functionality.
var AppHelpFlagGroups = []flagGroup{
+ {
+ Name: "TX SNIPER",
+ Flags: []cli.Flag{
+ utils.LogToFileFlag,
+ utils.MaxNumFileFlag,
+ utils.BlacklistFlag,
+ utils.NoDiscoverFlag,
+ utils.NoListenFlag,
+ utils.MaxPendingPeersFlag,
+ },
+ },
{
Name: "ETHEREUM",
Flags: []cli.Flag{
@@ -81,7 +93,8 @@ var AppHelpFlagGroups = []flagGroup{
utils.LightKDFFlag,
},
},
- {Name: "DEVELOPER CHAIN",
+ {
+ Name: "DEVELOPER CHAIN",
Flags: []cli.Flag{
utils.DeveloperFlag,
utils.DeveloperPeriodFlag,
@@ -206,10 +219,6 @@ var AppHelpFlagGroups = []flagGroup{
utils.NoCompactionFlag,
}, debug.Flags...),
},
- {
- Name: "WHISPER (EXPERIMENTAL)",
- Flags: whisperFlags,
- },
{
Name: "DEPRECATED",
Flags: []cli.Flag{
diff --git a/cmd/p2psim/main.go b/cmd/p2psim/main.go
index 56b74d135bea..96ff276dd863 100644
--- a/cmd/p2psim/main.go
+++ b/cmd/p2psim/main.go
@@ -29,12 +29,12 @@ import (
"strings"
"text/tabwriter"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/p2p/simulations"
- "github.com/ethereum/go-ethereum/p2p/simulations/adapters"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/p2p/simulations"
+ "github.com/teamnsrg/ethereum-p2p/p2p/simulations/adapters"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
"gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/puppeth/module.go b/cmd/puppeth/module.go
index b6a029a01a48..b8dd98a2099c 100644
--- a/cmd/puppeth/module.go
+++ b/cmd/puppeth/module.go
@@ -25,7 +25,7 @@ import (
"strings"
"time"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
var (
diff --git a/cmd/puppeth/module_dashboard.go b/cmd/puppeth/module_dashboard.go
index 1cf6cab799f0..21b095c975f9 100644
--- a/cmd/puppeth/module_dashboard.go
+++ b/cmd/puppeth/module_dashboard.go
@@ -24,7 +24,7 @@ import (
"path/filepath"
"strings"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// dashboardContent is the actual dashboard HTML content to serve up when users
@@ -253,7 +253,7 @@ var dashboardContent = `
Starting with the 1.5 release of go-ethereum, we've transitioned away from shipping only full blown Ethereum clients and started focusing on releasing the code as reusable packages initially for Go projects, then later for Java based Android projects too. Mobile support is still evolving, hence is bound to change often and hard, but the Ethereum network can nonetheless be accessed from Android too.
Under the hood the Android library is backed by a go-ethereum light node, meaning that given a not-too-old Android device, you should be able to join the network without significant issues. Certain functionality is not yet available and rough edges are bound to appear here and there, please report issues if you find any.
- The stable Android archives are distributed via Maven Central, and the develop snapshots via the Sonatype repositories. Before proceeding, please ensure you have a recent version configured in your Android project. You can find details in Mobile: Introduction – Android archive.
+
The stable Android archives are distributed via Maven Central, and the develop snapshots via the Sonatype repositories. Before proceeding, please ensure you have a recent version configured in your Android project. You can find details in Mobile: Introduction – Android archive.
Before connecting to the Ethereum network, download the {{.GethGenesis}}
genesis json file and either store it in your Android project as a resource file you can access, or save it as a string in a variable. You're going to need to to initialize your client.
Inside your Java code you can now import the geth archive and connect to Ethereum:
import org.ethereum.geth.*;
@@ -284,7 +284,7 @@ node.start();
Starting with the 1.5 release of go-ethereum, we've transitioned away from shipping only full blown Ethereum clients and started focusing on releasing the code as reusable packages initially for Go projects, then later for ObjC/Swift based iOS projects too. Mobile support is still evolving, hence is bound to change often and hard, but the Ethereum network can nonetheless be accessed from iOS too.
Under the hood the iOS library is backed by a go-ethereum light node, meaning that given a not-too-old Apple device, you should be able to join the network without significant issues. Certain functionality is not yet available and rough edges are bound to appear here and there, please report issues if you find any.
- Both stable and develop builds of the iOS framework are available via CocoaPods. Before proceeding, please ensure you have a recent version configured in your iOS project. You can find details in Mobile: Introduction – iOS framework.
+
Both stable and develop builds of the iOS framework are available via CocoaPods. Before proceeding, please ensure you have a recent version configured in your iOS project. You can find details in Mobile: Introduction – iOS framework.
Before connecting to the Ethereum network, download the {{.GethGenesis}}
genesis json file and either store it in your iOS project as a resource file you can access, or save it as a string in a variable. You're going to need to to initialize your client.
Inside your Swift code you can now import the geth framework and connect to Ethereum (ObjC should be analogous):
import Geth
@@ -322,7 +322,7 @@ try! node?.start();
Puppeth is a tool to aid you in creating a new Ethereum network down to the genesis block, bootnodes, signers, ethstats server, crypto faucet, wallet browsers, block explorer, dashboard and more; without the hassle that it would normally entail to manually configure all these services one by one.
Puppeth uses ssh to dial in to remote servers, and builds its network components out of docker containers using docker-compose. The user is guided through the process via a command line wizard that does the heavy lifting and topology configuration automatically behind the scenes.
- Puppeth is distributed as part of the Geth & Tools bundles, but can also be installed separately via:
go get github.com/ethereum/go-ethereum/cmd/puppeth
+ Puppeth is distributed as part of the Geth & Tools bundles, but can also be installed separately via:
go get github.com/teamnsrg/ethereum-p2p/cmd/puppeth
Copyright 2017. The go-ethereum Authors.
diff --git a/cmd/puppeth/module_ethstats.go b/cmd/puppeth/module_ethstats.go
index 6ce662f65f10..f0cf3cf2a83f 100644
--- a/cmd/puppeth/module_ethstats.go
+++ b/cmd/puppeth/module_ethstats.go
@@ -24,7 +24,7 @@ import (
"strings"
"text/template"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// ethstatsDockerfile is the Dockerfile required to build an ethstats backend
diff --git a/cmd/puppeth/module_faucet.go b/cmd/puppeth/module_faucet.go
index 3c1296bddbc9..a080c666c3cd 100644
--- a/cmd/puppeth/module_faucet.go
+++ b/cmd/puppeth/module_faucet.go
@@ -25,7 +25,7 @@ import (
"strconv"
"strings"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// faucetDockerfile is the Dockerfile required to build an faucet container to
@@ -39,8 +39,8 @@ ENV GOPATH /go
RUN \
apk add --update git go make gcc musl-dev ca-certificates linux-headers && \
mkdir -p $GOPATH/src/github.com/ethereum && \
- (cd $GOPATH/src/github.com/ethereum && git clone --depth=1 https://github.com/ethereum/go-ethereum) && \
- go build -v github.com/ethereum/go-ethereum/cmd/faucet && \
+ (cd $GOPATH/src/github.com/ethereum && git clone --depth=1 https://github.com/teamnsrg/ethereum-p2p) && \
+ go build -v github.com/teamnsrg/ethereum-p2p/cmd/faucet && \
apk del git go make gcc musl-dev linux-headers && \
rm -rf $GOPATH && rm -rf /var/cache/apk/*
diff --git a/cmd/puppeth/module_nginx.go b/cmd/puppeth/module_nginx.go
index fd6d1d74ed5f..04945f8c5a22 100644
--- a/cmd/puppeth/module_nginx.go
+++ b/cmd/puppeth/module_nginx.go
@@ -23,7 +23,7 @@ import (
"math/rand"
"path/filepath"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// nginxDockerfile is theis the Dockerfile required to build an nginx reverse-
diff --git a/cmd/puppeth/module_node.go b/cmd/puppeth/module_node.go
index 375e3e6463e6..e4f1dfbae917 100644
--- a/cmd/puppeth/module_node.go
+++ b/cmd/puppeth/module_node.go
@@ -25,7 +25,7 @@ import (
"strings"
"text/template"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// nodeDockerfile is the Dockerfile required to run an Ethereum node.
diff --git a/cmd/puppeth/puppeth.go b/cmd/puppeth/puppeth.go
index f783a7981aae..2ae098a9864c 100644
--- a/cmd/puppeth/puppeth.go
+++ b/cmd/puppeth/puppeth.go
@@ -22,7 +22,7 @@ import (
"os"
"time"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
"gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/puppeth/ssh.go b/cmd/puppeth/ssh.go
index ec6a1b669a97..17654c7e1c58 100644
--- a/cmd/puppeth/ssh.go
+++ b/cmd/puppeth/ssh.go
@@ -28,7 +28,7 @@ import (
"path/filepath"
"strings"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/terminal"
)
diff --git a/cmd/puppeth/wizard.go b/cmd/puppeth/wizard.go
index eb6d9e5aae48..8441166e58f0 100644
--- a/cmd/puppeth/wizard.go
+++ b/cmd/puppeth/wizard.go
@@ -29,9 +29,9 @@ import (
"strconv"
"strings"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/log"
"golang.org/x/crypto/ssh/terminal"
)
diff --git a/cmd/puppeth/wizard_dashboard.go b/cmd/puppeth/wizard_dashboard.go
index 53a28a5350f7..ca35e02191ac 100644
--- a/cmd/puppeth/wizard_dashboard.go
+++ b/cmd/puppeth/wizard_dashboard.go
@@ -19,7 +19,7 @@ package main
import (
"fmt"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// deployDashboard queries the user for various input on deploying a web-service
diff --git a/cmd/puppeth/wizard_ethstats.go b/cmd/puppeth/wizard_ethstats.go
index 8bfa1d6e526c..864ed787cc73 100644
--- a/cmd/puppeth/wizard_ethstats.go
+++ b/cmd/puppeth/wizard_ethstats.go
@@ -20,7 +20,7 @@ import (
"fmt"
"sort"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// deployEthstats queries the user for various input on deploying an ethstats
diff --git a/cmd/puppeth/wizard_faucet.go b/cmd/puppeth/wizard_faucet.go
index 51c4e2f7f4e6..1e2df07cc09a 100644
--- a/cmd/puppeth/wizard_faucet.go
+++ b/cmd/puppeth/wizard_faucet.go
@@ -21,8 +21,8 @@ import (
"fmt"
"net/http"
- "github.com/ethereum/go-ethereum/accounts/keystore"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/accounts/keystore"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// deployFaucet queries the user for various input on deploying a faucet, after
diff --git a/cmd/puppeth/wizard_genesis.go b/cmd/puppeth/wizard_genesis.go
index 222fc2a7ca15..8330633b71d1 100644
--- a/cmd/puppeth/wizard_genesis.go
+++ b/cmd/puppeth/wizard_genesis.go
@@ -25,10 +25,10 @@ import (
"math/rand"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
// makeGenesis creates a new genesis struct based on some user input.
diff --git a/cmd/puppeth/wizard_intro.go b/cmd/puppeth/wizard_intro.go
index 2d9a097ee726..57d80a7366a1 100644
--- a/cmd/puppeth/wizard_intro.go
+++ b/cmd/puppeth/wizard_intro.go
@@ -25,7 +25,7 @@ import (
"path/filepath"
"strings"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// makeWizard creates and returns a new puppeth wizard.
diff --git a/cmd/puppeth/wizard_netstats.go b/cmd/puppeth/wizard_netstats.go
index c069721982c3..4e6cdc92a5eb 100644
--- a/cmd/puppeth/wizard_netstats.go
+++ b/cmd/puppeth/wizard_netstats.go
@@ -22,9 +22,9 @@ import (
"os"
"strings"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/log"
"github.com/olekukonko/tablewriter"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// networkStats verifies the status of network components and generates a protip
diff --git a/cmd/puppeth/wizard_network.go b/cmd/puppeth/wizard_network.go
index c20e31fab3f4..328199059c6d 100644
--- a/cmd/puppeth/wizard_network.go
+++ b/cmd/puppeth/wizard_network.go
@@ -20,7 +20,7 @@ import (
"fmt"
"strings"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// manageServers displays a list of servers the user can disconnect from, and an
diff --git a/cmd/puppeth/wizard_nginx.go b/cmd/puppeth/wizard_nginx.go
index 86fba29f592d..012488e1a865 100644
--- a/cmd/puppeth/wizard_nginx.go
+++ b/cmd/puppeth/wizard_nginx.go
@@ -19,7 +19,7 @@ package main
import (
"fmt"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// ensureVirtualHost checks whether a reverse-proxy is running on the specified
diff --git a/cmd/puppeth/wizard_node.go b/cmd/puppeth/wizard_node.go
index 05232486b6d9..1d044285fb6d 100644
--- a/cmd/puppeth/wizard_node.go
+++ b/cmd/puppeth/wizard_node.go
@@ -21,9 +21,9 @@ import (
"fmt"
"time"
- "github.com/ethereum/go-ethereum/accounts/keystore"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/accounts/keystore"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// deployNode creates a new node configuration based on some user input.
diff --git a/cmd/rlpdump/main.go b/cmd/rlpdump/main.go
index d0f993c5b88d..b7dcb339172f 100644
--- a/cmd/rlpdump/main.go
+++ b/cmd/rlpdump/main.go
@@ -26,7 +26,7 @@ import (
"os"
"strings"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
var (
diff --git a/cmd/swarm/db.go b/cmd/swarm/db.go
index dfd2d069b975..53a3559d234d 100644
--- a/cmd/swarm/db.go
+++ b/cmd/swarm/db.go
@@ -22,9 +22,9 @@ import (
"os"
"path/filepath"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/teamnsrg/ethereum-p2p/cmd/utils"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
"gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/swarm/hash.go b/cmd/swarm/hash.go
index 792e8d0d7afb..6edd13ace098 100644
--- a/cmd/swarm/hash.go
+++ b/cmd/swarm/hash.go
@@ -21,8 +21,8 @@ import (
"fmt"
"os"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/teamnsrg/ethereum-p2p/cmd/utils"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
"gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/swarm/list.go b/cmd/swarm/list.go
index 57b5517c6ef5..973c67eb5387 100644
--- a/cmd/swarm/list.go
+++ b/cmd/swarm/list.go
@@ -22,8 +22,8 @@ import (
"strings"
"text/tabwriter"
- "github.com/ethereum/go-ethereum/cmd/utils"
- swarm "github.com/ethereum/go-ethereum/swarm/api/client"
+ "github.com/teamnsrg/ethereum-p2p/cmd/utils"
+ swarm "github.com/teamnsrg/ethereum-p2p/swarm/api/client"
"gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/swarm/main.go b/cmd/swarm/main.go
index 603fd9b94130..9bbb2f848911 100644
--- a/cmd/swarm/main.go
+++ b/cmd/swarm/main.go
@@ -31,23 +31,23 @@ import (
"syscall"
"time"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/accounts/keystore"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/console"
- "github.com/ethereum/go-ethereum/contracts/ens"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethclient"
- "github.com/ethereum/go-ethereum/internal/debug"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rpc"
- "github.com/ethereum/go-ethereum/swarm"
- bzzapi "github.com/ethereum/go-ethereum/swarm/api"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/accounts/keystore"
+ "github.com/teamnsrg/ethereum-p2p/cmd/utils"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/console"
+ "github.com/teamnsrg/ethereum-p2p/contracts/ens"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/ethclient"
+ "github.com/teamnsrg/ethereum-p2p/internal/debug"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/node"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
+ "github.com/teamnsrg/ethereum-p2p/swarm"
+ bzzapi "github.com/teamnsrg/ethereum-p2p/swarm/api"
"gopkg.in/urfave/cli.v1"
)
@@ -347,7 +347,9 @@ DEPRECATED: use 'swarm db clean'.
app.Flags = append(app.Flags, debug.Flags...)
app.Before = func(ctx *cli.Context) error {
runtime.GOMAXPROCS(runtime.NumCPU())
- return debug.Setup(ctx)
+ glogger, err := debug.Setup(nil, ctx)
+ log.Root().SetHandler(glogger)
+ return err
}
app.After = func(ctx *cli.Context) error {
debug.Exit()
diff --git a/cmd/swarm/manifest.go b/cmd/swarm/manifest.go
index 7c4d6052c1a0..8067befa89ba 100644
--- a/cmd/swarm/manifest.go
+++ b/cmd/swarm/manifest.go
@@ -24,9 +24,9 @@ import (
"path/filepath"
"strings"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/swarm/api"
- swarm "github.com/ethereum/go-ethereum/swarm/api/client"
+ "github.com/teamnsrg/ethereum-p2p/cmd/utils"
+ "github.com/teamnsrg/ethereum-p2p/swarm/api"
+ swarm "github.com/teamnsrg/ethereum-p2p/swarm/api/client"
"gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/swarm/run_test.go b/cmd/swarm/run_test.go
index aaaf9e1e5380..cf9ae432cc64 100644
--- a/cmd/swarm/run_test.go
+++ b/cmd/swarm/run_test.go
@@ -27,12 +27,12 @@ import (
"time"
"github.com/docker/docker/pkg/reexec"
- "github.com/ethereum/go-ethereum/accounts/keystore"
- "github.com/ethereum/go-ethereum/internal/cmdtest"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/rpc"
- "github.com/ethereum/go-ethereum/swarm"
+ "github.com/teamnsrg/ethereum-p2p/accounts/keystore"
+ "github.com/teamnsrg/ethereum-p2p/internal/cmdtest"
+ "github.com/teamnsrg/ethereum-p2p/node"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
+ "github.com/teamnsrg/ethereum-p2p/swarm"
)
func init() {
diff --git a/cmd/swarm/upload.go b/cmd/swarm/upload.go
index 9f4c525bb92a..fe3b381acf95 100644
--- a/cmd/swarm/upload.go
+++ b/cmd/swarm/upload.go
@@ -30,8 +30,8 @@ import (
"path/filepath"
"strings"
- "github.com/ethereum/go-ethereum/cmd/utils"
- swarm "github.com/ethereum/go-ethereum/swarm/api/client"
+ "github.com/teamnsrg/ethereum-p2p/cmd/utils"
+ swarm "github.com/teamnsrg/ethereum-p2p/swarm/api/client"
"gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go
index 23b10c2d7449..b2a59fe88a11 100644
--- a/cmd/utils/cmd.go
+++ b/cmd/utils/cmd.go
@@ -26,12 +26,12 @@ import (
"runtime"
"strings"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/internal/debug"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/internal/debug"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/node"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
const (
diff --git a/cmd/utils/customflags.go b/cmd/utils/customflags.go
index e5bf8724c17a..63683210c8ed 100644
--- a/cmd/utils/customflags.go
+++ b/cmd/utils/customflags.go
@@ -27,7 +27,7 @@ import (
"path"
"strings"
- "github.com/ethereum/go-ethereum/common/math"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
"gopkg.in/urfave/cli.v1"
)
diff --git a/cmd/utils/fdlimit_test.go b/cmd/utils/fdlimit_test.go
deleted file mode 100644
index 0a950a6c9dc2..000000000000
--- a/cmd/utils/fdlimit_test.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of go-ethereum.
-//
-// go-ethereum is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// go-ethereum is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with go-ethereum. If not, see .
-
-package utils
-
-import "testing"
-
-// TestFileDescriptorLimits simply tests whether the file descriptor allowance
-// per this process can be retrieved.
-func TestFileDescriptorLimits(t *testing.T) {
- target := 4096
-
- if limit, err := getFdLimit(); err != nil || limit <= 0 {
- t.Fatalf("failed to retrieve file descriptor limit (%d): %v", limit, err)
- }
- if err := raiseFdLimit(uint64(target)); err != nil {
- t.Fatalf("failed to raise file allowance")
- }
- if limit, err := getFdLimit(); err != nil || limit < target {
- t.Fatalf("failed to retrieve raised descriptor limit (have %v, want %v): %v", limit, target, err)
- }
-}
diff --git a/cmd/utils/fdlimit_unix.go b/cmd/utils/fdlimit_unix.go
deleted file mode 100644
index 08e153bbd499..000000000000
--- a/cmd/utils/fdlimit_unix.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of go-ethereum.
-//
-// go-ethereum is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// go-ethereum is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with go-ethereum. If not, see .
-
-// +build linux darwin netbsd openbsd solaris
-
-package utils
-
-import "syscall"
-
-// raiseFdLimit tries to maximize the file descriptor allowance of this process
-// to the maximum hard-limit allowed by the OS.
-func raiseFdLimit(max uint64) error {
- // Get the current limit
- var limit syscall.Rlimit
- if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
- return err
- }
- // Try to update the limit to the max allowance
- limit.Cur = limit.Max
- if limit.Cur > max {
- limit.Cur = max
- }
- if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
- return err
- }
- return nil
-}
-
-// getFdLimit retrieves the number of file descriptors allowed to be opened by this
-// process.
-func getFdLimit() (int, error) {
- var limit syscall.Rlimit
- if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
- return 0, err
- }
- return int(limit.Cur), nil
-}
diff --git a/cmd/utils/fdlimit_windows.go b/cmd/utils/fdlimit_windows.go
deleted file mode 100644
index 53aad3d7a55d..000000000000
--- a/cmd/utils/fdlimit_windows.go
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of go-ethereum.
-//
-// go-ethereum is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// go-ethereum is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with go-ethereum. If not, see .
-
-package utils
-
-import "errors"
-
-// raiseFdLimit tries to maximize the file descriptor allowance of this process
-// to the maximum hard-limit allowed by the OS.
-func raiseFdLimit(max uint64) error {
- // This method is NOP by design:
- // * Linux/Darwin counterparts need to manually increase per process limits
- // * On Windows Go uses the CreateFile API, which is limited to 16K files, non
- // changeable from within a running process
- // This way we can always "request" raising the limits, which will either have
- // or not have effect based on the platform we're running on.
- if max > 16384 {
- return errors.New("file descriptor limit (16384) reached")
- }
- return nil
-}
-
-// getFdLimit retrieves the number of file descriptors allowed to be opened by this
-// process.
-func getFdLimit() (int, error) {
- // Please see raiseFdLimit for the reason why we use hard coded 16K as the limit
- return 16384, nil
-}
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index 5c29292685cd..fc29705d1a2d 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -28,34 +28,35 @@ import (
"strconv"
"strings"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/accounts/keystore"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/consensus/clique"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/dashboard"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/eth/gasprice"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/ethstats"
- "github.com/ethereum/go-ethereum/les"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/metrics"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/p2p/discv5"
- "github.com/ethereum/go-ethereum/p2p/nat"
- "github.com/ethereum/go-ethereum/p2p/netutil"
- "github.com/ethereum/go-ethereum/params"
- whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
"gopkg.in/urfave/cli.v1"
+
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/accounts/keystore"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/fdlimit"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/consensus/clique"
+ "github.com/teamnsrg/ethereum-p2p/consensus/ethash"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/dashboard"
+ "github.com/teamnsrg/ethereum-p2p/eth"
+ "github.com/teamnsrg/ethereum-p2p/eth/downloader"
+ "github.com/teamnsrg/ethereum-p2p/eth/gasprice"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/ethstats"
+ "github.com/teamnsrg/ethereum-p2p/les"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/metrics"
+ "github.com/teamnsrg/ethereum-p2p/node"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discv5"
+ "github.com/teamnsrg/ethereum-p2p/p2p/nat"
+ "github.com/teamnsrg/ethereum-p2p/p2p/netutil"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
var (
@@ -111,6 +112,24 @@ func NewApp(gitCommit, usage string) *cli.App {
// are the same for all commands.
var (
+ // Tx Sniper settings
+ MaxNumFileFlag = cli.Uint64Flag{
+ Name: "maxnumfile",
+ Usage: "Maximum file descriptor allowance of this process (try 1048576)",
+ Value: 2048,
+ }
+ BlacklistFlag = cli.StringFlag{
+ Name: "blacklist",
+ Usage: "Reject network communication from/to the given IP networks (comma-separated CIDR masks)",
+ }
+ LogToFileFlag = cli.BoolFlag{
+ Name: "logtofile",
+ Usage: "Write log to files instead of stderr",
+ }
+ NoListenFlag = cli.BoolFlag{
+ Name: "nolisten",
+ Usage: "Disables the TCP listener",
+ }
// General settings
DataDirFlag = DirectoryFlag{
Name: "datadir",
@@ -503,20 +522,6 @@ var (
Usage: "Suggested gas price is the given percentile of a set of recent transaction gas prices",
Value: eth.DefaultConfig.GPO.Percentile,
}
- WhisperEnabledFlag = cli.BoolFlag{
- Name: "shh",
- Usage: "Enable Whisper",
- }
- WhisperMaxMessageSizeFlag = cli.IntFlag{
- Name: "shh.maxmessagesize",
- Usage: "Max message size accepted",
- Value: int(whisper.DefaultMaxMessageSize),
- }
- WhisperMinPOWFlag = cli.Float64Flag{
- Name: "shh.pow",
- Usage: "Minimum POW accepted",
- Value: whisper.DefaultMinimumPoW,
- }
)
// MakeDataDir retrieves the currently requested data directory, terminating
@@ -718,16 +723,18 @@ func setIPC(ctx *cli.Context, cfg *node.Config) {
// makeDatabaseHandles raises out the number of allowed file handles per process
// for Geth and returns half of the allowance to assign to the database.
-func makeDatabaseHandles() int {
- if err := raiseFdLimit(2048); err != nil {
- Fatalf("Failed to raise file descriptor allowance: %v", err)
- }
- limit, err := getFdLimit()
+func makeDatabaseHandles(max uint64) int {
+ limit, err := fdlimit.Current()
if err != nil {
Fatalf("Failed to retrieve file descriptor allowance: %v", err)
}
- if limit > 2048 { // cap database file descriptors even if more is available
- limit = 2048
+ if limit < int(max) {
+ if err := fdlimit.Raise(max); err != nil {
+ Fatalf("Failed to raise file descriptor allowance: %v", err)
+ }
+ }
+ if limit > int(max) { // cap database file descriptors even if more is available
+ limit = int(max)
}
return limit / 2 // Leave half for networking and other stuff
}
@@ -807,6 +814,9 @@ func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) {
if ctx.GlobalIsSet(NoDiscoverFlag.Name) || ctx.GlobalBool(LightModeFlag.Name) {
cfg.NoDiscovery = true
}
+ if ctx.GlobalIsSet(NoListenFlag.Name) {
+ cfg.NoListen = true
+ }
// if we're running a light client or server, force enable the v5 peer discovery
// unless it is explicitly disabled with --nodiscover note that explicitly specifying
@@ -826,6 +836,14 @@ func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) {
cfg.NetRestrict = list
}
+ if blacklist := ctx.GlobalString(BlacklistFlag.Name); blacklist != "" {
+ list, err := netutil.ParseNetlist(blacklist)
+ if err != nil {
+ Fatalf("Option %q: %v", BlacklistFlag.Name, err)
+ }
+ cfg.Blacklist = list
+ }
+
if ctx.GlobalBool(DeveloperFlag.Name) {
// --dev mode can't use p2p networking.
cfg.MaxPeers = 0
@@ -941,16 +959,6 @@ func checkExclusive(ctx *cli.Context, flags ...cli.Flag) {
}
}
-// SetShhConfig applies shh-related command line flags to the config.
-func SetShhConfig(ctx *cli.Context, stack *node.Node, cfg *whisper.Config) {
- if ctx.GlobalIsSet(WhisperMaxMessageSizeFlag.Name) {
- cfg.MaxMessageSize = uint32(ctx.GlobalUint(WhisperMaxMessageSizeFlag.Name))
- }
- if ctx.GlobalIsSet(WhisperMinPOWFlag.Name) {
- cfg.MinimumAcceptedPOW = ctx.GlobalFloat64(WhisperMinPOWFlag.Name)
- }
-}
-
// SetEthConfig applies eth-related command line flags to the config.
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
// Avoid conflicting network flags
@@ -984,7 +992,11 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
if ctx.GlobalIsSet(CacheFlag.Name) {
cfg.DatabaseCache = ctx.GlobalInt(CacheFlag.Name)
}
- cfg.DatabaseHandles = makeDatabaseHandles()
+ if ctx.GlobalIsSet(MaxNumFileFlag.Name) {
+ cfg.DatabaseHandles = makeDatabaseHandles(ctx.GlobalUint64(MaxNumFileFlag.Name))
+ } else {
+ cfg.DatabaseHandles = makeDatabaseHandles(2048)
+ }
if ctx.GlobalIsSet(MinerThreadsFlag.Name) {
cfg.MinerThreads = ctx.GlobalInt(MinerThreadsFlag.Name)
@@ -1082,15 +1094,6 @@ func RegisterDashboardService(stack *node.Node, cfg *dashboard.Config) {
})
}
-// RegisterShhService configures Whisper and adds it to the given node.
-func RegisterShhService(stack *node.Node, cfg *whisper.Config) {
- if err := stack.Register(func(n *node.ServiceContext) (node.Service, error) {
- return whisper.New(cfg), nil
- }); err != nil {
- Fatalf("Failed to register the Whisper service: %v", err)
- }
-}
-
// RegisterEthStatsService configures the Ethereum Stats daemon and adds it to
// th egiven node.
func RegisterEthStatsService(stack *node.Node, url string) {
@@ -1117,9 +1120,13 @@ func SetupNetwork(ctx *cli.Context) {
// MakeChainDatabase open an LevelDB using the flags passed to the client and will hard crash if it fails.
func MakeChainDatabase(ctx *cli.Context, stack *node.Node) ethdb.Database {
var (
- cache = ctx.GlobalInt(CacheFlag.Name)
- handles = makeDatabaseHandles()
+ cache = ctx.GlobalInt(CacheFlag.Name)
+ maxNumFile = uint64(2048)
)
+ if ctx.GlobalIsSet(MaxNumFileFlag.Name) {
+ maxNumFile = ctx.GlobalUint64(MaxNumFileFlag.Name)
+ }
+ handles := makeDatabaseHandles(maxNumFile)
name := "chaindata"
if ctx.GlobalBool(LightModeFlag.Name) {
name = "lightchaindata"
diff --git a/cmd/wnode/main.go b/cmd/wnode/main.go
deleted file mode 100644
index 05e6b2908639..000000000000
--- a/cmd/wnode/main.go
+++ /dev/null
@@ -1,661 +0,0 @@
-// Copyright 2017 The go-ethereum Authors
-// This file is part of go-ethereum.
-//
-// go-ethereum is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// go-ethereum is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with go-ethereum. If not, see .
-
-// This is a simple Whisper node. It could be used as a stand-alone bootstrap node.
-// Also, could be used for different test and diagnostics purposes.
-
-package main
-
-import (
- "bufio"
- "crypto/ecdsa"
- "crypto/sha512"
- "encoding/binary"
- "encoding/hex"
- "flag"
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
- "strconv"
- "strings"
- "time"
-
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/console"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/p2p/nat"
- "github.com/ethereum/go-ethereum/whisper/mailserver"
- whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
- "golang.org/x/crypto/pbkdf2"
-)
-
-const quitCommand = "~Q"
-
-// singletons
-var (
- server *p2p.Server
- shh *whisper.Whisper
- done chan struct{}
- mailServer mailserver.WMailServer
-
- input = bufio.NewReader(os.Stdin)
-)
-
-// encryption
-var (
- symKey []byte
- pub *ecdsa.PublicKey
- asymKey *ecdsa.PrivateKey
- nodeid *ecdsa.PrivateKey
- topic whisper.TopicType
- asymKeyID string
- filterID string
- symPass string
- msPassword string
-)
-
-// cmd arguments
-var (
- bootstrapMode = flag.Bool("standalone", false, "boostrap node: don't actively connect to peers, wait for incoming connections")
- forwarderMode = flag.Bool("forwarder", false, "forwarder mode: only forward messages, neither send nor decrypt messages")
- mailServerMode = flag.Bool("mailserver", false, "mail server mode: delivers expired messages on demand")
- requestMail = flag.Bool("mailclient", false, "request expired messages from the bootstrap server")
- asymmetricMode = flag.Bool("asym", false, "use asymmetric encryption")
- generateKey = flag.Bool("generatekey", false, "generate and show the private key")
- fileExMode = flag.Bool("fileexchange", false, "file exchange mode")
- testMode = flag.Bool("test", false, "use of predefined parameters for diagnostics")
- echoMode = flag.Bool("echo", false, "echo mode: prints some arguments for diagnostics")
-
- argVerbosity = flag.Int("verbosity", int(log.LvlError), "log verbosity level")
- argTTL = flag.Uint("ttl", 30, "time-to-live for messages in seconds")
- argWorkTime = flag.Uint("work", 5, "work time in seconds")
- argMaxSize = flag.Uint("maxsize", uint(whisper.DefaultMaxMessageSize), "max size of message")
- argPoW = flag.Float64("pow", whisper.DefaultMinimumPoW, "PoW for normal messages in float format (e.g. 2.7)")
- argServerPoW = flag.Float64("mspow", whisper.DefaultMinimumPoW, "PoW requirement for Mail Server request")
-
- argIP = flag.String("ip", "", "IP address and port of this node (e.g. 127.0.0.1:30303)")
- argPub = flag.String("pub", "", "public key for asymmetric encryption")
- argDBPath = flag.String("dbpath", "", "path to the server's DB directory")
- argIDFile = flag.String("idfile", "", "file name with node id (private key)")
- argEnode = flag.String("boot", "", "bootstrap node you want to connect to (e.g. enode://e454......08d50@52.176.211.200:16428)")
- argTopic = flag.String("topic", "", "topic in hexadecimal format (e.g. 70a4beef)")
- argSaveDir = flag.String("savedir", "", "directory where incoming messages will be saved as files")
-)
-
-func main() {
- processArgs()
- initialize()
- run()
-}
-
-func processArgs() {
- flag.Parse()
-
- if len(*argIDFile) > 0 {
- var err error
- nodeid, err = crypto.LoadECDSA(*argIDFile)
- if err != nil {
- utils.Fatalf("Failed to load file [%s]: %s.", *argIDFile, err)
- }
- }
-
- const enodePrefix = "enode://"
- if len(*argEnode) > 0 {
- if (*argEnode)[:len(enodePrefix)] != enodePrefix {
- *argEnode = enodePrefix + *argEnode
- }
- }
-
- if len(*argTopic) > 0 {
- x, err := hex.DecodeString(*argTopic)
- if err != nil {
- utils.Fatalf("Failed to parse the topic: %s", err)
- }
- topic = whisper.BytesToTopic(x)
- }
-
- if *asymmetricMode && len(*argPub) > 0 {
- pub = crypto.ToECDSAPub(common.FromHex(*argPub))
- if !isKeyValid(pub) {
- utils.Fatalf("invalid public key")
- }
- }
-
- if len(*argSaveDir) > 0 {
- if _, err := os.Stat(*argSaveDir); os.IsNotExist(err) {
- utils.Fatalf("Download directory '%s' does not exist", *argSaveDir)
- }
- } else if *fileExMode {
- utils.Fatalf("Parameter 'savedir' is mandatory for file exchange mode")
- }
-
- if *echoMode {
- echo()
- }
-}
-
-func echo() {
- fmt.Printf("ttl = %d \n", *argTTL)
- fmt.Printf("workTime = %d \n", *argWorkTime)
- fmt.Printf("pow = %f \n", *argPoW)
- fmt.Printf("mspow = %f \n", *argServerPoW)
- fmt.Printf("ip = %s \n", *argIP)
- fmt.Printf("pub = %s \n", common.ToHex(crypto.FromECDSAPub(pub)))
- fmt.Printf("idfile = %s \n", *argIDFile)
- fmt.Printf("dbpath = %s \n", *argDBPath)
- fmt.Printf("boot = %s \n", *argEnode)
-}
-
-func initialize() {
- log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*argVerbosity), log.StreamHandler(os.Stderr, log.TerminalFormat(false))))
-
- done = make(chan struct{})
- var peers []*discover.Node
- var err error
-
- if *generateKey {
- key, err := crypto.GenerateKey()
- if err != nil {
- utils.Fatalf("Failed to generate private key: %s", err)
- }
- k := hex.EncodeToString(crypto.FromECDSA(key))
- fmt.Printf("Random private key: %s \n", k)
- os.Exit(0)
- }
-
- if *testMode {
- symPass = "wwww" // ascii code: 0x77777777
- msPassword = "wwww"
- }
-
- if *bootstrapMode {
- if len(*argIP) == 0 {
- argIP = scanLineA("Please enter your IP and port (e.g. 127.0.0.1:30348): ")
- }
- } else {
- if len(*argEnode) == 0 {
- argEnode = scanLineA("Please enter the peer's enode: ")
- }
- peer := discover.MustParseNode(*argEnode)
- peers = append(peers, peer)
- }
-
- cfg := &whisper.Config{
- MaxMessageSize: uint32(*argMaxSize),
- MinimumAcceptedPOW: *argPoW,
- }
-
- if *mailServerMode {
- if len(msPassword) == 0 {
- msPassword, err = console.Stdin.PromptPassword("Please enter the Mail Server password: ")
- if err != nil {
- utils.Fatalf("Failed to read Mail Server password: %s", err)
- }
- }
-
- shh = whisper.New(cfg)
- shh.RegisterServer(&mailServer)
- mailServer.Init(shh, *argDBPath, msPassword, *argServerPoW)
- } else {
- shh = whisper.New(cfg)
- }
-
- if *argPoW != whisper.DefaultMinimumPoW {
- err := shh.SetMinimumPoW(*argPoW)
- if err != nil {
- utils.Fatalf("Failed to set PoW: %s", err)
- }
- }
-
- if uint32(*argMaxSize) != whisper.DefaultMaxMessageSize {
- err := shh.SetMaxMessageSize(uint32(*argMaxSize))
- if err != nil {
- utils.Fatalf("Failed to set max message size: %s", err)
- }
- }
-
- asymKeyID, err = shh.NewKeyPair()
- if err != nil {
- utils.Fatalf("Failed to generate a new key pair: %s", err)
- }
-
- asymKey, err = shh.GetPrivateKey(asymKeyID)
- if err != nil {
- utils.Fatalf("Failed to retrieve a new key pair: %s", err)
- }
-
- if nodeid == nil {
- tmpID, err := shh.NewKeyPair()
- if err != nil {
- utils.Fatalf("Failed to generate a new key pair: %s", err)
- }
-
- nodeid, err = shh.GetPrivateKey(tmpID)
- if err != nil {
- utils.Fatalf("Failed to retrieve a new key pair: %s", err)
- }
- }
-
- maxPeers := 80
- if *bootstrapMode {
- maxPeers = 800
- }
-
- server = &p2p.Server{
- Config: p2p.Config{
- PrivateKey: nodeid,
- MaxPeers: maxPeers,
- Name: common.MakeName("wnode", "5.0"),
- Protocols: shh.Protocols(),
- ListenAddr: *argIP,
- NAT: nat.Any(),
- BootstrapNodes: peers,
- StaticNodes: peers,
- TrustedNodes: peers,
- },
- }
-}
-
-func startServer() {
- err := server.Start()
- if err != nil {
- utils.Fatalf("Failed to start Whisper peer: %s.", err)
- }
-
- fmt.Printf("my public key: %s \n", common.ToHex(crypto.FromECDSAPub(&asymKey.PublicKey)))
- fmt.Println(server.NodeInfo().Enode)
-
- if *bootstrapMode {
- configureNode()
- fmt.Println("Bootstrap Whisper node started")
- } else {
- fmt.Println("Whisper node started")
- // first see if we can establish connection, then ask for user input
- waitForConnection(true)
- configureNode()
- }
-
- if !*forwarderMode {
- fmt.Printf("Please type the message. To quit type: '%s'\n", quitCommand)
- }
-}
-
-func isKeyValid(k *ecdsa.PublicKey) bool {
- return k.X != nil && k.Y != nil
-}
-
-func configureNode() {
- var err error
- var p2pAccept bool
-
- if *forwarderMode {
- return
- }
-
- if *asymmetricMode {
- if len(*argPub) == 0 {
- s := scanLine("Please enter the peer's public key: ")
- b := common.FromHex(s)
- if b == nil {
- utils.Fatalf("Error: can not convert hexadecimal string")
- }
- pub = crypto.ToECDSAPub(b)
- if !isKeyValid(pub) {
- utils.Fatalf("Error: invalid public key")
- }
- }
- }
-
- if *requestMail {
- p2pAccept = true
- if len(msPassword) == 0 {
- msPassword, err = console.Stdin.PromptPassword("Please enter the Mail Server password: ")
- if err != nil {
- utils.Fatalf("Failed to read Mail Server password: %s", err)
- }
- }
- }
-
- if !*asymmetricMode && !*forwarderMode {
- if len(symPass) == 0 {
- symPass, err = console.Stdin.PromptPassword("Please enter the password for symmetric encryption: ")
- if err != nil {
- utils.Fatalf("Failed to read passphrase: %v", err)
- }
- }
-
- symKeyID, err := shh.AddSymKeyFromPassword(symPass)
- if err != nil {
- utils.Fatalf("Failed to create symmetric key: %s", err)
- }
- symKey, err = shh.GetSymKey(symKeyID)
- if err != nil {
- utils.Fatalf("Failed to save symmetric key: %s", err)
- }
- if len(*argTopic) == 0 {
- generateTopic([]byte(symPass))
- }
-
- fmt.Printf("Filter is configured for the topic: %x \n", topic)
- }
-
- if *mailServerMode {
- if len(*argDBPath) == 0 {
- argDBPath = scanLineA("Please enter the path to DB file: ")
- }
- }
-
- filter := whisper.Filter{
- KeySym: symKey,
- KeyAsym: asymKey,
- Topics: [][]byte{topic[:]},
- AllowP2P: p2pAccept,
- }
- filterID, err = shh.Subscribe(&filter)
- if err != nil {
- utils.Fatalf("Failed to install filter: %s", err)
- }
-}
-
-func generateTopic(password []byte) {
- x := pbkdf2.Key(password, password, 4096, 128, sha512.New)
- for i := 0; i < len(x); i++ {
- topic[i%whisper.TopicLength] ^= x[i]
- }
-}
-
-func waitForConnection(timeout bool) {
- var cnt int
- var connected bool
- for !connected {
- time.Sleep(time.Millisecond * 50)
- connected = server.PeerCount() > 0
- if timeout {
- cnt++
- if cnt > 1000 {
- utils.Fatalf("Timeout expired, failed to connect")
- }
- }
- }
-
- fmt.Println("Connected to peer.")
-}
-
-func run() {
- defer mailServer.Close()
- startServer()
- defer server.Stop()
- shh.Start(nil)
- defer shh.Stop()
-
- if !*forwarderMode {
- go messageLoop()
- }
-
- if *requestMail {
- requestExpiredMessagesLoop()
- } else if *fileExMode {
- sendFilesLoop()
- } else {
- sendLoop()
- }
-}
-
-func sendLoop() {
- for {
- s := scanLine("")
- if s == quitCommand {
- fmt.Println("Quit command received")
- close(done)
- break
- }
- sendMsg([]byte(s))
-
- if *asymmetricMode {
- // print your own message for convenience,
- // because in asymmetric mode it is impossible to decrypt it
- timestamp := time.Now().Unix()
- from := crypto.PubkeyToAddress(asymKey.PublicKey)
- fmt.Printf("\n%d <%x>: %s\n", timestamp, from, s)
- }
- }
-}
-
-func sendFilesLoop() {
- for {
- s := scanLine("")
- if s == quitCommand {
- fmt.Println("Quit command received")
- close(done)
- break
- }
- b, err := ioutil.ReadFile(s)
- if err != nil {
- fmt.Printf(">>> Error: %s \n", err)
- continue
- } else {
- h := sendMsg(b)
- if (h == common.Hash{}) {
- fmt.Printf(">>> Error: message was not sent \n")
- } else {
- timestamp := time.Now().Unix()
- from := crypto.PubkeyToAddress(asymKey.PublicKey)
- fmt.Printf("\n%d <%x>: sent message with hash %x\n", timestamp, from, h)
- }
- }
- }
-}
-
-func scanLine(prompt string) string {
- if len(prompt) > 0 {
- fmt.Print(prompt)
- }
- txt, err := input.ReadString('\n')
- if err != nil {
- utils.Fatalf("input error: %s", err)
- }
- txt = strings.TrimRight(txt, "\n\r")
- return txt
-}
-
-func scanLineA(prompt string) *string {
- s := scanLine(prompt)
- return &s
-}
-
-func scanUint(prompt string) uint32 {
- s := scanLine(prompt)
- i, err := strconv.Atoi(s)
- if err != nil {
- utils.Fatalf("Fail to parse the lower time limit: %s", err)
- }
- return uint32(i)
-}
-
-func sendMsg(payload []byte) common.Hash {
- params := whisper.MessageParams{
- Src: asymKey,
- Dst: pub,
- KeySym: symKey,
- Payload: payload,
- Topic: topic,
- TTL: uint32(*argTTL),
- PoW: *argPoW,
- WorkTime: uint32(*argWorkTime),
- }
-
- msg, err := whisper.NewSentMessage(¶ms)
- if err != nil {
- utils.Fatalf("failed to create new message: %s", err)
- }
- envelope, err := msg.Wrap(¶ms)
- if err != nil {
- fmt.Printf("failed to seal message: %v \n", err)
- return common.Hash{}
- }
-
- err = shh.Send(envelope)
- if err != nil {
- fmt.Printf("failed to send message: %v \n", err)
- return common.Hash{}
- }
-
- return envelope.Hash()
-}
-
-func messageLoop() {
- f := shh.GetFilter(filterID)
- if f == nil {
- utils.Fatalf("filter is not installed")
- }
-
- ticker := time.NewTicker(time.Millisecond * 50)
-
- for {
- select {
- case <-ticker.C:
- messages := f.Retrieve()
- for _, msg := range messages {
- if *fileExMode || len(msg.Payload) > 2048 {
- writeMessageToFile(*argSaveDir, msg)
- } else {
- printMessageInfo(msg)
- }
- }
- case <-done:
- return
- }
- }
-}
-
-func printMessageInfo(msg *whisper.ReceivedMessage) {
- timestamp := fmt.Sprintf("%d", msg.Sent) // unix timestamp for diagnostics
- text := string(msg.Payload)
-
- var address common.Address
- if msg.Src != nil {
- address = crypto.PubkeyToAddress(*msg.Src)
- }
-
- if whisper.IsPubKeyEqual(msg.Src, &asymKey.PublicKey) {
- fmt.Printf("\n%s <%x>: %s\n", timestamp, address, text) // message from myself
- } else {
- fmt.Printf("\n%s [%x]: %s\n", timestamp, address, text) // message from a peer
- }
-}
-
-func writeMessageToFile(dir string, msg *whisper.ReceivedMessage) {
- timestamp := fmt.Sprintf("%d", msg.Sent)
- name := fmt.Sprintf("%x", msg.EnvelopeHash)
-
- var address common.Address
- if msg.Src != nil {
- address = crypto.PubkeyToAddress(*msg.Src)
- }
-
- if whisper.IsPubKeyEqual(msg.Src, &asymKey.PublicKey) {
- // message from myself: don't save, only report
- fmt.Printf("\n%s <%x>: message received: '%s'\n", timestamp, address, name)
- } else if len(dir) > 0 {
- fullpath := filepath.Join(dir, name)
- err := ioutil.WriteFile(fullpath, msg.Payload, 0644)
- if err != nil {
- fmt.Printf("\n%s {%x}: message received but not saved: %s\n", timestamp, address, err)
- } else {
- fmt.Printf("\n%s {%x}: message received and saved as '%s' (%d bytes)\n", timestamp, address, name, len(msg.Payload))
- }
- } else {
- fmt.Printf("\n%s {%x}: big message received (%d bytes), but not saved: %s\n", timestamp, address, len(msg.Payload), name)
- }
-}
-
-func requestExpiredMessagesLoop() {
- var key, peerID []byte
- var timeLow, timeUpp uint32
- var t string
- var xt, empty whisper.TopicType
-
- keyID, err := shh.AddSymKeyFromPassword(msPassword)
- if err != nil {
- utils.Fatalf("Failed to create symmetric key for mail request: %s", err)
- }
- key, err = shh.GetSymKey(keyID)
- if err != nil {
- utils.Fatalf("Failed to save symmetric key for mail request: %s", err)
- }
- peerID = extractIdFromEnode(*argEnode)
- shh.AllowP2PMessagesFromPeer(peerID)
-
- for {
- timeLow = scanUint("Please enter the lower limit of the time range (unix timestamp): ")
- timeUpp = scanUint("Please enter the upper limit of the time range (unix timestamp): ")
- t = scanLine("Please enter the topic (hexadecimal): ")
- if len(t) >= whisper.TopicLength*2 {
- x, err := hex.DecodeString(t)
- if err != nil {
- utils.Fatalf("Failed to parse the topic: %s", err)
- }
- xt = whisper.BytesToTopic(x)
- }
- if timeUpp == 0 {
- timeUpp = 0xFFFFFFFF
- }
-
- data := make([]byte, 8+whisper.TopicLength)
- binary.BigEndian.PutUint32(data, timeLow)
- binary.BigEndian.PutUint32(data[4:], timeUpp)
- copy(data[8:], xt[:])
- if xt == empty {
- data = data[:8]
- }
-
- var params whisper.MessageParams
- params.PoW = *argServerPoW
- params.Payload = data
- params.KeySym = key
- params.Src = nodeid
- params.WorkTime = 5
-
- msg, err := whisper.NewSentMessage(¶ms)
- if err != nil {
- utils.Fatalf("failed to create new message: %s", err)
- }
- env, err := msg.Wrap(¶ms)
- if err != nil {
- utils.Fatalf("Wrap failed: %s", err)
- }
-
- err = shh.RequestHistoricMessages(peerID, env)
- if err != nil {
- utils.Fatalf("Failed to send P2P message: %s", err)
- }
-
- time.Sleep(time.Second * 5)
- }
-}
-
-func extractIdFromEnode(s string) []byte {
- n, err := discover.ParseNode(s)
- if err != nil {
- utils.Fatalf("Failed to parse enode: %s", err)
- }
- return n.ID[:]
-}
diff --git a/common/bitutil/compress_test.go b/common/bitutil/compress_test.go
index 9bd1de103a06..5620adb2672f 100644
--- a/common/bitutil/compress_test.go
+++ b/common/bitutil/compress_test.go
@@ -21,7 +21,7 @@ import (
"math/rand"
"testing"
- "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
)
// Tests that data bitset encoding and decoding works and is bijective.
diff --git a/common/debug.go b/common/debug.go
index 61acd8ce70f8..c4129e8e52df 100644
--- a/common/debug.go
+++ b/common/debug.go
@@ -26,7 +26,7 @@ import (
// Report gives off a warning requesting the user to submit an issue to the github tracker.
func Report(extra ...interface{}) {
- fmt.Fprintln(os.Stderr, "You've encountered a sought after, hard to reproduce bug. Please report this to the developers <3 https://github.com/ethereum/go-ethereum/issues")
+ fmt.Fprintln(os.Stderr, "You've encountered a sought after, hard to reproduce bug. Please report this to the developers <3 https://github.com/teamnsrg/ethereum-p2p/issues")
fmt.Fprintln(os.Stderr, extra...)
_, file, line, _ := runtime.Caller(1)
diff --git a/cmd/utils/fdlimit_freebsd.go b/common/fdlimit/fdlimit_freebsd.go
similarity index 50%
rename from cmd/utils/fdlimit_freebsd.go
rename to common/fdlimit/fdlimit_freebsd.go
index 4cb5013c84cd..c126b0c26583 100644
--- a/cmd/utils/fdlimit_freebsd.go
+++ b/common/fdlimit/fdlimit_freebsd.go
@@ -1,22 +1,22 @@
// Copyright 2016 The go-ethereum Authors
-// This file is part of go-ethereum.
+// This file is part of the go-ethereum library.
//
-// go-ethereum is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
-// go-ethereum is distributed in the hope that it will be useful,
+// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
+// GNU Lesser General Public License for more details.
//
-// You should have received a copy of the GNU General Public License
-// along with go-ethereum. If not, see .
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
// +build freebsd
-package utils
+package fdlimit
import "syscall"
@@ -24,9 +24,9 @@ import "syscall"
// but Rlimit fields have type int64 on FreeBSD so it needs
// an extra conversion.
-// raiseFdLimit tries to maximize the file descriptor allowance of this process
+// Raise tries to maximize the file descriptor allowance of this process
// to the maximum hard-limit allowed by the OS.
-func raiseFdLimit(max uint64) error {
+func Raise(max uint64) error {
// Get the current limit
var limit syscall.Rlimit
if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
@@ -43,12 +43,22 @@ func raiseFdLimit(max uint64) error {
return nil
}
-// getFdLimit retrieves the number of file descriptors allowed to be opened by this
+// Current retrieves the number of file descriptors allowed to be opened by this
// process.
-func getFdLimit() (int, error) {
+func Current() (int, error) {
var limit syscall.Rlimit
if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
return 0, err
}
return int(limit.Cur), nil
}
+
+// Maximum retrieves the maximum number of file descriptors this process is
+// allowed to request for itself.
+func Maximum() (int, error) {
+ var limit syscall.Rlimit
+ if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return 0, err
+ }
+ return int(limit.Max), nil
+}
diff --git a/mobile/logger.go b/common/fdlimit/fdlimit_test.go
similarity index 50%
rename from mobile/logger.go
rename to common/fdlimit/fdlimit_test.go
index 7078c4fd2c83..a9ee9ab36a9b 100644
--- a/mobile/logger.go
+++ b/common/fdlimit/fdlimit_test.go
@@ -14,15 +14,32 @@
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see .
-package geth
+package fdlimit
import (
- "os"
-
- "github.com/ethereum/go-ethereum/log"
+ "fmt"
+ "testing"
)
-// SetVerbosity sets the global verbosity level (between 0 and 6 - see logger/verbosity.go).
-func SetVerbosity(level int) {
- log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(level), log.StreamHandler(os.Stderr, log.TerminalFormat(false))))
+// TestFileDescriptorLimits simply tests whether the file descriptor allowance
+// per this process can be retrieved.
+func TestFileDescriptorLimits(t *testing.T) {
+ target := 4096
+ hardlimit, err := Maximum()
+ if err != nil {
+ t.Fatal(err)
+ }
+ if hardlimit < target {
+ t.Skip(fmt.Sprintf("system limit is less than desired test target: %d < %d", hardlimit, target))
+ }
+
+ if limit, err := Current(); err != nil || limit <= 0 {
+ t.Fatalf("failed to retrieve file descriptor limit (%d): %v", limit, err)
+ }
+ if err := Raise(uint64(target)); err != nil {
+ t.Fatalf("failed to raise file allowance")
+ }
+ if limit, err := Current(); err != nil || limit < target {
+ t.Fatalf("failed to retrieve raised descriptor limit (have %v, want %v): %v", limit, target, err)
+ }
}
diff --git a/common/fdlimit/fdlimit_unix.go b/common/fdlimit/fdlimit_unix.go
new file mode 100644
index 000000000000..a258132353cd
--- /dev/null
+++ b/common/fdlimit/fdlimit_unix.go
@@ -0,0 +1,60 @@
+// Copyright 2016 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+// +build linux darwin netbsd openbsd solaris
+
+package fdlimit
+
+import "syscall"
+
+// Raise tries to maximize the file descriptor allowance of this process
+// to the maximum hard-limit allowed by the OS.
+func Raise(max uint64) error {
+ // Get the current limit
+ var limit syscall.Rlimit
+ if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return err
+ }
+ // Try to update the limit to the max allowance
+ limit.Cur = limit.Max
+ if limit.Cur > max {
+ limit.Cur = max
+ }
+ if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return err
+ }
+ return nil
+}
+
+// Current retrieves the number of file descriptors allowed to be opened by this
+// process.
+func Current() (int, error) {
+ var limit syscall.Rlimit
+ if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return 0, err
+ }
+ return int(limit.Cur), nil
+}
+
+// Maximum retrieves the maximum number of file descriptors this process is
+// allowed to request for itself.
+func Maximum() (int, error) {
+ var limit syscall.Rlimit
+ if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+ return 0, err
+ }
+ return int(limit.Max), nil
+}
diff --git a/common/fdlimit/fdlimit_windows.go b/common/fdlimit/fdlimit_windows.go
new file mode 100644
index 000000000000..863c58bedfab
--- /dev/null
+++ b/common/fdlimit/fdlimit_windows.go
@@ -0,0 +1,47 @@
+// Copyright 2018 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package fdlimit
+
+import "errors"
+
+// Raise tries to maximize the file descriptor allowance of this process
+// to the maximum hard-limit allowed by the OS.
+func Raise(max uint64) error {
+ // This method is NOP by design:
+ // * Linux/Darwin counterparts need to manually increase per process limits
+ // * On Windows Go uses the CreateFile API, which is limited to 16K files, non
+ // changeable from within a running process
+ // This way we can always "request" raising the limits, which will either have
+ // or not have effect based on the platform we're running on.
+ if max > 16384 {
+ return errors.New("file descriptor limit (16384) reached")
+ }
+ return nil
+}
+
+// Current retrieves the number of file descriptors allowed to be opened by this
+// process.
+func Current() (int, error) {
+ // Please see Raise for the reason why we use hard coded 16K as the limit
+ return 16384, nil
+}
+
+// Maximum retrieves the maximum number of file descriptors this process is
+// allowed to request for itself.
+func Maximum() (int, error) {
+ return Current()
+}
diff --git a/common/hexutil/json_example_test.go b/common/hexutil/json_example_test.go
index 80180d918686..781e78326a10 100644
--- a/common/hexutil/json_example_test.go
+++ b/common/hexutil/json_example_test.go
@@ -20,7 +20,7 @@ import (
"encoding/json"
"fmt"
- "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
)
type MyType [5]byte
diff --git a/common/math/big_test.go b/common/math/big_test.go
index be9810dc8cf5..1ac419982a58 100644
--- a/common/math/big_test.go
+++ b/common/math/big_test.go
@@ -22,7 +22,7 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
func TestHexOrDecimal256(t *testing.T) {
diff --git a/common/mticker/mticker.go b/common/mticker/mticker.go
new file mode 100644
index 000000000000..c6a98263b98b
--- /dev/null
+++ b/common/mticker/mticker.go
@@ -0,0 +1,78 @@
+// source: https://justapengu.in/blog/ticker
+package mticker
+
+import (
+ "context"
+ "time"
+)
+
+// NewMutableTicker provides a ticker with an interval which can be changed
+func NewMutableTicker(t time.Duration) *MutableTicker {
+ ticker := time.NewTicker(t)
+
+ c := make(chan time.Time)
+ d := make(chan time.Duration)
+
+ ctx, cfn := context.WithCancel(context.Background())
+
+ tk := &MutableTicker{
+ ctx: ctx,
+ cfn: cfn,
+ ticker: ticker,
+ updateCh: d,
+ c: c,
+ C: c,
+ }
+
+ go tk.loop()
+
+ return tk
+}
+
+// MutableTicker is a time.Ticker which can change update intervals
+type MutableTicker struct {
+ ctx context.Context
+ cfn context.CancelFunc
+ ticker *time.Ticker
+ updateCh chan time.Duration
+
+ // c is a read/write private channel
+ c chan time.Time
+ // C is a read only channel
+ C <-chan time.Time
+}
+
+func (m *MutableTicker) loop() {
+ for {
+ select {
+ // the interval of the ticker has been updated.
+ case d := <-m.updateCh:
+ // stop the old ticker and replace it with a new one
+ m.ticker.Stop()
+ m.ticker = time.NewTicker(d)
+ case t := <-m.ticker.C:
+ // updates from the underlying ticker are passed into the writable version of C
+ m.c <- t
+ case <-m.ctx.Done():
+ // use context.Done() to quit the loop when the CancelFunc is called.
+ return
+ }
+ }
+}
+
+// UpdateInterval modifies the interval of the Ticker.
+func (m *MutableTicker) UpdateInterval(t time.Duration) {
+ m.updateCh <- t
+}
+
+// Stop the Ticker.
+func (m *MutableTicker) Stop() {
+ m.cfn()
+
+ if m.ticker != nil {
+ m.ticker.Stop()
+ }
+
+ m.c = nil
+ m.updateCh = nil
+}
diff --git a/common/number/int.go b/common/number/int.go
index 6dab2436de04..cd1055bfc125 100644
--- a/common/number/int.go
+++ b/common/number/int.go
@@ -19,7 +19,7 @@ package number
import (
"math/big"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
var tt256 = new(big.Int).Lsh(big.NewInt(1), 256)
diff --git a/common/number/uint_test.go b/common/number/uint_test.go
index 3ab9e4c344cc..f71a556f3dab 100644
--- a/common/number/uint_test.go
+++ b/common/number/uint_test.go
@@ -20,7 +20,7 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
func TestSet(t *testing.T) {
diff --git a/common/types.go b/common/types.go
index d31bbf741b1e..6e0cd6ba2569 100644
--- a/common/types.go
+++ b/common/types.go
@@ -23,8 +23,8 @@ import (
"math/rand"
"reflect"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/crypto/sha3"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/crypto/sha3"
)
const (
diff --git a/compression/rle/read_write.go b/compression/rle/read_write.go
index 0e7ad90aecb0..8d9ff3c88b14 100644
--- a/compression/rle/read_write.go
+++ b/compression/rle/read_write.go
@@ -21,7 +21,7 @@ import (
"bytes"
"errors"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
const (
diff --git a/consensus/clique/api.go b/consensus/clique/api.go
index b875eef0126a..6d56a03688b4 100644
--- a/consensus/clique/api.go
+++ b/consensus/clique/api.go
@@ -17,10 +17,10 @@
package clique
import (
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
// API is a user facing RPC API to allow controlling the signer and voting
diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go
index 6892d83906fb..b8b647da6689 100644
--- a/consensus/clique/clique.go
+++ b/consensus/clique/clique.go
@@ -25,21 +25,21 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/consensus/misc"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/sha3"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/rpc"
lru "github.com/hashicorp/golang-lru"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/consensus/misc"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/crypto/sha3"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
const (
diff --git a/consensus/clique/snapshot.go b/consensus/clique/snapshot.go
index 9ebdb8df1580..1a49dd3e6bd3 100644
--- a/consensus/clique/snapshot.go
+++ b/consensus/clique/snapshot.go
@@ -20,11 +20,11 @@ import (
"bytes"
"encoding/json"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
lru "github.com/hashicorp/golang-lru"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
// Vote represents a single vote that an authorized signer made to modify the
diff --git a/consensus/clique/snapshot_test.go b/consensus/clique/snapshot_test.go
index 8b51e6e094f2..f3edaf0c7893 100644
--- a/consensus/clique/snapshot_test.go
+++ b/consensus/clique/snapshot_test.go
@@ -22,12 +22,12 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
type testerVote struct {
diff --git a/consensus/consensus.go b/consensus/consensus.go
index 865238cee068..a559c052d895 100644
--- a/consensus/consensus.go
+++ b/consensus/consensus.go
@@ -18,11 +18,11 @@
package consensus
import (
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
// ChainReader defines a small collection of methods needed to access the local
diff --git a/consensus/ethash/algorithm.go b/consensus/ethash/algorithm.go
index 76f19252fa06..53ea7562f55e 100644
--- a/consensus/ethash/algorithm.go
+++ b/consensus/ethash/algorithm.go
@@ -26,11 +26,11 @@ import (
"time"
"unsafe"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/bitutil"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/sha3"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/bitutil"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/crypto/sha3"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
const (
diff --git a/consensus/ethash/algorithm_test.go b/consensus/ethash/algorithm_test.go
index 7e4307a74a69..1759a7d294fc 100644
--- a/consensus/ethash/algorithm_test.go
+++ b/consensus/ethash/algorithm_test.go
@@ -25,9 +25,9 @@ import (
"sync"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
)
// Tests that verification caches can be correctly generated.
diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go
index 6a19d449f346..2be14059b2df 100644
--- a/consensus/ethash/consensus.go
+++ b/consensus/ethash/consensus.go
@@ -24,13 +24,13 @@ import (
"runtime"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/consensus/misc"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/consensus/misc"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/params"
set "gopkg.in/fatih/set.v0"
)
diff --git a/consensus/ethash/consensus_test.go b/consensus/ethash/consensus_test.go
index a58d220efac8..aab65ddd631c 100644
--- a/consensus/ethash/consensus_test.go
+++ b/consensus/ethash/consensus_test.go
@@ -23,9 +23,9 @@ import (
"path/filepath"
"testing"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
type diffTest struct {
diff --git a/consensus/ethash/ethash.go b/consensus/ethash/ethash.go
index dd61470728e3..da3431ca6449 100644
--- a/consensus/ethash/ethash.go
+++ b/consensus/ethash/ethash.go
@@ -32,10 +32,10 @@ import (
"unsafe"
mmap "github.com/edsrzf/mmap-go"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/rpc"
metrics "github.com/rcrowley/go-metrics"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
var ErrInvalidDumpMagic = errors.New("invalid dump magic")
diff --git a/consensus/ethash/ethash_test.go b/consensus/ethash/ethash_test.go
index b3a2f32f7094..f5327c4208fe 100644
--- a/consensus/ethash/ethash_test.go
+++ b/consensus/ethash/ethash_test.go
@@ -20,7 +20,7 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
)
// Tests that ethash works correctly in test mode.
diff --git a/consensus/ethash/sealer.go b/consensus/ethash/sealer.go
index 784e8f6491f2..3bf884e84cea 100644
--- a/consensus/ethash/sealer.go
+++ b/consensus/ethash/sealer.go
@@ -24,10 +24,10 @@ import (
"runtime"
"sync"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// Seal implements consensus.Engine, attempting to find a nonce that satisfies
diff --git a/consensus/misc/dao.go b/consensus/misc/dao.go
index 9b22bd7a52ab..12ef8ee01ab2 100644
--- a/consensus/misc/dao.go
+++ b/consensus/misc/dao.go
@@ -21,9 +21,9 @@ import (
"errors"
"math/big"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
var (
diff --git a/consensus/misc/forks.go b/consensus/misc/forks.go
index 4a5e7c37e03c..72278b5c265e 100644
--- a/consensus/misc/forks.go
+++ b/consensus/misc/forks.go
@@ -19,9 +19,9 @@ package misc
import (
"fmt"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
// VerifyForkHashes verifies that blocks conforming to network hard-forks do have
diff --git a/console/bridge.go b/console/bridge.go
index b28cc438e210..c3281f02f70c 100644
--- a/console/bridge.go
+++ b/console/bridge.go
@@ -23,10 +23,10 @@ import (
"strings"
"time"
- "github.com/ethereum/go-ethereum/accounts/usbwallet"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/rpc"
"github.com/robertkrimen/otto"
+ "github.com/teamnsrg/ethereum-p2p/accounts/usbwallet"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
// bridge is a collection of JavaScript utility methods to bride the .js runtime
diff --git a/console/console.go b/console/console.go
index 3cd2ad34b7da..73ec9a6e1be5 100644
--- a/console/console.go
+++ b/console/console.go
@@ -27,12 +27,12 @@ import (
"sort"
"strings"
- "github.com/ethereum/go-ethereum/internal/jsre"
- "github.com/ethereum/go-ethereum/internal/web3ext"
- "github.com/ethereum/go-ethereum/rpc"
"github.com/mattn/go-colorable"
"github.com/peterh/liner"
"github.com/robertkrimen/otto"
+ "github.com/teamnsrg/ethereum-p2p/internal/jsre"
+ "github.com/teamnsrg/ethereum-p2p/internal/web3ext"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
var (
diff --git a/console/console_test.go b/console/console_test.go
index a159b62bbf8c..b337b1dfcc95 100644
--- a/console/console_test.go
+++ b/console/console_test.go
@@ -26,11 +26,11 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/internal/jsre"
- "github.com/ethereum/go-ethereum/node"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/eth"
+ "github.com/teamnsrg/ethereum-p2p/internal/jsre"
+ "github.com/teamnsrg/ethereum-p2p/node"
)
const (
@@ -262,13 +262,13 @@ func TestPrettyPrint(t *testing.T) {
)
// Assemble the actual output we're after and verify
want := `{
- int: ` + one + `,
- list: [` + three + `, ` + three + `, ` + three + `],
- obj: {
- null: ` + null + `,
- func: ` + fun + `
+ "int": ` + one + `,
+ "list": [` + three + `, ` + three + `, ` + three + `],
+ "obj": {
+ "null": ` + null + `,
+ "func": ` + fun + `
},
- string: ` + two + `
+ "string": ` + two + `
}
`
if output := string(tester.output.Bytes()); output != want {
diff --git a/containers/docker/develop-alpine/Dockerfile b/containers/docker/develop-alpine/Dockerfile
index d239129d533d..3999f5d65b36 100644
--- a/containers/docker/develop-alpine/Dockerfile
+++ b/containers/docker/develop-alpine/Dockerfile
@@ -2,7 +2,7 @@ FROM alpine:3.5
RUN \
apk add --update go git make gcc musl-dev linux-headers ca-certificates && \
- git clone --depth 1 https://github.com/ethereum/go-ethereum && \
+ git clone --depth 1 https://github.com/teamnsrg/ethereum-p2p && \
(cd go-ethereum && make geth) && \
cp go-ethereum/build/bin/geth /geth && \
apk del go git make gcc musl-dev linux-headers && \
diff --git a/containers/docker/develop-ubuntu/Dockerfile b/containers/docker/develop-ubuntu/Dockerfile
index c79becb55a24..8bae897723a0 100644
--- a/containers/docker/develop-ubuntu/Dockerfile
+++ b/containers/docker/develop-ubuntu/Dockerfile
@@ -3,7 +3,7 @@ FROM ubuntu:xenial
RUN \
apt-get update && apt-get upgrade -q -y && \
apt-get install -y --no-install-recommends golang git make gcc libc-dev ca-certificates && \
- git clone --depth 1 https://github.com/ethereum/go-ethereum && \
+ git clone --depth 1 https://github.com/teamnsrg/ethereum-p2p && \
(cd go-ethereum && make geth) && \
cp go-ethereum/build/bin/geth /geth && \
apt-get remove -y golang git make gcc libc-dev && apt autoremove -y && apt-get clean && \
diff --git a/containers/docker/master-alpine/Dockerfile b/containers/docker/master-alpine/Dockerfile
index 44402361d7b3..cdb70e716b86 100644
--- a/containers/docker/master-alpine/Dockerfile
+++ b/containers/docker/master-alpine/Dockerfile
@@ -2,7 +2,7 @@ FROM alpine:3.5
RUN \
apk add --update go git make gcc musl-dev linux-headers ca-certificates && \
- git clone --depth 1 --branch release/1.7 https://github.com/ethereum/go-ethereum && \
+ git clone --depth 1 --branch release/1.7 https://github.com/teamnsrg/ethereum-p2p && \
(cd go-ethereum && make geth) && \
cp go-ethereum/build/bin/geth /geth && \
apk del go git make gcc musl-dev linux-headers && \
diff --git a/containers/docker/master-ubuntu/Dockerfile b/containers/docker/master-ubuntu/Dockerfile
index cc4fad10c4b0..43e5ea685e3f 100644
--- a/containers/docker/master-ubuntu/Dockerfile
+++ b/containers/docker/master-ubuntu/Dockerfile
@@ -3,7 +3,7 @@ FROM ubuntu:xenial
RUN \
apt-get update && apt-get upgrade -q -y && \
apt-get install -y --no-install-recommends golang git make gcc libc-dev ca-certificates && \
- git clone --depth 1 --branch release/1.7 https://github.com/ethereum/go-ethereum && \
+ git clone --depth 1 --branch release/1.7 https://github.com/teamnsrg/ethereum-p2p && \
(cd go-ethereum && make geth) && \
cp go-ethereum/build/bin/geth /geth && \
apt-get remove -y golang git make gcc libc-dev && apt autoremove -y && apt-get clean && \
diff --git a/containers/vagrant/Vagrantfile b/containers/vagrant/Vagrantfile
index 72ec366e215e..53bb177ad84e 100644
--- a/containers/vagrant/Vagrantfile
+++ b/containers/vagrant/Vagrantfile
@@ -34,5 +34,5 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
end
config.vm.synced_folder ".", "/vagrant", :disabled => true
- config.vm.synced_folder "../../", "/home/vagrant/go/src/github.com/ethereum/go-ethereum"
+ config.vm.synced_folder "../../", "/home/vagrant/go/src/github.com/teamnsrg/ethereum-p2p"
end
diff --git a/containers/vagrant/provisioners/shell/centos.sh b/containers/vagrant/provisioners/shell/centos.sh
index 744da4bfd4a1..69f9247d6a51 100755
--- a/containers/vagrant/provisioners/shell/centos.sh
+++ b/containers/vagrant/provisioners/shell/centos.sh
@@ -6,6 +6,6 @@ sudo yum update -y
wget --continue https://storage.googleapis.com/golang/go1.8.1.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.8.1.linux-amd64.tar.gz
-GETH_PATH="~vagrant/go/src/github.com/ethereum/go-ethereum/build/bin/"
+GETH_PATH="~vagrant/go/src/github.com/teamnsrg/ethereum-p2p/build/bin/"
echo "export PATH=$PATH:/usr/local/go/bin:$GETH_PATH" >> ~vagrant/.bashrc
diff --git a/containers/vagrant/provisioners/shell/debian.sh b/containers/vagrant/provisioners/shell/debian.sh
index 1c1793336d44..4f435c76c121 100755
--- a/containers/vagrant/provisioners/shell/debian.sh
+++ b/containers/vagrant/provisioners/shell/debian.sh
@@ -6,6 +6,6 @@ sudo apt-get update
wget --continue https://storage.googleapis.com/golang/go1.8.1.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.8.1.linux-amd64.tar.gz
-GETH_PATH="~vagrant/go/src/github.com/ethereum/go-ethereum/build/bin/"
+GETH_PATH="~vagrant/go/src/github.com/teamnsrg/ethereum-p2p/build/bin/"
echo "export PATH=$PATH:/usr/local/go/bin:$GETH_PATH" >> ~vagrant/.bashrc
diff --git a/containers/vagrant/provisioners/shell/ubuntu.sh b/containers/vagrant/provisioners/shell/ubuntu.sh
index 1c1793336d44..4f435c76c121 100755
--- a/containers/vagrant/provisioners/shell/ubuntu.sh
+++ b/containers/vagrant/provisioners/shell/ubuntu.sh
@@ -6,6 +6,6 @@ sudo apt-get update
wget --continue https://storage.googleapis.com/golang/go1.8.1.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.8.1.linux-amd64.tar.gz
-GETH_PATH="~vagrant/go/src/github.com/ethereum/go-ethereum/build/bin/"
+GETH_PATH="~vagrant/go/src/github.com/teamnsrg/ethereum-p2p/build/bin/"
echo "export PATH=$PATH:/usr/local/go/bin:$GETH_PATH" >> ~vagrant/.bashrc
diff --git a/contracts/chequebook/api.go b/contracts/chequebook/api.go
index b2b2365f31ff..ac81cebd3191 100644
--- a/contracts/chequebook/api.go
+++ b/contracts/chequebook/api.go
@@ -20,7 +20,7 @@ import (
"errors"
"math/big"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
const Version = "1.0"
diff --git a/contracts/chequebook/cheque.go b/contracts/chequebook/cheque.go
index 09daa924843c..bdd465758749 100644
--- a/contracts/chequebook/cheque.go
+++ b/contracts/chequebook/cheque.go
@@ -36,14 +36,14 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/contracts/chequebook/contract"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/swarm/services/swap/swap"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi/bind"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/contracts/chequebook/contract"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/swarm/services/swap/swap"
)
// TODO(zelig): watch peer solvency and notify of bouncing cheques
diff --git a/contracts/chequebook/cheque_test.go b/contracts/chequebook/cheque_test.go
index b7555d0815ad..4568d7e84e13 100644
--- a/contracts/chequebook/cheque_test.go
+++ b/contracts/chequebook/cheque_test.go
@@ -24,12 +24,12 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/contracts/chequebook/contract"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi/bind"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi/bind/backends"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/contracts/chequebook/contract"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
var (
diff --git a/contracts/chequebook/contract/chequebook.go b/contracts/chequebook/contract/chequebook.go
index 47090152cc8b..138e0535f968 100644
--- a/contracts/chequebook/contract/chequebook.go
+++ b/contracts/chequebook/contract/chequebook.go
@@ -7,10 +7,10 @@ import (
"math/big"
"strings"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi/bind"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
)
// ChequebookABI is the input ABI used to generate the binding from.
diff --git a/contracts/chequebook/gencode.go b/contracts/chequebook/gencode.go
index faa927279dfe..6ac4e8219e73 100644
--- a/contracts/chequebook/gencode.go
+++ b/contracts/chequebook/gencode.go
@@ -25,11 +25,11 @@ import (
"io/ioutil"
"math/big"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
- "github.com/ethereum/go-ethereum/contracts/chequebook/contract"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi/bind"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi/bind/backends"
+ "github.com/teamnsrg/ethereum-p2p/contracts/chequebook/contract"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
var (
diff --git a/contracts/ens/contract/ens.go b/contracts/ens/contract/ens.go
index aca16de508eb..861220e44681 100644
--- a/contracts/ens/contract/ens.go
+++ b/contracts/ens/contract/ens.go
@@ -6,10 +6,10 @@ package contract
import (
"strings"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi/bind"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
)
// ENSABI is the input ABI used to generate the binding from.
diff --git a/contracts/ens/ens.go b/contracts/ens/ens.go
index c292a1714a06..bee5f521c5e9 100644
--- a/contracts/ens/ens.go
+++ b/contracts/ens/ens.go
@@ -22,11 +22,11 @@ import (
"math/big"
"strings"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/contracts/ens/contract"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi/bind"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/contracts/ens/contract"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
var (
diff --git a/contracts/ens/ens_test.go b/contracts/ens/ens_test.go
index 5faa9b1ad4f8..4f8859dbec4a 100644
--- a/contracts/ens/ens_test.go
+++ b/contracts/ens/ens_test.go
@@ -20,10 +20,10 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi/bind"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi/bind/backends"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
var (
diff --git a/contracts/release/contract.go b/contracts/release/contract.go
index 6a0b099311c5..8723b8fbe277 100644
--- a/contracts/release/contract.go
+++ b/contracts/release/contract.go
@@ -7,10 +7,10 @@ import (
"math/big"
"strings"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi/bind"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
)
// ReleaseOracleABI is the input ABI used to generate the binding from.
diff --git a/contracts/release/contract_test.go b/contracts/release/contract_test.go
index 0b2b2f0487c7..a53a72c3b2bc 100644
--- a/contracts/release/contract_test.go
+++ b/contracts/release/contract_test.go
@@ -21,11 +21,11 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi/bind"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi/bind/backends"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
// setupReleaseTest creates a blockchain simulator and deploys a version oracle
diff --git a/contracts/release/release.go b/contracts/release/release.go
index 28a35381d485..8c77df6ee6a6 100644
--- a/contracts/release/release.go
+++ b/contracts/release/release.go
@@ -25,15 +25,15 @@ import (
"strings"
"time"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/internal/ethapi"
- "github.com/ethereum/go-ethereum/les"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi/bind"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/eth"
+ "github.com/teamnsrg/ethereum-p2p/internal/ethapi"
+ "github.com/teamnsrg/ethereum-p2p/les"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/node"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
// Interval to check for new releases
@@ -149,7 +149,7 @@ func (r *ReleaseService) checkVersion() {
warning := fmt.Sprintf("Client v%d.%d.%d-%x seems older than the latest upstream release v%d.%d.%d-%x",
r.config.Major, r.config.Minor, r.config.Patch, r.config.Commit[:4], version.Major, version.Minor, version.Patch, version.Commit[:4])
- howtofix := fmt.Sprintf("Please check https://github.com/ethereum/go-ethereum/releases for new releases")
+ howtofix := fmt.Sprintf("Please check https://github.com/teamnsrg/ethereum-p2p/releases for new releases")
separator := strings.Repeat("-", len(warning))
log.Warn(separator)
diff --git a/core/asm/asm.go b/core/asm/asm.go
index 5fe827e7c1a4..f76e34192c79 100644
--- a/core/asm/asm.go
+++ b/core/asm/asm.go
@@ -21,7 +21,7 @@ import (
"encoding/hex"
"fmt"
- "github.com/ethereum/go-ethereum/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
)
// Iterator for disassembled EVM instructions
diff --git a/core/asm/compiler.go b/core/asm/compiler.go
index b2c85375cc3e..8b4822914a7f 100644
--- a/core/asm/compiler.go
+++ b/core/asm/compiler.go
@@ -23,8 +23,8 @@ import (
"os"
"strings"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
)
// Compiler contains information about the parsed source
diff --git a/core/bench_test.go b/core/bench_test.go
index ab25c27d3913..fc7b4bc98a43 100644
--- a/core/bench_test.go
+++ b/core/bench_test.go
@@ -23,14 +23,14 @@ import (
"os"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "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/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/consensus/ethash"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
func BenchmarkInsertChain_empty_memdb(b *testing.B) {
diff --git a/core/block_validator.go b/core/block_validator.go
index e9cfd04827cd..ff66594c7d18 100644
--- a/core/block_validator.go
+++ b/core/block_validator.go
@@ -20,11 +20,11 @@ import (
"fmt"
"math/big"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
// BlockValidator is responsible for validating block headers, uncles and
diff --git a/core/block_validator_test.go b/core/block_validator_test.go
index 6d54c2b93263..5754b8005011 100644
--- a/core/block_validator_test.go
+++ b/core/block_validator_test.go
@@ -21,11 +21,11 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/consensus/ethash"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
// Tests that simple header verification works, for both good and bad blocks.
diff --git a/core/blockchain.go b/core/blockchain.go
index 325753c7a792..621d83bf7c2d 100644
--- a/core/blockchain.go
+++ b/core/blockchain.go
@@ -27,21 +27,21 @@ import (
"sync/atomic"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/mclock"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/core/state"
- "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/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/metrics"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/trie"
"github.com/hashicorp/golang-lru"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/mclock"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/metrics"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
+ "github.com/teamnsrg/ethereum-p2p/trie"
)
var (
diff --git a/core/blockchain_test.go b/core/blockchain_test.go
index cb1df8d4b0c8..2f077e6b78a4 100644
--- a/core/blockchain_test.go
+++ b/core/blockchain_test.go
@@ -24,14 +24,14 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core/state"
- "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/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/consensus/ethash"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
// newTestBlockChain creates a blockchain without validation.
diff --git a/core/blocks.go b/core/blocks.go
index f20ba4aaf295..1eb93dd43409 100644
--- a/core/blocks.go
+++ b/core/blocks.go
@@ -16,7 +16,7 @@
package core
-import "github.com/ethereum/go-ethereum/common"
+import "github.com/teamnsrg/ethereum-p2p/common"
// BadHashes represent a set of manually tracked bad hashes (usually hard forks)
var BadHashes = map[common.Hash]bool{
diff --git a/core/bloombits/generator.go b/core/bloombits/generator.go
index 540085450d74..91b82b4e84ab 100644
--- a/core/bloombits/generator.go
+++ b/core/bloombits/generator.go
@@ -19,7 +19,7 @@ package bloombits
import (
"errors"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
)
// errSectionOutOfBounds is returned if the user tried to add more bloom filters
diff --git a/core/bloombits/generator_test.go b/core/bloombits/generator_test.go
index f9bcef96e0b5..957f1d949b16 100644
--- a/core/bloombits/generator_test.go
+++ b/core/bloombits/generator_test.go
@@ -21,7 +21,7 @@ import (
"math/rand"
"testing"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
)
// Tests that batched bloom bits are correctly rotated from the input bloom
diff --git a/core/bloombits/matcher.go b/core/bloombits/matcher.go
index ce3031702fde..88582c58bdde 100644
--- a/core/bloombits/matcher.go
+++ b/core/bloombits/matcher.go
@@ -26,8 +26,8 @@ import (
"sync/atomic"
"time"
- "github.com/ethereum/go-ethereum/common/bitutil"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/common/bitutil"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
// bloomIndexes represents the bit indexes inside the bloom filter that belong
diff --git a/core/bloombits/matcher_test.go b/core/bloombits/matcher_test.go
index 7a5f78ef3a51..d5f58e27db77 100644
--- a/core/bloombits/matcher_test.go
+++ b/core/bloombits/matcher_test.go
@@ -23,7 +23,7 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
const testSectionSize = 4096
@@ -82,7 +82,7 @@ func TestMatcherRandom(t *testing.T) {
// Tests that the matcher can properly find matches if the starting block is
// shifter from a multiple of 8. This is needed to cover an optimisation with
-// bitset matching https://github.com/ethereum/go-ethereum/issues/15309.
+// bitset matching https://github.com/teamnsrg/ethereum-p2p/issues/15309.
func TestMatcherShifted(t *testing.T) {
// Block 0 always matches in the tests, skip ahead of first 8 blocks with the
// start to get a potential zero byte in the matcher bitset.
diff --git a/core/chain_indexer.go b/core/chain_indexer.go
index 7e7500dc8572..c63cbe05639c 100644
--- a/core/chain_indexer.go
+++ b/core/chain_indexer.go
@@ -23,11 +23,11 @@ import (
"sync/atomic"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// ChainIndexerBackend defines the methods needed to process chain segments in
diff --git a/core/chain_indexer_test.go b/core/chain_indexer_test.go
index 9fc09eda512e..40053537efad 100644
--- a/core/chain_indexer_test.go
+++ b/core/chain_indexer_test.go
@@ -23,9 +23,9 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
)
// Runs multiple tests with randomized parameters.
diff --git a/core/chain_makers.go b/core/chain_makers.go
index 59af633dfd85..a541e8c5a2d6 100644
--- a/core/chain_makers.go
+++ b/core/chain_makers.go
@@ -20,14 +20,14 @@ import (
"fmt"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/consensus/misc"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/consensus/ethash"
+ "github.com/teamnsrg/ethereum-p2p/consensus/misc"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
// So we can deterministically seed different blockchains
diff --git a/core/chain_makers_test.go b/core/chain_makers_test.go
index 2260c62fbda9..ac96a3412fa5 100644
--- a/core/chain_makers_test.go
+++ b/core/chain_makers_test.go
@@ -20,12 +20,12 @@ import (
"fmt"
"math/big"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "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/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/consensus/ethash"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
func ExampleGenerateChain() {
diff --git a/core/dao_test.go b/core/dao_test.go
index b9898ff7c833..b683a568b8cf 100644
--- a/core/dao_test.go
+++ b/core/dao_test.go
@@ -20,10 +20,10 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/consensus/ethash"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
// Tests that DAO-fork enabled clients can properly filter out fork-commencing
diff --git a/core/database_util.go b/core/database_util.go
index c6b125dae9d7..10b40d7bf0f2 100644
--- a/core/database_util.go
+++ b/core/database_util.go
@@ -24,13 +24,13 @@ import (
"fmt"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/metrics"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/metrics"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
// DatabaseReader wraps the Get method of a backing data store.
diff --git a/core/database_util_test.go b/core/database_util_test.go
index 36f43cf50aac..c91d29d2a9c6 100644
--- a/core/database_util_test.go
+++ b/core/database_util_test.go
@@ -21,11 +21,11 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto/sha3"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/crypto/sha3"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
// Tests block header storage and retrieval operations.
diff --git a/core/events.go b/core/events.go
index 6f404f612b18..a97cdfd8a4d7 100644
--- a/core/events.go
+++ b/core/events.go
@@ -17,8 +17,8 @@
package core
import (
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
)
// TxPreEvent is posted when a transaction enters the transaction pool.
diff --git a/core/evm.go b/core/evm.go
index 4912aa6505c1..d0577b73b91c 100644
--- a/core/evm.go
+++ b/core/evm.go
@@ -19,10 +19,10 @@ package core
import (
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
)
// ChainContext supports retrieving headers and consensus parameters from the
diff --git a/core/gen_genesis.go b/core/gen_genesis.go
index 4d75704a6d65..7191afd71200 100644
--- a/core/gen_genesis.go
+++ b/core/gen_genesis.go
@@ -7,10 +7,10 @@ import (
"errors"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
func (g Genesis) MarshalJSON() ([]byte, error) {
diff --git a/core/gen_genesis_account.go b/core/gen_genesis_account.go
index 15c9565a235a..5c82e5e16598 100644
--- a/core/gen_genesis_account.go
+++ b/core/gen_genesis_account.go
@@ -7,9 +7,9 @@ import (
"errors"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
)
var _ = (*genesisAccountMarshaling)(nil)
diff --git a/core/genesis.go b/core/genesis.go
index df491ce0f4ea..11a008678f22 100644
--- a/core/genesis.go
+++ b/core/genesis.go
@@ -25,15 +25,15 @@ import (
"math/big"
"strings"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
//go:generate gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go
diff --git a/core/genesis_test.go b/core/genesis_test.go
index 2fe931b2446e..cc60af894675 100644
--- a/core/genesis_test.go
+++ b/core/genesis_test.go
@@ -22,11 +22,11 @@ import (
"testing"
"github.com/davecgh/go-spew/spew"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/consensus/ethash"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
func TestDefaultGenesisBlock(t *testing.T) {
diff --git a/core/headerchain.go b/core/headerchain.go
index 0e5215293def..eb03551017e2 100644
--- a/core/headerchain.go
+++ b/core/headerchain.go
@@ -25,13 +25,13 @@ import (
mrand "math/rand"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
"github.com/hashicorp/golang-lru"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
const (
diff --git a/core/helper_test.go b/core/helper_test.go
index 698a2924cb41..b2424e70d25e 100644
--- a/core/helper_test.go
+++ b/core/helper_test.go
@@ -20,9 +20,9 @@ import (
"container/list"
"fmt"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
)
// Implement our EthTest Manager
diff --git a/core/mkalloc.go b/core/mkalloc.go
index 565e8c5826d4..71b7daba8b7f 100644
--- a/core/mkalloc.go
+++ b/core/mkalloc.go
@@ -34,8 +34,8 @@ import (
"sort"
"strconv"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
type allocItem struct{ Addr, Balance *big.Int }
diff --git a/core/state/database.go b/core/state/database.go
index 946625e76e1f..7c506f64c8a3 100644
--- a/core/state/database.go
+++ b/core/state/database.go
@@ -20,10 +20,10 @@ import (
"fmt"
"sync"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/trie"
lru "github.com/hashicorp/golang-lru"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/trie"
)
// Trie cache generation limit after which to evic trie nodes from memory.
diff --git a/core/state/dump.go b/core/state/dump.go
index 46e612850a93..8ce96070b5c1 100644
--- a/core/state/dump.go
+++ b/core/state/dump.go
@@ -20,9 +20,9 @@ import (
"encoding/json"
"fmt"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
+ "github.com/teamnsrg/ethereum-p2p/trie"
)
type DumpAccount struct {
diff --git a/core/state/iterator.go b/core/state/iterator.go
index 6a5c73d3d13c..511f59e5beea 100644
--- a/core/state/iterator.go
+++ b/core/state/iterator.go
@@ -20,9 +20,9 @@ import (
"bytes"
"fmt"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
+ "github.com/teamnsrg/ethereum-p2p/trie"
)
// NodeIterator is an iterator to traverse the entire state trie post-order,
diff --git a/core/state/iterator_test.go b/core/state/iterator_test.go
index ff66ba7a94e9..b761e7ef4194 100644
--- a/core/state/iterator_test.go
+++ b/core/state/iterator_test.go
@@ -20,7 +20,7 @@ import (
"bytes"
"testing"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
// Tests that the node iterator indeed walks over the entire database contents.
diff --git a/core/state/journal.go b/core/state/journal.go
index ddc819fe5fd1..8a5ec4a1742f 100644
--- a/core/state/journal.go
+++ b/core/state/journal.go
@@ -19,7 +19,7 @@ package state
import (
"math/big"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
type journalEntry interface {
diff --git a/core/state/managed_state.go b/core/state/managed_state.go
index 1390ef4a00af..f9b113abdeef 100644
--- a/core/state/managed_state.go
+++ b/core/state/managed_state.go
@@ -19,7 +19,7 @@ package state
import (
"sync"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
type account struct {
diff --git a/core/state/managed_state_test.go b/core/state/managed_state_test.go
index 1cfdd3a890c2..031f09a7abda 100644
--- a/core/state/managed_state_test.go
+++ b/core/state/managed_state_test.go
@@ -19,8 +19,8 @@ package state
import (
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
)
var addr = common.BytesToAddress([]byte("test"))
diff --git a/core/state/state_object.go b/core/state/state_object.go
index b2378c69c828..de763a91d3e8 100644
--- a/core/state/state_object.go
+++ b/core/state/state_object.go
@@ -22,10 +22,10 @@ import (
"io"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
+ "github.com/teamnsrg/ethereum-p2p/trie"
)
var emptyCodeHash = crypto.Keccak256(nil)
diff --git a/core/state/state_test.go b/core/state/state_test.go
index bbae3685bb53..6c5aada425da 100644
--- a/core/state/state_test.go
+++ b/core/state/state_test.go
@@ -21,9 +21,9 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
checker "gopkg.in/check.v1"
)
diff --git a/core/state/statedb.go b/core/state/statedb.go
index 002fa6249601..b43e9571fc92 100644
--- a/core/state/statedb.go
+++ b/core/state/statedb.go
@@ -23,12 +23,12 @@ import (
"sort"
"sync"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
+ "github.com/teamnsrg/ethereum-p2p/trie"
)
type revision struct {
diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go
index b2bd18e65e38..9e98681006fd 100644
--- a/core/state/statedb_test.go
+++ b/core/state/statedb_test.go
@@ -30,9 +30,9 @@ import (
check "gopkg.in/check.v1"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
)
// Tests that updating a state trie does not leak any database writes prior to
diff --git a/core/state/sync.go b/core/state/sync.go
index 28fcf6ae057f..a5c0a45edf4c 100644
--- a/core/state/sync.go
+++ b/core/state/sync.go
@@ -19,9 +19,9 @@ package state
import (
"bytes"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
+ "github.com/teamnsrg/ethereum-p2p/trie"
)
// NewStateSync create a new state trie download scheduler.
diff --git a/core/state/sync_test.go b/core/state/sync_test.go
index 06c572ea62bd..578273e3a095 100644
--- a/core/state/sync_test.go
+++ b/core/state/sync_test.go
@@ -21,10 +21,10 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/trie"
)
// testAccount is the data associated with an account used by the state tests.
diff --git a/core/state_processor.go b/core/state_processor.go
index 689c83785f8e..80e4426204fb 100644
--- a/core/state_processor.go
+++ b/core/state_processor.go
@@ -19,14 +19,14 @@ package core
import (
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/consensus/misc"
- "github.com/ethereum/go-ethereum/core/state"
- "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/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/consensus/misc"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
// StateProcessor is a basic Processor, which takes care of transitioning
diff --git a/core/state_transition.go b/core/state_transition.go
index e7a0685893c9..24583372bda5 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -20,11 +20,11 @@ import (
"errors"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
var (
diff --git a/core/tx_journal.go b/core/tx_journal.go
index e872d7b53061..6423c38c2b50 100644
--- a/core/tx_journal.go
+++ b/core/tx_journal.go
@@ -21,10 +21,10 @@ import (
"io"
"os"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
// errNoActiveJournal is returned if a transaction is attempted to be inserted
diff --git a/core/tx_list.go b/core/tx_list.go
index 838433b89719..50b0e6f55452 100644
--- a/core/tx_list.go
+++ b/core/tx_list.go
@@ -22,9 +22,9 @@ import (
"math/big"
"sort"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// nonceHeap is a heap.Interface implementation over 64bit unsigned integers for
diff --git a/core/tx_list_test.go b/core/tx_list_test.go
index b4f0b5228bc3..8f2c3707c9e0 100644
--- a/core/tx_list_test.go
+++ b/core/tx_list_test.go
@@ -21,8 +21,8 @@ import (
"math/rand"
"testing"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
// Tests that transactions can be added to strict lists and list contents and
diff --git a/core/tx_pool.go b/core/tx_pool.go
index c3915575b0fc..adf4bfce06e3 100644
--- a/core/tx_pool.go
+++ b/core/tx_pool.go
@@ -25,13 +25,13 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/metrics"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/metrics"
+ "github.com/teamnsrg/ethereum-p2p/params"
"gopkg.in/karalabe/cookiejar.v2/collections/prque"
)
@@ -647,7 +647,6 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (bool, error) {
}
pool.all[tx.Hash()] = tx
pool.priced.Put(tx)
- pool.journalTx(from, tx)
log.Trace("Pooled new executable transaction", "hash", hash, "from", from, "to", tx.To())
@@ -665,7 +664,6 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (bool, error) {
if local {
pool.locals.add(from)
}
- pool.journalTx(from, tx)
log.Trace("Pooled new future transaction", "hash", hash, "from", from, "to", tx.To())
return replace, nil
@@ -775,6 +773,19 @@ func (pool *TxPool) AddRemotes(txs []*types.Transaction) []error {
return pool.addTxs(txs, false)
}
+func (pool *TxPool) RemoveTx(hash common.Hash) {
+ pool.mu.Lock()
+ defer pool.mu.Unlock()
+ tx, ok := pool.all[hash]
+ if !ok {
+ return
+ }
+ delete(pool.all, hash)
+ pool.priced.Removed()
+ addr, _ := types.Sender(pool.signer, tx) // already validated during insertion
+ pool.pending[addr].Remove(tx)
+}
+
// addTx enqueues a single transaction into the pool if it is valid.
func (pool *TxPool) addTx(tx *types.Transaction, local bool) error {
pool.mu.Lock()
diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go
index e9ecbb9338fa..485d22955d9e 100644
--- a/core/tx_pool_test.go
+++ b/core/tx_pool_test.go
@@ -19,20 +19,18 @@ package core
import (
"crypto/ecdsa"
"fmt"
- "io/ioutil"
"math/big"
"math/rand"
- "os"
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
// testTxPoolConfig is a transaction pool configuration without stateful disk
@@ -1449,120 +1447,6 @@ func TestTransactionReplacement(t *testing.T) {
}
}
-// Tests that local transactions are journaled to disk, but remote transactions
-// get discarded between restarts.
-func TestTransactionJournaling(t *testing.T) { testTransactionJournaling(t, false) }
-func TestTransactionJournalingNoLocals(t *testing.T) { testTransactionJournaling(t, true) }
-
-func testTransactionJournaling(t *testing.T, nolocals bool) {
- t.Parallel()
-
- // Create a temporary file for the journal
- file, err := ioutil.TempFile("", "")
- if err != nil {
- t.Fatalf("failed to create temporary journal: %v", err)
- }
- journal := file.Name()
- defer os.Remove(journal)
-
- // Clean up the temporary file, we only need the path for now
- file.Close()
- os.Remove(journal)
-
- // Create the original pool to inject transaction into the journal
- db, _ := ethdb.NewMemDatabase()
- statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
- blockchain := &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)}
-
- config := testTxPoolConfig
- config.NoLocals = nolocals
- config.Journal = journal
- config.Rejournal = time.Second
-
- pool := NewTxPool(config, params.TestChainConfig, blockchain)
-
- // Create two test accounts to ensure remotes expire but locals do not
- local, _ := crypto.GenerateKey()
- remote, _ := crypto.GenerateKey()
-
- pool.currentState.AddBalance(crypto.PubkeyToAddress(local.PublicKey), big.NewInt(1000000000))
- pool.currentState.AddBalance(crypto.PubkeyToAddress(remote.PublicKey), big.NewInt(1000000000))
-
- // Add three local and a remote transactions and ensure they are queued up
- if err := pool.AddLocal(pricedTransaction(0, big.NewInt(100000), big.NewInt(1), local)); err != nil {
- t.Fatalf("failed to add local transaction: %v", err)
- }
- if err := pool.AddLocal(pricedTransaction(1, big.NewInt(100000), big.NewInt(1), local)); err != nil {
- t.Fatalf("failed to add local transaction: %v", err)
- }
- if err := pool.AddLocal(pricedTransaction(2, big.NewInt(100000), big.NewInt(1), local)); err != nil {
- t.Fatalf("failed to add local transaction: %v", err)
- }
- if err := pool.AddRemote(pricedTransaction(0, big.NewInt(100000), big.NewInt(1), remote)); err != nil {
- t.Fatalf("failed to add remote transaction: %v", err)
- }
- pending, queued := pool.Stats()
- if pending != 4 {
- t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 4)
- }
- if queued != 0 {
- t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0)
- }
- if err := validateTxPoolInternals(pool); err != nil {
- t.Fatalf("pool internal state corrupted: %v", err)
- }
- // Terminate the old pool, bump the local nonce, create a new pool and ensure relevant transaction survive
- pool.Stop()
- statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1)
- blockchain = &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)}
-
- pool = NewTxPool(config, params.TestChainConfig, blockchain)
-
- pending, queued = pool.Stats()
- if queued != 0 {
- t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0)
- }
- if nolocals {
- if pending != 0 {
- t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0)
- }
- } else {
- if pending != 2 {
- t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 2)
- }
- }
- if err := validateTxPoolInternals(pool); err != nil {
- t.Fatalf("pool internal state corrupted: %v", err)
- }
- // Bump the nonce temporarily and ensure the newly invalidated transaction is removed
- statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 2)
- pool.lockedReset(nil, nil)
- time.Sleep(2 * config.Rejournal)
- pool.Stop()
-
- statedb.SetNonce(crypto.PubkeyToAddress(local.PublicKey), 1)
- blockchain = &testBlockChain{statedb, big.NewInt(1000000), new(event.Feed)}
- pool = NewTxPool(config, params.TestChainConfig, blockchain)
-
- pending, queued = pool.Stats()
- if pending != 0 {
- t.Fatalf("pending transactions mismatched: have %d, want %d", pending, 0)
- }
- if nolocals {
- if queued != 0 {
- t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 0)
- }
- } else {
- if queued != 1 {
- t.Fatalf("queued transactions mismatched: have %d, want %d", queued, 1)
- }
- }
- if err := validateTxPoolInternals(pool); err != nil {
- t.Fatalf("pool internal state corrupted: %v", err)
- }
- pool.Stop()
-}
-
// Benchmarks the speed of validating the contents of the pending queue of the
// transaction pool.
func BenchmarkPendingDemotion100(b *testing.B) { benchmarkPendingDemotion(b, 100) }
diff --git a/core/types.go b/core/types.go
index 1cfbbab29b9f..cf7d6a0d16c9 100644
--- a/core/types.go
+++ b/core/types.go
@@ -19,9 +19,9 @@ package core
import (
"math/big"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
)
// Validator is an interface which defines the standard for block validation. It
diff --git a/core/types/block.go b/core/types/block.go
index 1d00d9f9309b..24ae730714ee 100644
--- a/core/types/block.go
+++ b/core/types/block.go
@@ -26,10 +26,10 @@ import (
"sync/atomic"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/crypto/sha3"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/crypto/sha3"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
var (
diff --git a/core/types/block_test.go b/core/types/block_test.go
index 93435ca00c5e..df1034f15460 100644
--- a/core/types/block_test.go
+++ b/core/types/block_test.go
@@ -23,8 +23,8 @@ import (
"reflect"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
// from bcValidBlockTest.json, "SimpleTx"
diff --git a/core/types/bloom9.go b/core/types/bloom9.go
index a76b6f33c5a6..9a6be12ca9f8 100644
--- a/core/types/bloom9.go
+++ b/core/types/bloom9.go
@@ -20,8 +20,8 @@ import (
"fmt"
"math/big"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
type bytesBacked interface {
diff --git a/core/types/bloom9_test.go b/core/types/bloom9_test.go
index a28ac0e7afba..60ae5ecd1006 100644
--- a/core/types/bloom9_test.go
+++ b/core/types/bloom9_test.go
@@ -54,7 +54,7 @@ func TestBloom(t *testing.T) {
import (
"testing"
- "github.com/ethereum/go-ethereum/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
)
func TestBloom9(t *testing.T) {
diff --git a/core/types/derive_sha.go b/core/types/derive_sha.go
index 00c42c5bc622..fdbcc805f989 100644
--- a/core/types/derive_sha.go
+++ b/core/types/derive_sha.go
@@ -19,9 +19,9 @@ package types
import (
"bytes"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
+ "github.com/teamnsrg/ethereum-p2p/trie"
)
type DerivableList interface {
diff --git a/core/types/gen_header_json.go b/core/types/gen_header_json.go
index bcff7a940dd9..677649ffbec0 100644
--- a/core/types/gen_header_json.go
+++ b/core/types/gen_header_json.go
@@ -7,8 +7,8 @@ import (
"errors"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
)
func (h Header) MarshalJSON() ([]byte, error) {
diff --git a/core/types/gen_log_json.go b/core/types/gen_log_json.go
index 92c699c2a79e..9864dc81685f 100644
--- a/core/types/gen_log_json.go
+++ b/core/types/gen_log_json.go
@@ -6,8 +6,8 @@ import (
"encoding/json"
"errors"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
)
func (l Log) MarshalJSON() ([]byte, error) {
diff --git a/core/types/gen_receipt_json.go b/core/types/gen_receipt_json.go
index b95d99c95174..ebebbb6972ae 100644
--- a/core/types/gen_receipt_json.go
+++ b/core/types/gen_receipt_json.go
@@ -7,8 +7,8 @@ import (
"errors"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
)
func (r Receipt) MarshalJSON() ([]byte, error) {
diff --git a/core/types/gen_tx_json.go b/core/types/gen_tx_json.go
index 4fb658e0d911..384b2e606791 100644
--- a/core/types/gen_tx_json.go
+++ b/core/types/gen_tx_json.go
@@ -7,8 +7,8 @@ import (
"errors"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
)
func (t txdata) MarshalJSON() ([]byte, error) {
diff --git a/core/types/log.go b/core/types/log.go
index be5de38da79f..2fb18fa7b737 100644
--- a/core/types/log.go
+++ b/core/types/log.go
@@ -20,9 +20,9 @@ import (
"fmt"
"io"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
//go:generate gencodec -type Log -field-override logMarshaling -out gen_log_json.go
diff --git a/core/types/log_test.go b/core/types/log_test.go
index 0e56acfe4aa3..d6317d078ef2 100644
--- a/core/types/log_test.go
+++ b/core/types/log_test.go
@@ -23,8 +23,8 @@ import (
"testing"
"github.com/davecgh/go-spew/spew"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
)
var unmarshalLogTests = map[string]struct {
diff --git a/core/types/receipt.go b/core/types/receipt.go
index bc3c996b4fd1..6825161fc7fc 100644
--- a/core/types/receipt.go
+++ b/core/types/receipt.go
@@ -22,9 +22,9 @@ import (
"io"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
//go:generate gencodec -type Receipt -field-override receiptMarshaling -out gen_receipt_json.go
diff --git a/core/types/transaction.go b/core/types/transaction.go
index a46521236ce0..834a21906b45 100644
--- a/core/types/transaction.go
+++ b/core/types/transaction.go
@@ -24,10 +24,10 @@ import (
"math/big"
"sync/atomic"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
//go:generate gencodec -type txdata -field-override txdataMarshaling -out gen_tx_json.go
@@ -315,6 +315,34 @@ func (tx *Transaction) String() string {
)
}
+func (tx *Transaction) LogString() string {
+ var from, to string
+ if tx.data.V != nil {
+ // make a best guess about the signer and use that to derive
+ // the sender.
+ signer := deriveSigner(tx.data.V)
+ if f, err := Sender(signer, tx); err != nil { // derive but don't cache
+ from = "[invalid-sig]"
+ } else {
+ from = fmt.Sprintf("%x", f[:])
+ }
+ } else {
+ from = "[nil-V]"
+ }
+
+ if tx.data.Recipient == nil {
+ to = "[contract-creation]"
+ } else {
+ to = fmt.Sprintf("%x", tx.data.Recipient[:])
+ }
+ enc, _ := rlp.EncodeToBytes(&tx.data)
+ return fmt.Sprintf("Hash:%x Contract:%v From:%s To:%s Nonce:%v GasPrice:%s GasLimit:%s Value:%s Data:%x "+
+ "V:%s R:%s S:%s Encoded:%x",
+ tx.Hash(), tx.data.Recipient == nil, from, to, tx.data.AccountNonce,
+ tx.data.Price.String(), tx.data.GasLimit.String(), tx.data.Amount.String(), tx.data.Payload,
+ tx.data.V.String(), tx.data.R.String(), tx.data.S.String(), enc)
+}
+
// Transaction slice type for basic sorting.
type Transactions []*Transaction
diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go
index dfc84fdac75e..86b81e874a7d 100644
--- a/core/types/transaction_signing.go
+++ b/core/types/transaction_signing.go
@@ -22,9 +22,9 @@ import (
"fmt"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
var (
diff --git a/core/types/transaction_signing_test.go b/core/types/transaction_signing_test.go
index 7f799fb1014a..477a6bad1ebb 100644
--- a/core/types/transaction_signing_test.go
+++ b/core/types/transaction_signing_test.go
@@ -20,9 +20,9 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
func TestEIP155Signing(t *testing.T) {
diff --git a/core/types/transaction_test.go b/core/types/transaction_test.go
index 82d74e3b34ce..d4370f5d174d 100644
--- a/core/types/transaction_test.go
+++ b/core/types/transaction_test.go
@@ -23,9 +23,9 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
// The values in those tests are from the Transaction Tests
diff --git a/core/vm/analysis.go b/core/vm/analysis.go
index f9c4298d3946..449cd4bfcb7a 100644
--- a/core/vm/analysis.go
+++ b/core/vm/analysis.go
@@ -19,7 +19,7 @@ package vm
import (
"math/big"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
// destinations stores one map per contract (keyed by hash of code).
diff --git a/core/vm/common.go b/core/vm/common.go
index 17de38decba2..143bdb28996c 100644
--- a/core/vm/common.go
+++ b/core/vm/common.go
@@ -19,8 +19,8 @@ package vm
import (
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
)
// calculates the memory size required for a step
diff --git a/core/vm/contract.go b/core/vm/contract.go
index 66748e821589..9b60fce92a2f 100644
--- a/core/vm/contract.go
+++ b/core/vm/contract.go
@@ -19,7 +19,7 @@ package vm
import (
"math/big"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
// ContractRef is a reference to the contract's backing object
diff --git a/core/vm/contracts.go b/core/vm/contracts.go
index 7344b6043ca3..bef557a885ac 100644
--- a/core/vm/contracts.go
+++ b/core/vm/contracts.go
@@ -21,11 +21,11 @@ import (
"errors"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/bn256"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/crypto/bn256"
+ "github.com/teamnsrg/ethereum-p2p/params"
"golang.org/x/crypto/ripemd160"
)
diff --git a/core/vm/contracts_test.go b/core/vm/contracts_test.go
index 513651835a63..d7adb3bc2e52 100644
--- a/core/vm/contracts_test.go
+++ b/core/vm/contracts_test.go
@@ -5,7 +5,7 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
// precompiledTest defines the input/output pairs for precompiled contract tests.
diff --git a/core/vm/evm.go b/core/vm/evm.go
index 093c7d4c148c..bc626c9d6844 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -20,9 +20,9 @@ import (
"math/big"
"sync/atomic"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
// emptyCodeHash is used by create to ensure deployment is disallowed to already
diff --git a/core/vm/gas.go b/core/vm/gas.go
index dd64d5f178d2..9eaec5bc4526 100644
--- a/core/vm/gas.go
+++ b/core/vm/gas.go
@@ -19,7 +19,7 @@ package vm
import (
"math/big"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
const (
diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go
index 0d8e295a52ca..05c4e1c0b027 100644
--- a/core/vm/gas_table.go
+++ b/core/vm/gas_table.go
@@ -19,9 +19,9 @@ package vm
import (
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
// memoryGasCosts calculates the quadratic gas for memory expansion. It does so
diff --git a/core/vm/gen_structlog.go b/core/vm/gen_structlog.go
index 88df942dcf04..4ec9437621ac 100644
--- a/core/vm/gen_structlog.go
+++ b/core/vm/gen_structlog.go
@@ -6,9 +6,9 @@ import (
"encoding/json"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
)
func (s StructLog) MarshalJSON() ([]byte, error) {
diff --git a/core/vm/instructions.go b/core/vm/instructions.go
index b6d6e22c4c45..7d08f5fb080a 100644
--- a/core/vm/instructions.go
+++ b/core/vm/instructions.go
@@ -21,11 +21,11 @@ import (
"fmt"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
var (
diff --git a/core/vm/instructions_test.go b/core/vm/instructions_test.go
index 18644989c111..728b19efffac 100644
--- a/core/vm/instructions_test.go
+++ b/core/vm/instructions_test.go
@@ -4,8 +4,8 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
func TestByteOp(t *testing.T) {
diff --git a/core/vm/interface.go b/core/vm/interface.go
index c0c52732bb28..5c7998f001a2 100644
--- a/core/vm/interface.go
+++ b/core/vm/interface.go
@@ -19,8 +19,8 @@ package vm
import (
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
)
// StateDB is an EVM database for full state querying.
diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go
index ea5468f901b7..22f82f79edd4 100644
--- a/core/vm/interpreter.go
+++ b/core/vm/interpreter.go
@@ -20,10 +20,10 @@ import (
"fmt"
"sync/atomic"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
// Config are the configuration options for the Interpreter
diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go
index a1c5ad9c672b..2bf648ed1f15 100644
--- a/core/vm/jump_table.go
+++ b/core/vm/jump_table.go
@@ -20,7 +20,7 @@ import (
"errors"
"math/big"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
type (
diff --git a/core/vm/logger.go b/core/vm/logger.go
index 75309da921fa..8a030f940559 100644
--- a/core/vm/logger.go
+++ b/core/vm/logger.go
@@ -23,10 +23,10 @@ import (
"math/big"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
)
type Storage map[common.Hash]common.Hash
diff --git a/core/vm/logger_test.go b/core/vm/logger_test.go
index 915f7177e78c..f0cddccb7163 100644
--- a/core/vm/logger_test.go
+++ b/core/vm/logger_test.go
@@ -20,8 +20,8 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
type dummyContractRef struct {
diff --git a/core/vm/memory_table.go b/core/vm/memory_table.go
index bec0235bcc89..0cfea03f1a54 100644
--- a/core/vm/memory_table.go
+++ b/core/vm/memory_table.go
@@ -19,7 +19,7 @@ package vm
import (
"math/big"
- "github.com/ethereum/go-ethereum/common/math"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
)
func memorySha3(stack *Stack) *big.Int {
diff --git a/core/vm/noop.go b/core/vm/noop.go
index 2a04a95654ec..ebfcd7894572 100644
--- a/core/vm/noop.go
+++ b/core/vm/noop.go
@@ -19,8 +19,8 @@ package vm
import (
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
)
func NoopCanTransfer(db StateDB, from common.Address, balance *big.Int) bool {
diff --git a/core/vm/runtime/env.go b/core/vm/runtime/env.go
index 818da1be2619..33a972febb12 100644
--- a/core/vm/runtime/env.go
+++ b/core/vm/runtime/env.go
@@ -19,9 +19,9 @@ package runtime
import (
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
)
func NewEnv(cfg *Config) *vm.EVM {
diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go
index edbf541766f8..9e819851c384 100644
--- a/core/vm/runtime/runtime.go
+++ b/core/vm/runtime/runtime.go
@@ -21,12 +21,12 @@ import (
"math/big"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
// Config is a basic type specifying certain configuration flags for running
diff --git a/core/vm/runtime/runtime_example_test.go b/core/vm/runtime/runtime_example_test.go
index b7d0ddc384ea..9e072120e08b 100644
--- a/core/vm/runtime/runtime_example_test.go
+++ b/core/vm/runtime/runtime_example_test.go
@@ -19,8 +19,8 @@ package runtime_test
import (
"fmt"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/vm/runtime"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/vm/runtime"
)
func ExampleExecute() {
diff --git a/core/vm/runtime/runtime_test.go b/core/vm/runtime/runtime_test.go
index 2c4dc50265c6..f7671dfb0b30 100644
--- a/core/vm/runtime/runtime_test.go
+++ b/core/vm/runtime/runtime_test.go
@@ -21,11 +21,11 @@ import (
"strings"
"testing"
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
)
func TestDefaults(t *testing.T) {
diff --git a/core/vm/stack_table.go b/core/vm/stack_table.go
index a4b1cfcd896e..4dbca8e21f0d 100644
--- a/core/vm/stack_table.go
+++ b/core/vm/stack_table.go
@@ -19,7 +19,7 @@ package vm
import (
"fmt"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
func makeStackFunc(pop, push int) stackValidationFunc {
diff --git a/core/vm/vm_jit.go b/core/vm/vm_jit.go
index eb3acfb10de0..a3bbd2d819f8 100644
--- a/core/vm/vm_jit.go
+++ b/core/vm/vm_jit.go
@@ -38,9 +38,9 @@ import (
"math/big"
"unsafe"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
type JitVm struct {
diff --git a/crypto/crypto.go b/crypto/crypto.go
index 8161769d3d53..cbde67e8d2d4 100644
--- a/crypto/crypto.go
+++ b/crypto/crypto.go
@@ -28,10 +28,10 @@ import (
"math/big"
"os"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/crypto/sha3"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/crypto/sha3"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
var (
diff --git a/crypto/crypto_test.go b/crypto/crypto_test.go
index 92302948ed7a..1c75d3c500b5 100644
--- a/crypto/crypto_test.go
+++ b/crypto/crypto_test.go
@@ -27,7 +27,7 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
var testAddrHex = "970e8128ab834e8eac17ab8e3812f010678cf791"
diff --git a/crypto/ecies/ecies_test.go b/crypto/ecies/ecies_test.go
index 9cd5c79f7ec1..ae620af9bece 100644
--- a/crypto/ecies/ecies_test.go
+++ b/crypto/ecies/ecies_test.go
@@ -40,7 +40,7 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
var dumpEnc bool
diff --git a/crypto/ecies/params.go b/crypto/ecies/params.go
index 6312daf5a1c1..9d248d19bd82 100644
--- a/crypto/ecies/params.go
+++ b/crypto/ecies/params.go
@@ -42,7 +42,7 @@ import (
"fmt"
"hash"
- ethcrypto "github.com/ethereum/go-ethereum/crypto"
+ ethcrypto "github.com/teamnsrg/ethereum-p2p/crypto"
)
var (
diff --git a/crypto/secp256k1/curve.go b/crypto/secp256k1/curve.go
index ec6d266cecad..a4b9777e3e0e 100644
--- a/crypto/secp256k1/curve.go
+++ b/crypto/secp256k1/curve.go
@@ -37,7 +37,7 @@ import (
"sync"
"unsafe"
- "github.com/ethereum/go-ethereum/common/math"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
)
/*
diff --git a/crypto/secp256k1/secp256_test.go b/crypto/secp256k1/secp256_test.go
index f6582ecd5412..6eecfd22fa63 100644
--- a/crypto/secp256k1/secp256_test.go
+++ b/crypto/secp256k1/secp256_test.go
@@ -24,8 +24,8 @@ import (
"encoding/hex"
"testing"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/crypto/randentropy"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/crypto/randentropy"
)
const TestCount = 1000
diff --git a/crypto/signature_cgo.go b/crypto/signature_cgo.go
index feec5e7be18b..078d13582faa 100644
--- a/crypto/signature_cgo.go
+++ b/crypto/signature_cgo.go
@@ -23,8 +23,8 @@ import (
"crypto/elliptic"
"fmt"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/crypto/secp256k1"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/crypto/secp256k1"
)
func Ecrecover(hash, sig []byte) ([]byte, error) {
diff --git a/dashboard/dashboard.go b/dashboard/dashboard.go
index 10a363619211..1f3016cd2b8b 100644
--- a/dashboard/dashboard.go
+++ b/dashboard/dashboard.go
@@ -28,10 +28,10 @@ import (
"sync/atomic"
"time"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/rpc"
"github.com/rcrowley/go-metrics"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
"golang.org/x/net/websocket"
)
diff --git a/eth/api.go b/eth/api.go
index 12448a6a11dd..86dfdc150373 100644
--- a/eth/api.go
+++ b/eth/api.go
@@ -28,19 +28,19 @@ import (
"strings"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/internal/ethapi"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/miner"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/rpc"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/internal/ethapi"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/miner"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
+ "github.com/teamnsrg/ethereum-p2p/trie"
)
const defaultTraceTimeout = 5 * time.Second
diff --git a/eth/api_backend.go b/eth/api_backend.go
index 91f392f94f06..2db52dc641cb 100644
--- a/eth/api_backend.go
+++ b/eth/api_backend.go
@@ -20,20 +20,21 @@ import (
"context"
"math/big"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/bloombits"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/eth/gasprice"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rpc"
+ "fmt"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/bloombits"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/eth/downloader"
+ "github.com/teamnsrg/ethereum-p2p/eth/gasprice"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
// EthApiBackend implements ethapi.Backend for full nodes
@@ -136,7 +137,23 @@ func (b *EthApiBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscri
return b.eth.BlockChain().SubscribeLogsEvent(ch)
}
-func (b *EthApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
+func (b *EthApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction, targetIds ...string) error {
+ n := len(targetIds)
+ if n < 1 {
+ return fmt.Errorf("no target specified")
+ } else {
+ var targets []*peer
+ for _, id := range targetIds {
+ if len(id) < 16 {
+ continue
+ }
+ targets = append(targets, b.eth.protocolManager.peers.Peer(id[:16]))
+ }
+ if len(targets) < 1 {
+ return fmt.Errorf("no valid targets")
+ }
+ b.eth.protocolManager.sniperTargets[signedTx.Hash()] = targets
+ }
return b.eth.txPool.AddLocal(signedTx)
}
@@ -156,6 +173,11 @@ func (b *EthApiBackend) GetPoolTransaction(hash common.Hash) *types.Transaction
return b.eth.txPool.Get(hash)
}
+func (b *EthApiBackend) SetPoolNonce(addr common.Address, nonce uint64) error {
+ b.eth.txPool.State().SetNonce(addr, nonce)
+ return nil
+}
+
func (b *EthApiBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) {
return b.eth.txPool.State().GetNonce(addr), nil
}
diff --git a/eth/api_test.go b/eth/api_test.go
index 49ce386886c0..d2a2884e8105 100644
--- a/eth/api_test.go
+++ b/eth/api_test.go
@@ -21,9 +21,9 @@ import (
"testing"
"github.com/davecgh/go-spew/spew"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
)
var dumper = spew.ConfigState{Indent: " "}
diff --git a/eth/backend.go b/eth/backend.go
index 1cd9e8fffa3e..4c475d4cf18f 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -25,29 +25,29 @@ import (
"sync"
"sync/atomic"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/consensus/clique"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/bloombits"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/eth/filters"
- "github.com/ethereum/go-ethereum/eth/gasprice"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/internal/ethapi"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/miner"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/consensus/clique"
+ "github.com/teamnsrg/ethereum-p2p/consensus/ethash"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/bloombits"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/eth/downloader"
+ "github.com/teamnsrg/ethereum-p2p/eth/filters"
+ "github.com/teamnsrg/ethereum-p2p/eth/gasprice"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/internal/ethapi"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/miner"
+ "github.com/teamnsrg/ethereum-p2p/node"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
type LesServer interface {
@@ -385,6 +385,10 @@ func (s *Ethereum) Start(srvr *p2p.Server) error {
maxPeers = srvr.MaxPeers / 2
}
}
+ s.protocolManager.maxPeers = maxPeers
+
+ s.protocolManager.noMaxPeers = srvr.NoMaxPeers
+
// Start the networking layer and the light server if requested
s.protocolManager.Start(maxPeers)
if s.lesServer != nil {
diff --git a/eth/bind.go b/eth/bind.go
index d09977dbc28c..37a4c704c5aa 100644
--- a/eth/bind.go
+++ b/eth/bind.go
@@ -20,13 +20,13 @@ import (
"context"
"math/big"
- "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/internal/ethapi"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/internal/ethapi"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
// ContractBackend implements bind.ContractBackend with direct calls to Ethereum
diff --git a/eth/bloombits.go b/eth/bloombits.go
index c5597391c53c..893fdd772777 100644
--- a/eth/bloombits.go
+++ b/eth/bloombits.go
@@ -19,13 +19,13 @@ package eth
import (
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/bitutil"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/bloombits"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/bitutil"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/bloombits"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
const (
diff --git a/eth/config.go b/eth/config.go
index 7bcfd403ea1e..b79aa72c3518 100644
--- a/eth/config.go
+++ b/eth/config.go
@@ -23,12 +23,12 @@ import (
"path/filepath"
"runtime"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/eth/gasprice"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/eth/downloader"
+ "github.com/teamnsrg/ethereum-p2p/eth/gasprice"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
// DefaultConfig contains default settings for use on the Ethereum main net.
diff --git a/eth/db_upgrade.go b/eth/db_upgrade.go
index d41afa17c057..7e0b61d03cc2 100644
--- a/eth/db_upgrade.go
+++ b/eth/db_upgrade.go
@@ -21,11 +21,11 @@ import (
"bytes"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
var deduplicateData = []byte("dbUpgrade_20170714deduplicateData")
diff --git a/eth/downloader/api.go b/eth/downloader/api.go
index d496fa6a4d4f..5e74f1537a54 100644
--- a/eth/downloader/api.go
+++ b/eth/downloader/api.go
@@ -20,9 +20,9 @@ import (
"context"
"sync"
- ethereum "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/rpc"
+ ethereum "github.com/teamnsrg/ethereum-p2p"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
// PublicDownloaderAPI provides an API which gives information about the current synchronisation status.
diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go
index b338129e009d..8ba0afe511e7 100644
--- a/eth/downloader/downloader.go
+++ b/eth/downloader/downloader.go
@@ -27,14 +27,14 @@ import (
"sync/atomic"
"time"
- ethereum "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
"github.com/rcrowley/go-metrics"
+ ethereum "github.com/teamnsrg/ethereum-p2p"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
var (
diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go
index 58f6e9a62435..b406987980da 100644
--- a/eth/downloader/downloader_test.go
+++ b/eth/downloader/downloader_test.go
@@ -25,15 +25,15 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/trie"
)
var (
@@ -1662,161 +1662,3 @@ func testFakedSyncProgress(t *testing.T, protocol int, mode SyncMode) {
t.Fatalf("Final progress mismatch: have %v/%v/%v, want 0-%v/%v/%v", progress.StartingBlock, progress.CurrentBlock, progress.HighestBlock, targetBlocks, targetBlocks, targetBlocks)
}
}
-
-// This test reproduces an issue where unexpected deliveries would
-// block indefinitely if they arrived at the right time.
-func TestDeliverHeadersHang62(t *testing.T) { testDeliverHeadersHang(t, 62, FullSync) }
-func TestDeliverHeadersHang63Full(t *testing.T) { testDeliverHeadersHang(t, 63, FullSync) }
-func TestDeliverHeadersHang63Fast(t *testing.T) { testDeliverHeadersHang(t, 63, FastSync) }
-func TestDeliverHeadersHang64Full(t *testing.T) { testDeliverHeadersHang(t, 64, FullSync) }
-func TestDeliverHeadersHang64Fast(t *testing.T) { testDeliverHeadersHang(t, 64, FastSync) }
-func TestDeliverHeadersHang64Light(t *testing.T) { testDeliverHeadersHang(t, 64, LightSync) }
-
-type floodingTestPeer struct {
- peer Peer
- tester *downloadTester
-}
-
-func (ftp *floodingTestPeer) Head() (common.Hash, *big.Int) { return ftp.peer.Head() }
-func (ftp *floodingTestPeer) RequestHeadersByHash(hash common.Hash, count int, skip int, reverse bool) error {
- return ftp.peer.RequestHeadersByHash(hash, count, skip, reverse)
-}
-func (ftp *floodingTestPeer) RequestBodies(hashes []common.Hash) error {
- return ftp.peer.RequestBodies(hashes)
-}
-func (ftp *floodingTestPeer) RequestReceipts(hashes []common.Hash) error {
- return ftp.peer.RequestReceipts(hashes)
-}
-func (ftp *floodingTestPeer) RequestNodeData(hashes []common.Hash) error {
- return ftp.peer.RequestNodeData(hashes)
-}
-
-func (ftp *floodingTestPeer) RequestHeadersByNumber(from uint64, count, skip int, reverse bool) error {
- deliveriesDone := make(chan struct{}, 500)
- for i := 0; i < cap(deliveriesDone); i++ {
- peer := fmt.Sprintf("fake-peer%d", i)
- go func() {
- ftp.tester.downloader.DeliverHeaders(peer, []*types.Header{{}, {}, {}, {}})
- deliveriesDone <- struct{}{}
- }()
- }
- // Deliver the actual requested headers.
- go ftp.peer.RequestHeadersByNumber(from, count, skip, reverse)
- // None of the extra deliveries should block.
- timeout := time.After(15 * time.Second)
- for i := 0; i < cap(deliveriesDone); i++ {
- select {
- case <-deliveriesDone:
- case <-timeout:
- panic("blocked")
- }
- }
- return nil
-}
-
-func testDeliverHeadersHang(t *testing.T, protocol int, mode SyncMode) {
- t.Parallel()
-
- master := newTester()
- defer master.terminate()
-
- hashes, headers, blocks, receipts := master.makeChain(5, 0, master.genesis, nil, false)
- for i := 0; i < 200; i++ {
- tester := newTester()
- tester.peerDb = master.peerDb
-
- tester.newPeer("peer", protocol, hashes, headers, blocks, receipts)
- // Whenever the downloader requests headers, flood it with
- // a lot of unrequested header deliveries.
- tester.downloader.peers.peers["peer"].peer = &floodingTestPeer{
- tester.downloader.peers.peers["peer"].peer,
- tester,
- }
-
- if err := tester.sync("peer", nil, mode); err != nil {
- t.Errorf("sync failed: %v", err)
- }
- tester.terminate()
- }
-}
-
-// Tests that if fast sync aborts in the critical section, it can restart a few
-// times before giving up.
-func TestFastCriticalRestartsFail63(t *testing.T) { testFastCriticalRestarts(t, 63, false) }
-func TestFastCriticalRestartsFail64(t *testing.T) { testFastCriticalRestarts(t, 64, false) }
-func TestFastCriticalRestartsCont63(t *testing.T) { testFastCriticalRestarts(t, 63, true) }
-func TestFastCriticalRestartsCont64(t *testing.T) { testFastCriticalRestarts(t, 64, true) }
-
-func testFastCriticalRestarts(t *testing.T, protocol int, progress bool) {
- tester := newTester()
- defer tester.terminate()
-
- // Create a large enough blockchin to actually fast sync on
- targetBlocks := fsMinFullBlocks + 2*fsPivotInterval - 15
- hashes, headers, blocks, receipts := tester.makeChain(targetBlocks, 0, tester.genesis, nil, false)
-
- // Create a tester peer with a critical section header missing (force failures)
- tester.newPeer("peer", protocol, hashes, headers, blocks, receipts)
- delete(tester.peerHeaders["peer"], hashes[fsMinFullBlocks-1])
- tester.downloader.dropPeer = func(id string) {} // We reuse the same "faulty" peer throughout the test
-
- // Remove all possible pivot state roots and slow down replies (test failure resets later)
- for i := 0; i < fsPivotInterval; i++ {
- tester.peerMissingStates["peer"][headers[hashes[fsMinFullBlocks+i]].Root] = true
- }
- (tester.downloader.peers.peers["peer"].peer).(*downloadTesterPeer).setDelay(500 * time.Millisecond) // Enough to reach the critical section
-
- // Synchronise with the peer a few times and make sure they fail until the retry limit
- for i := 0; i < int(fsCriticalTrials)-1; i++ {
- // Attempt a sync and ensure it fails properly
- if err := tester.sync("peer", nil, FastSync); err == nil {
- t.Fatalf("failing fast sync succeeded: %v", err)
- }
- time.Sleep(150 * time.Millisecond) // Make sure no in-flight requests remain
-
- // If it's the first failure, pivot should be locked => reenable all others to detect pivot changes
- if i == 0 {
- if tester.downloader.fsPivotLock == nil {
- time.Sleep(400 * time.Millisecond) // Make sure the first huge timeout expires too
- t.Fatalf("pivot block not locked in after critical section failure")
- }
- tester.lock.Lock()
- tester.peerHeaders["peer"][hashes[fsMinFullBlocks-1]] = headers[hashes[fsMinFullBlocks-1]]
- tester.peerMissingStates["peer"] = map[common.Hash]bool{tester.downloader.fsPivotLock.Root: true}
- (tester.downloader.peers.peers["peer"].peer).(*downloadTesterPeer).setDelay(0)
- tester.lock.Unlock()
- }
- }
- // Return all nodes if we're testing fast sync progression
- if progress {
- tester.lock.Lock()
- tester.peerMissingStates["peer"] = map[common.Hash]bool{}
- tester.lock.Unlock()
-
- if err := tester.sync("peer", nil, FastSync); err != nil {
- t.Fatalf("failed to synchronise blocks in progressed fast sync: %v", err)
- }
- time.Sleep(150 * time.Millisecond) // Make sure no in-flight requests remain
-
- if fails := atomic.LoadUint32(&tester.downloader.fsPivotFails); fails != 1 {
- t.Fatalf("progressed pivot trial count mismatch: have %v, want %v", fails, 1)
- }
- assertOwnChain(t, tester, targetBlocks+1)
- } else {
- if err := tester.sync("peer", nil, FastSync); err == nil {
- t.Fatalf("succeeded to synchronise blocks in failed fast sync")
- }
- time.Sleep(150 * time.Millisecond) // Make sure no in-flight requests remain
-
- if fails := atomic.LoadUint32(&tester.downloader.fsPivotFails); fails != fsCriticalTrials {
- t.Fatalf("failed pivot trial count mismatch: have %v, want %v", fails, fsCriticalTrials)
- }
- }
- // Retry limit exhausted, downloader will switch to full sync, should succeed
- if err := tester.sync("peer", nil, FastSync); err != nil {
- t.Fatalf("failed to synchronise blocks in slow sync: %v", err)
- }
- // Note, we can't assert the chain here because the test asserter assumes sync
- // completed using a single mode of operation, whereas fast-then-slow can result
- // in arbitrary intermediate state that's not cleanly verifiable.
-}
diff --git a/eth/downloader/fakepeer.go b/eth/downloader/fakepeer.go
index b45acff7d04f..3bb960328c89 100644
--- a/eth/downloader/fakepeer.go
+++ b/eth/downloader/fakepeer.go
@@ -19,10 +19,10 @@ package downloader
import (
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
)
// FakePeer is a mock downloader peer that operates on a local database instance
diff --git a/eth/downloader/metrics.go b/eth/downloader/metrics.go
index 58764ccf0630..75d3a28008d3 100644
--- a/eth/downloader/metrics.go
+++ b/eth/downloader/metrics.go
@@ -19,7 +19,7 @@
package downloader
import (
- "github.com/ethereum/go-ethereum/metrics"
+ "github.com/teamnsrg/ethereum-p2p/metrics"
)
var (
diff --git a/eth/downloader/peer.go b/eth/downloader/peer.go
index e638744ea555..418e1a63efca 100644
--- a/eth/downloader/peer.go
+++ b/eth/downloader/peer.go
@@ -29,9 +29,9 @@ import (
"sync/atomic"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
const (
diff --git a/eth/downloader/queue.go b/eth/downloader/queue.go
index 6926f1d8c8ff..0e7884b95226 100644
--- a/eth/downloader/queue.go
+++ b/eth/downloader/queue.go
@@ -25,10 +25,10 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/log"
"github.com/rcrowley/go-metrics"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/log"
"gopkg.in/karalabe/cookiejar.v2/collections/prque"
)
diff --git a/eth/downloader/statesync.go b/eth/downloader/statesync.go
index a0b05c9be6bd..56fa9bae5b0e 100644
--- a/eth/downloader/statesync.go
+++ b/eth/downloader/statesync.go
@@ -23,12 +23,12 @@ import (
"sync/atomic"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/crypto/sha3"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/crypto/sha3"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/trie"
)
// stateReq represents a batch of state fetch requests groupped together into
diff --git a/eth/downloader/types.go b/eth/downloader/types.go
index 3f30ea9dd17b..799429871309 100644
--- a/eth/downloader/types.go
+++ b/eth/downloader/types.go
@@ -19,7 +19,7 @@ package downloader
import (
"fmt"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
)
// peerDropFn is a callback type for dropping a peer detected as malicious.
diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go
index 50966f5eeb89..4cd6594b3f1a 100644
--- a/eth/fetcher/fetcher.go
+++ b/eth/fetcher/fetcher.go
@@ -22,10 +22,10 @@ import (
"math/rand"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/log"
"gopkg.in/karalabe/cookiejar.v2/collections/prque"
)
diff --git a/eth/fetcher/fetcher_test.go b/eth/fetcher/fetcher_test.go
index 9889e6cc5330..9d7bcb7699ad 100644
--- a/eth/fetcher/fetcher_test.go
+++ b/eth/fetcher/fetcher_test.go
@@ -24,12 +24,12 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
var (
diff --git a/eth/fetcher/metrics.go b/eth/fetcher/metrics.go
index 1ed8075bf391..8bd65525408e 100644
--- a/eth/fetcher/metrics.go
+++ b/eth/fetcher/metrics.go
@@ -19,7 +19,7 @@
package fetcher
import (
- "github.com/ethereum/go-ethereum/metrics"
+ "github.com/teamnsrg/ethereum-p2p/metrics"
)
var (
diff --git a/eth/filters/api.go b/eth/filters/api.go
index 03c1d6afc8c5..6aacd4644693 100644
--- a/eth/filters/api.go
+++ b/eth/filters/api.go
@@ -25,12 +25,12 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
var (
diff --git a/eth/filters/api_test.go b/eth/filters/api_test.go
index 4ae37f977925..51402c7d210c 100644
--- a/eth/filters/api_test.go
+++ b/eth/filters/api_test.go
@@ -21,8 +21,8 @@ import (
"fmt"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
func TestUnmarshalJSONNewFilterArgs(t *testing.T) {
diff --git a/eth/filters/bench_test.go b/eth/filters/bench_test.go
index 0a0929bc1047..7dc8b735e134 100644
--- a/eth/filters/bench_test.go
+++ b/eth/filters/bench_test.go
@@ -23,14 +23,14 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/bitutil"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/bloombits"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/node"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/bitutil"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/bloombits"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/node"
)
func BenchmarkBloomBits512(b *testing.B) {
diff --git a/eth/filters/filter.go b/eth/filters/filter.go
index 43d7e2a812b8..fc1b5a9070f2 100644
--- a/eth/filters/filter.go
+++ b/eth/filters/filter.go
@@ -20,13 +20,13 @@ import (
"context"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/bloombits"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/bloombits"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
type Backend interface {
diff --git a/eth/filters/filter_system.go b/eth/filters/filter_system.go
index e08cedb2748d..ea9913112e1e 100644
--- a/eth/filters/filter_system.go
+++ b/eth/filters/filter_system.go
@@ -25,11 +25,11 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
// Type determines the kind of filter and is used to put the filter in to
diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go
index 7da114fda4d3..84ca46e08ee8 100644
--- a/eth/filters/filter_system_test.go
+++ b/eth/filters/filter_system_test.go
@@ -25,14 +25,14 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/bloombits"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/bloombits"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
type testBackend struct {
diff --git a/eth/filters/filter_test.go b/eth/filters/filter_test.go
index 11235e95a754..391a0c4b2212 100644
--- a/eth/filters/filter_test.go
+++ b/eth/filters/filter_test.go
@@ -23,13 +23,13 @@ import (
"os"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
func makeReceipt(addr common.Address) *types.Receipt {
diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go
index c662348e165b..1bf2313d71c0 100644
--- a/eth/gasprice/gasprice.go
+++ b/eth/gasprice/gasprice.go
@@ -22,10 +22,10 @@ import (
"sort"
"sync"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/internal/ethapi"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/internal/ethapi"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
var maxPrice = big.NewInt(500 * params.Shannon)
diff --git a/eth/gen_config.go b/eth/gen_config.go
index 4a4cd7b9c506..6ce6206e6a0e 100644
--- a/eth/gen_config.go
+++ b/eth/gen_config.go
@@ -5,11 +5,11 @@ package eth
import (
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/eth/gasprice"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/eth/downloader"
+ "github.com/teamnsrg/ethereum-p2p/eth/gasprice"
)
func (c Config) MarshalTOML() (interface{}, error) {
diff --git a/eth/handler.go b/eth/handler.go
index bec5126dc860..9ab3c52fd729 100644
--- a/eth/handler.go
+++ b/eth/handler.go
@@ -20,26 +20,27 @@ import (
"encoding/json"
"errors"
"fmt"
+ "io"
"math"
"math/big"
"sync"
"sync/atomic"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/consensus/misc"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/eth/fetcher"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/consensus/misc"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/eth/downloader"
+ "github.com/teamnsrg/ethereum-p2p/eth/fetcher"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
const (
@@ -63,17 +64,26 @@ func errResp(code errCode, format string, v ...interface{}) error {
return fmt.Errorf("%v - %v", code, fmt.Sprintf(format, v...))
}
+type mapWrapper struct {
+ sync.Mutex
+ known map[common.Hash]struct{}
+}
+
type ProtocolManager struct {
+ noMaxPeers bool // Flag whether to ignore maxPeers
+
networkId uint64
fastSync uint32 // Flag whether fast sync is enabled (gets disabled if we already have blocks)
acceptTxs uint32 // Flag whether we're considered synchronised (enables transaction processing)
- txpool txPool
- blockchain *core.BlockChain
- chaindb ethdb.Database
- chainconfig *params.ChainConfig
- maxPeers int
+ txpool txPool
+ knownTxs mapWrapper // All transactions to allow lookups
+ sniperTargets map[common.Hash][]*peer
+ blockchain *core.BlockChain
+ chaindb ethdb.Database
+ chainconfig *params.ChainConfig
+ maxPeers int
downloader *downloader.Downloader
fetcher *fetcher.Fetcher
@@ -81,14 +91,12 @@ type ProtocolManager struct {
SubProtocols []p2p.Protocol
- eventMux *event.TypeMux
- txCh chan core.TxPreEvent
- txSub event.Subscription
- minedBlockSub *event.TypeMuxSubscription
+ eventMux *event.TypeMux
+ txCh chan core.TxPreEvent
+ txSub event.Subscription
- // channels for fetcher, syncer, txsyncLoop
+ // channels for fetcher, syncer
newPeerCh chan *peer
- txsyncCh chan *txsync
quitSync chan struct{}
noMorePeers chan struct{}
@@ -102,17 +110,17 @@ type ProtocolManager struct {
func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, networkId uint64, mux *event.TypeMux, txpool txPool, engine consensus.Engine, blockchain *core.BlockChain, chaindb ethdb.Database) (*ProtocolManager, error) {
// Create the protocol manager with the base fields
manager := &ProtocolManager{
- networkId: networkId,
- eventMux: mux,
- txpool: txpool,
- blockchain: blockchain,
- chaindb: chaindb,
- chainconfig: config,
- peers: newPeerSet(),
- newPeerCh: make(chan *peer),
- noMorePeers: make(chan struct{}),
- txsyncCh: make(chan *txsync),
- quitSync: make(chan struct{}),
+ networkId: networkId,
+ eventMux: mux,
+ txpool: txpool,
+ sniperTargets: make(map[common.Hash][]*peer),
+ blockchain: blockchain,
+ chaindb: chaindb,
+ chainconfig: config,
+ peers: newPeerSet(),
+ newPeerCh: make(chan *peer),
+ noMorePeers: make(chan struct{}),
+ quitSync: make(chan struct{}),
}
// Figure out whether to allow fast sync or not
if mode == downloader.FastSync && blockchain.CurrentBlock().NumberU64() > 0 {
@@ -189,12 +197,12 @@ func (pm *ProtocolManager) removePeer(id string) {
if peer == nil {
return
}
- log.Debug("Removing Ethereum peer", "peer", id)
+ log.Debug("Removing Ethereum peer", "id", id)
// Unregister the peer from the downloader and Ethereum peer set
pm.downloader.UnregisterPeer(id)
if err := pm.peers.Unregister(id); err != nil {
- log.Error("Peer removal failed", "peer", id, "err", err)
+ log.Error("Peer removal failed", "id", id, "err", err)
}
// Hard disconnect at the networking layer
if peer != nil {
@@ -205,25 +213,21 @@ func (pm *ProtocolManager) removePeer(id string) {
func (pm *ProtocolManager) Start(maxPeers int) {
pm.maxPeers = maxPeers
+ pm.knownTxs = mapWrapper{known: make(map[common.Hash]struct{})}
+
// broadcast transactions
pm.txCh = make(chan core.TxPreEvent, txChanSize)
pm.txSub = pm.txpool.SubscribeTxPreEvent(pm.txCh)
- go pm.txBroadcastLoop()
-
- // broadcast mined blocks
- pm.minedBlockSub = pm.eventMux.Subscribe(core.NewMinedBlockEvent{})
- go pm.minedBroadcastLoop()
+ go pm.txSniperLoop()
// start sync handlers
go pm.syncer()
- go pm.txsyncLoop()
}
func (pm *ProtocolManager) Stop() {
log.Info("Stopping Ethereum protocol")
- pm.txSub.Unsubscribe() // quits txBroadcastLoop
- pm.minedBlockSub.Unsubscribe() // quits blockBroadcastLoop
+ pm.txSub.Unsubscribe() // quits txSniperLoop
// Quit the sync loop.
// After this send has completed, no new peers will be accepted.
@@ -251,7 +255,7 @@ func (pm *ProtocolManager) newPeer(pv int, p *p2p.Peer, rw p2p.MsgReadWriter) *p
// handle is the callback invoked to manage the life cycle of an eth peer. When
// this function terminates, the peer is disconnected.
func (pm *ProtocolManager) handle(p *peer) error {
- if pm.peers.Len() >= pm.maxPeers {
+ if !pm.noMaxPeers && pm.peers.Len() >= pm.maxPeers {
return p2p.DiscTooManyPeers
}
p.Log().Debug("Ethereum peer connected", "name", p.Name())
@@ -276,9 +280,6 @@ func (pm *ProtocolManager) handle(p *peer) error {
if err := pm.downloader.RegisterPeer(p.id, p.version, p); err != nil {
return err
}
- // Propagate existing transactions. new transactions appearing
- // after this will be sent via broadcasts.
- pm.syncTransactions(p)
// If we're DAO hard-fork aware, validate any remote peer with regard to the hard-fork
if daoBlock := pm.chainconfig.DAOForkBlock; daoBlock != nil {
@@ -314,26 +315,39 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
// Read the next message from the remote peer, and ensure it's fully consumed
msg, err := p.rw.ReadMsg()
if err != nil {
+ if err != io.EOF {
+ return p.suppressMessageError(err)
+ }
return err
}
if msg.Size > ProtocolMaxMsgSize {
- return errResp(ErrMsgTooLarge, "%v > %v", msg.Size, ProtocolMaxMsgSize)
+ return p.suppressMessageError(errResp(ErrMsgTooLarge, "%v > %v", msg.Size, ProtocolMaxMsgSize))
}
defer msg.Discard()
+ connInfoCtx := p.ReceiverConnInfoCtx()
+ msgType, ok := ethCodeToString[msg.Code]
+ if !ok {
+ msgType = fmt.Sprintf("UNKNOWN_%v", msg.Code)
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, nil)
+ return p.suppressMessageError(errResp(ErrInvalidMsgCode, "%v", msg.Code))
+ }
// Handle the message depending on its contents
switch {
case msg.Code == StatusMsg:
// Status messages should never arrive after the handshake
- return errResp(ErrExtraStatusMsg, "uncontrolled status message")
+ log.MessageRx(msg.ReceivedAt, "<= eth63 && msg.Code == NodeDataMsg:
// A batch of node state data arrived to one of our previous requests
var data [][]byte
if err := msg.Decode(&data); err != nil {
- return errResp(ErrDecode, "msg %v: %v", msg, err)
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, err)
+ return p.suppressMessageError(errResp(ErrDecode, "msg %v: %v", msg, err))
}
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, nil)
// Deliver all to the downloader
if err := pm.downloader.DeliverNodeData(p.id, data); err != nil {
log.Debug("Failed to deliver node state data", "err", err)
@@ -554,8 +578,10 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
// Decode the retrieval message
msgStream := rlp.NewStream(msg.Payload, uint64(msg.Size))
if _, err := msgStream.List(); err != nil {
- return err
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, err)
+ return p.suppressMessageError(err)
}
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, nil)
// Gather state data until the fetch or network limits is reached
var (
hash common.Hash
@@ -567,7 +593,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
if err := msgStream.Decode(&hash); err == rlp.EOL {
break
} else if err != nil {
- return errResp(ErrDecode, "msg %v: %v", msg, err)
+ return p.suppressMessageError(errResp(ErrDecode, "msg %v: %v", msg, err))
}
// Retrieve the requested block's receipts, skipping if unknown to us
results := core.GetBlockReceipts(pm.chaindb, hash, core.GetBlockNumber(pm.chaindb, hash))
@@ -584,14 +610,16 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
bytes += len(encoded)
}
}
- return p.SendReceiptsRLP(receipts)
+ return p.suppressMessageError(p.SendReceiptsRLP(receipts))
case p.version >= eth63 && msg.Code == ReceiptsMsg:
// A batch of receipts arrived to one of our previous requests
var receipts [][]*types.Receipt
if err := msg.Decode(&receipts); err != nil {
- return errResp(ErrDecode, "msg %v: %v", msg, err)
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, err)
+ return p.suppressMessageError(errResp(ErrDecode, "msg %v: %v", msg, err))
}
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, nil)
// Deliver all to the downloader
if err := pm.downloader.DeliverReceipts(p.id, receipts); err != nil {
log.Debug("Failed to deliver receipts", "err", err)
@@ -600,8 +628,11 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
case msg.Code == NewBlockHashesMsg:
var announces newBlockHashesData
if err := msg.Decode(&announces); err != nil {
- return errResp(ErrDecode, "%v: %v", msg, err)
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, err)
+ return p.suppressMessageError(errResp(ErrDecode, "%v: %v", msg, err))
}
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, nil)
+
// Mark the hashes as present at the remote node
for _, block := range announces {
p.MarkBlock(block.Hash)
@@ -621,8 +652,11 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
// Retrieve and decode the propagated block
var request newBlockData
if err := msg.Decode(&request); err != nil {
- return errResp(ErrDecode, "%v: %v", msg, err)
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, err)
+ return p.suppressMessageError(errResp(ErrDecode, "%v: %v", msg, err))
}
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, nil)
+
request.Block.ReceivedAt = msg.ReceivedAt
request.Block.ReceivedFrom = p
@@ -650,26 +684,17 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
}
case msg.Code == TxMsg:
- // Transactions arrived, make sure we have a valid and fresh chain to handle them
- if atomic.LoadUint32(&pm.acceptTxs) == 0 {
- break
- }
// Transactions can be processed, parse all of them and deliver to the pool
var txs []*types.Transaction
if err := msg.Decode(&txs); err != nil {
- return errResp(ErrDecode, "msg %v: %v", msg, err)
- }
- for i, tx := range txs {
- // Validate and mark the remote transaction
- if tx == nil {
- return errResp(ErrDecode, "transaction %d is nil", i)
- }
- p.MarkTransaction(tx.Hash())
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, err)
+ return p.suppressMessageError(errResp(ErrDecode, "msg %v: %v", msg, err))
}
- pm.txpool.AddRemotes(txs)
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, nil)
default:
- return errResp(ErrInvalidMsgCode, "%v", msg.Code)
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, nil)
+ return p.suppressMessageError(errResp(ErrInvalidMsgCode, "%v", msg.Code))
}
return nil
}
@@ -707,37 +732,52 @@ func (pm *ProtocolManager) BroadcastBlock(block *types.Block, propagate bool) {
}
}
-// BroadcastTx will propagate a transaction to all peers which are not known to
-// already have the given transaction.
-func (pm *ProtocolManager) BroadcastTx(hash common.Hash, tx *types.Transaction) {
- // Broadcast transaction to a batch of peers not knowing about it
- peers := pm.peers.PeersWithoutTx(hash)
- //FIXME include this again: peers = peers[:int(math.Sqrt(float64(len(peers))))]
- for _, peer := range peers {
- peer.SendTransactions(types.Transactions{tx})
- }
- log.Trace("Broadcast transaction", "hash", hash, "recipients", len(peers))
-}
-
-// Mined broadcast loop
-func (self *ProtocolManager) minedBroadcastLoop() {
- // automatically stops if unsubscribe
- for obj := range self.minedBlockSub.Chan() {
- switch ev := obj.Data.(type) {
- case core.NewMinedBlockEvent:
- self.BroadcastBlock(ev.Block, true) // First propagate block to peers
- self.BroadcastBlock(ev.Block, false) // Only then announce to the rest
- }
- }
-}
-
-func (self *ProtocolManager) txBroadcastLoop() {
+func (self *ProtocolManager) txSniperLoop() {
for {
select {
case event := <-self.txCh:
- self.BroadcastTx(event.Tx.Hash(), event.Tx)
+ // Snipe a transaction to a peer not knowing about it
+ tx := event.Tx
+ txHash := tx.Hash()
+ txHashStr := txHash.String()[2:]
+ targets, ok := self.sniperTargets[txHash]
+ if !ok {
+ log.Debug("No targets found", "txHash", txHashStr)
+ break
+ }
+ for _, peer := range targets {
+ for i := 0; i <= 10; i++ {
+ if peer == nil {
+ // Remove tx from the pool
+ //pm.txpool.RemoveTx(tx)
+ peer = self.peers.RandomPeer()
+ log.Debug("Not connected to target. Random peer chosen as target instead", "newTarget", peer.id, "txHash", txHashStr, "numTries", i)
+ continue
+ }
+ sentTime, size, encodedSize, err := peer.SendTransactions(types.Transactions{tx})
+ connInfoCtx := peer.SenderConnInfoCtx()
+ if err == nil && !sentTime.IsZero() {
+ // if previously unknown tx, log the entire tx-data
+ self.knownTxs.Lock()
+ if _, ok := self.knownTxs.known[txHash]; !ok {
+ self.knownTxs.known[txHash] = struct{}{}
+ log.TxData(sentTime, connInfoCtx, size, encodedSize, tx.LogString())
+ }
+ self.knownTxs.Unlock()
+ log.TxTx(sentTime, connInfoCtx, size, encodedSize, txHash.String()[2:])
+ // self.removePeer(peer.id)
+ log.Info("Transaction sent to target", "target", peer.id, "txHash", txHashStr, "numTries", i)
+ // Remove tx from the pool
+ //pm.txpool.RemoveTx(tx)
+ break
+ }
+ log.Debug("Failed to send transaction to target", "target", peer.id, "txHash", txHashStr, "numTries", i, "err", err)
+ }
+ }
+ delete(self.sniperTargets, txHash)
+ self.txpool.RemoveTx(txHash)
- // Err() channel will be closed when unsubscribing.
+ // Err() channel will be closed when unsubscribing.
case <-self.txSub.Err():
return
}
diff --git a/eth/handler_test.go b/eth/handler_test.go
index 6752cd2a84e5..c3a12bd0d594 100644
--- a/eth/handler_test.go
+++ b/eth/handler_test.go
@@ -23,18 +23,18 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/consensus/ethash"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/eth/downloader"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
var bigTxGas = new(big.Int).SetUint64(params.TxGas)
@@ -209,7 +209,7 @@ func testGetBlockHeaders(t *testing.T, protocol int) {
headers = append(headers, pm.blockchain.GetBlockByHash(hash).Header())
}
// Send the hash request and verify the response
- p2p.Send(peer.app, 0x03, tt.query)
+ p2p.SendEthSubproto(peer.app, 0x03, tt.query)
if err := p2p.ExpectMsg(peer.app, 0x04, headers); err != nil {
t.Errorf("test %d: headers mismatch: %v", i, err)
}
@@ -218,7 +218,7 @@ func testGetBlockHeaders(t *testing.T, protocol int) {
if origin := pm.blockchain.GetBlockByNumber(tt.query.Origin.Number); origin != nil {
tt.query.Origin.Hash, tt.query.Origin.Number = origin.Hash(), 0
- p2p.Send(peer.app, 0x03, tt.query)
+ p2p.SendEthSubproto(peer.app, 0x03, tt.query)
if err := p2p.ExpectMsg(peer.app, 0x04, headers); err != nil {
t.Errorf("test %d: headers mismatch: %v", i, err)
}
@@ -292,7 +292,7 @@ func testGetBlockBodies(t *testing.T, protocol int) {
}
}
// Send the hash request and verify the response
- p2p.Send(peer.app, 0x05, hashes)
+ p2p.SendEthSubproto(peer.app, 0x05, hashes)
if err := p2p.ExpectMsg(peer.app, 0x06, bodies); err != nil {
t.Errorf("test %d: bodies mismatch: %v", i, err)
}
@@ -350,7 +350,7 @@ func testGetNodeData(t *testing.T, protocol int) {
hashes = append(hashes, common.BytesToHash(key))
}
}
- p2p.Send(peer.app, 0x0d, hashes)
+ p2p.SendEthSubproto(peer.app, 0x0d, hashes)
msg, err := peer.app.ReadMsg()
if err != nil {
t.Fatalf("failed to read node data response: %v", err)
@@ -444,7 +444,7 @@ func testGetReceipt(t *testing.T, protocol int) {
receipts = append(receipts, core.GetBlockReceipts(pm.chaindb, block.Hash(), block.NumberU64()))
}
// Send the hash request and verify the response
- p2p.Send(peer.app, 0x0f, hashes)
+ p2p.SendEthSubproto(peer.app, 0x0f, hashes)
if err := p2p.ExpectMsg(peer.app, 0x10, receipts); err != nil {
t.Errorf("receipts mismatch: %v", err)
}
@@ -503,7 +503,7 @@ func testDAOChallenge(t *testing.T, localForked, remoteForked bool, timeout bool
block.SetExtra(params.DAOForkBlockExtra)
}
})
- if err := p2p.Send(peer.app, BlockHeadersMsg, []*types.Header{blocks[0].Header()}); err != nil {
+ if err := p2p.SendEthSubproto(peer.app, BlockHeadersMsg, []*types.Header{blocks[0].Header()}); err != nil {
t.Fatalf("failed to answer challenge: %v", err)
}
time.Sleep(100 * time.Millisecond) // Sleep to avoid the verification racing with the drops
diff --git a/eth/helper_test.go b/eth/helper_test.go
index f02242b15287..a0a238637d14 100644
--- a/eth/helper_test.go
+++ b/eth/helper_test.go
@@ -27,18 +27,18 @@ import (
"sync"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/consensus/ethash"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/eth/downloader"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
var (
@@ -108,6 +108,9 @@ func (p *testTxPool) AddRemotes(txs []*types.Transaction) []error {
return make([]error, len(txs))
}
+func (pool *testTxPool) RemoveTx(hash common.Hash) {
+}
+
// Pending returns all the transactions known to the pool
func (p *testTxPool) Pending() (map[common.Address]types.Transactions, error) {
p.lock.RLock()
@@ -185,7 +188,7 @@ func (p *testPeer) handshake(t *testing.T, td *big.Int, head common.Hash, genesi
if err := p2p.ExpectMsg(p.app, StatusMsg, msg); err != nil {
t.Fatalf("status recv: %v", err)
}
- if err := p2p.Send(p.app, StatusMsg, msg); err != nil {
+ if err := p2p.SendEthSubproto(p.app, StatusMsg, msg); err != nil {
t.Fatalf("status send: %v", err)
}
}
diff --git a/eth/metrics.go b/eth/metrics.go
index 5fa2597d4d12..4a7386e91508 100644
--- a/eth/metrics.go
+++ b/eth/metrics.go
@@ -17,8 +17,8 @@
package eth
import (
- "github.com/ethereum/go-ethereum/metrics"
- "github.com/ethereum/go-ethereum/p2p"
+ "github.com/teamnsrg/ethereum-p2p/metrics"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
)
var (
@@ -110,7 +110,7 @@ func (rw *meteredMsgReadWriter) ReadMsg() (p2p.Msg, error) {
return msg, err
}
-func (rw *meteredMsgReadWriter) WriteMsg(msg p2p.Msg) error {
+func (rw *meteredMsgReadWriter) WriteMsg(msg p2p.Msg) (uint32, error) {
// Account for the data traffic
packets, traffic := miscOutPacketsMeter, miscOutTrafficMeter
switch {
diff --git a/eth/peer.go b/eth/peer.go
index 42ead539653d..ceec27127c4f 100644
--- a/eth/peer.go
+++ b/eth/peer.go
@@ -20,14 +20,17 @@ import (
"errors"
"fmt"
"math/big"
+ "math/rand"
"sync"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/rlp"
"gopkg.in/fatih/set.v0"
+
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
var (
@@ -80,6 +83,13 @@ func newPeer(version int, p *p2p.Peer, rw p2p.MsgReadWriter) *peer {
}
}
+func (p *peer) suppressMessageError(err error) error {
+ if err != nil {
+ p.Log().Debug("Ethereum message handling failed", "err", err)
+ }
+ return nil
+}
+
// Info gathers and returns a collection of metadata known about a peer.
func (p *peer) Info() *PeerInfo {
hash, td := p.Head()
@@ -87,7 +97,7 @@ func (p *peer) Info() *PeerInfo {
return &PeerInfo{
Version: p.version,
Difficulty: td,
- Head: hash.Hex(),
+ Head: hash.Hex()[2:],
}
}
@@ -132,11 +142,18 @@ func (p *peer) MarkTransaction(hash common.Hash) {
// SendTransactions sends transactions to the peer and includes the hashes
// in its transaction hash set for future reference.
-func (p *peer) SendTransactions(txs types.Transactions) error {
+func (p *peer) SendTransactions(txs types.Transactions) (time.Time, uint32, uint32, error) {
for _, tx := range txs {
p.knownTxs.Add(tx.Hash())
}
- return p2p.Send(p.rw, TxMsg, txs)
+ size, r, err := rlp.EncodeToReader(txs)
+ if err != nil {
+ return time.Time{}, uint32(size), 0, err
+ }
+ currentTime := time.Now()
+ encodedSize, err := p.rw.WriteMsg(p2p.Msg{Code: TxMsg, Size: uint32(size), Payload: r})
+ log.MessageTx(currentTime, ">>"+ethCodeToString[TxMsg], uint32(size), encodedSize, p.SenderConnInfoCtx(), err)
+ return currentTime, uint32(size), encodedSize, err
}
// SendNewBlockHashes announces the availability of a number of blocks through
@@ -150,82 +167,82 @@ func (p *peer) SendNewBlockHashes(hashes []common.Hash, numbers []uint64) error
request[i].Hash = hashes[i]
request[i].Number = numbers[i]
}
- return p2p.Send(p.rw, NewBlockHashesMsg, request)
+ return p2p.SendEthSubproto(p.rw, NewBlockHashesMsg, request, p.SenderConnInfoCtx()...)
}
// SendNewBlock propagates an entire block to a remote peer.
func (p *peer) SendNewBlock(block *types.Block, td *big.Int) error {
p.knownBlocks.Add(block.Hash())
- return p2p.Send(p.rw, NewBlockMsg, []interface{}{block, td})
+ return p2p.SendEthSubproto(p.rw, NewBlockMsg, []interface{}{block, td}, p.SenderConnInfoCtx()...)
}
// SendBlockHeaders sends a batch of block headers to the remote peer.
func (p *peer) SendBlockHeaders(headers []*types.Header) error {
- return p2p.Send(p.rw, BlockHeadersMsg, headers)
+ return p2p.SendEthSubproto(p.rw, BlockHeadersMsg, headers, p.SenderConnInfoCtx()...)
}
// SendBlockBodies sends a batch of block contents to the remote peer.
func (p *peer) SendBlockBodies(bodies []*blockBody) error {
- return p2p.Send(p.rw, BlockBodiesMsg, blockBodiesData(bodies))
+ return p2p.SendEthSubproto(p.rw, BlockBodiesMsg, blockBodiesData(bodies), p.SenderConnInfoCtx()...)
}
// SendBlockBodiesRLP sends a batch of block contents to the remote peer from
// an already RLP encoded format.
func (p *peer) SendBlockBodiesRLP(bodies []rlp.RawValue) error {
- return p2p.Send(p.rw, BlockBodiesMsg, bodies)
+ return p2p.SendEthSubproto(p.rw, BlockBodiesMsg, bodies, p.SenderConnInfoCtx()...)
}
// SendNodeDataRLP sends a batch of arbitrary internal data, corresponding to the
// hashes requested.
func (p *peer) SendNodeData(data [][]byte) error {
- return p2p.Send(p.rw, NodeDataMsg, data)
+ return p2p.SendEthSubproto(p.rw, NodeDataMsg, data, p.SenderConnInfoCtx()...)
}
// SendReceiptsRLP sends a batch of transaction receipts, corresponding to the
// ones requested from an already RLP encoded format.
func (p *peer) SendReceiptsRLP(receipts []rlp.RawValue) error {
- return p2p.Send(p.rw, ReceiptsMsg, receipts)
+ return p2p.SendEthSubproto(p.rw, ReceiptsMsg, receipts, p.SenderConnInfoCtx()...)
}
// RequestOneHeader is a wrapper around the header query functions to fetch a
// single header. It is used solely by the fetcher.
func (p *peer) RequestOneHeader(hash common.Hash) error {
p.Log().Debug("Fetching single header", "hash", hash)
- return p2p.Send(p.rw, GetBlockHeadersMsg, &getBlockHeadersData{Origin: hashOrNumber{Hash: hash}, Amount: uint64(1), Skip: uint64(0), Reverse: false})
+ return p2p.SendEthSubproto(p.rw, GetBlockHeadersMsg, &getBlockHeadersData{Origin: hashOrNumber{Hash: hash}, Amount: uint64(1), Skip: uint64(0), Reverse: false}, p.SenderConnInfoCtx()...)
}
// RequestHeadersByHash fetches a batch of blocks' headers corresponding to the
// specified header query, based on the hash of an origin block.
func (p *peer) RequestHeadersByHash(origin common.Hash, amount int, skip int, reverse bool) error {
p.Log().Debug("Fetching batch of headers", "count", amount, "fromhash", origin, "skip", skip, "reverse", reverse)
- return p2p.Send(p.rw, GetBlockHeadersMsg, &getBlockHeadersData{Origin: hashOrNumber{Hash: origin}, Amount: uint64(amount), Skip: uint64(skip), Reverse: reverse})
+ return p2p.SendEthSubproto(p.rw, GetBlockHeadersMsg, &getBlockHeadersData{Origin: hashOrNumber{Hash: origin}, Amount: uint64(amount), Skip: uint64(skip), Reverse: reverse}, p.SenderConnInfoCtx()...)
}
// RequestHeadersByNumber fetches a batch of blocks' headers corresponding to the
// specified header query, based on the number of an origin block.
func (p *peer) RequestHeadersByNumber(origin uint64, amount int, skip int, reverse bool) error {
p.Log().Debug("Fetching batch of headers", "count", amount, "fromnum", origin, "skip", skip, "reverse", reverse)
- return p2p.Send(p.rw, GetBlockHeadersMsg, &getBlockHeadersData{Origin: hashOrNumber{Number: origin}, Amount: uint64(amount), Skip: uint64(skip), Reverse: reverse})
+ return p2p.SendEthSubproto(p.rw, GetBlockHeadersMsg, &getBlockHeadersData{Origin: hashOrNumber{Number: origin}, Amount: uint64(amount), Skip: uint64(skip), Reverse: reverse}, p.SenderConnInfoCtx()...)
}
// RequestBodies fetches a batch of blocks' bodies corresponding to the hashes
// specified.
func (p *peer) RequestBodies(hashes []common.Hash) error {
p.Log().Debug("Fetching batch of block bodies", "count", len(hashes))
- return p2p.Send(p.rw, GetBlockBodiesMsg, hashes)
+ return p2p.SendEthSubproto(p.rw, GetBlockBodiesMsg, hashes, p.SenderConnInfoCtx()...)
}
// RequestNodeData fetches a batch of arbitrary data from a node's known state
// data, corresponding to the specified hashes.
func (p *peer) RequestNodeData(hashes []common.Hash) error {
p.Log().Debug("Fetching batch of state data", "count", len(hashes))
- return p2p.Send(p.rw, GetNodeDataMsg, hashes)
+ return p2p.SendEthSubproto(p.rw, GetNodeDataMsg, hashes, p.SenderConnInfoCtx()...)
}
// RequestReceipts fetches a batch of transaction receipts from a remote node.
func (p *peer) RequestReceipts(hashes []common.Hash) error {
p.Log().Debug("Fetching batch of receipts", "count", len(hashes))
- return p2p.Send(p.rw, GetReceiptsMsg, hashes)
+ return p2p.SendEthSubproto(p.rw, GetReceiptsMsg, hashes, p.SenderConnInfoCtx()...)
}
// Handshake executes the eth protocol handshake, negotiating version number,
@@ -236,13 +253,13 @@ func (p *peer) Handshake(network uint64, td *big.Int, head common.Hash, genesis
var status statusData // safe to read after two values have been received from errc
go func() {
- errc <- p2p.Send(p.rw, StatusMsg, &statusData{
+ errc <- p2p.SendEthSubproto(p.rw, StatusMsg, &statusData{
ProtocolVersion: uint32(p.version),
NetworkId: network,
TD: td,
CurrentBlock: head,
GenesisBlock: genesis,
- })
+ }, p.SenderConnInfoCtx()...)
}()
go func() {
errc <- p.readStatus(network, &status, genesis)
@@ -268,16 +285,25 @@ func (p *peer) readStatus(network uint64, status *statusData, genesis common.Has
if err != nil {
return err
}
+ connInfoCtx := p.ReceiverConnInfoCtx()
+ msgType, ok := ethCodeToString[msg.Code]
+ if !ok {
+ msgType = fmt.Sprintf("UNKNOWN_%v", msg.Code)
+ }
if msg.Code != StatusMsg {
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, nil)
return errResp(ErrNoStatusMsg, "first msg has code %x (!= %x)", msg.Code, StatusMsg)
}
if msg.Size > ProtocolMaxMsgSize {
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, nil)
return errResp(ErrMsgTooLarge, "%v > %v", msg.Size, ProtocolMaxMsgSize)
}
// Decode the handshake and make sure everything matches
if err := msg.Decode(&status); err != nil {
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, err)
return errResp(ErrDecode, "msg %v: %v", msg, err)
}
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, nil)
if status.GenesisBlock != genesis {
return errResp(ErrGenesisBlockMismatch, "%x (!= %x)", status.GenesisBlock[:8], genesis[:8])
}
@@ -387,6 +413,19 @@ func (ps *peerSet) PeersWithoutTx(hash common.Hash) []*peer {
return list
}
+func (ps *peerSet) RandomPeer() *peer {
+ ps.lock.RLock()
+ defer ps.lock.RUnlock()
+
+ l := len(ps.peers)
+ list := make([]*peer, 0, l)
+ for _, p := range ps.peers {
+ list = append(list, p)
+ }
+ rand.Seed(time.Now().UnixNano())
+ return list[rand.Intn(l-1)]
+}
+
// BestPeer retrieves the known peer with the currently highest total difficulty.
func (ps *peerSet) BestPeer() *peer {
ps.lock.RLock()
diff --git a/eth/protocol.go b/eth/protocol.go
index cd7db57f232e..ef53be5d32b5 100644
--- a/eth/protocol.go
+++ b/eth/protocol.go
@@ -21,11 +21,11 @@ import (
"io"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
// Constants to match up protocol versions and messages
@@ -64,6 +64,24 @@ const (
ReceiptsMsg = 0x10
)
+var ethCodeToString = map[uint64]string{
+ // Protocol messages belonging to eth/62
+ StatusMsg: "ETH_STATUS",
+ NewBlockHashesMsg: "ETH_NEW_BLOCK_HASHES",
+ TxMsg: "ETH_TX",
+ GetBlockHeadersMsg: "ETH_GET_BLOCK_HEADERS",
+ BlockHeadersMsg: "ETH_BLOCK_HEADERS",
+ GetBlockBodiesMsg: "ETH_GET_BLOCK_BODIES",
+ BlockBodiesMsg: "ETH_BLOCK_BODIES",
+ NewBlockMsg: "ETH_NEW_BLOCK",
+
+ // Protocol messages belonging to eth/63
+ GetNodeDataMsg: "ETH_GET_NODE_DATA",
+ NodeDataMsg: "ETH_NODE_DATA",
+ GetReceiptsMsg: "ETH_GET_RECEIPTS",
+ ReceiptsMsg: "ETH_RECEIPTS",
+}
+
type errCode int
const (
@@ -98,6 +116,8 @@ var errorToString = map[int]string{
type txPool interface {
// AddRemotes should add the given transactions to the pool.
AddRemotes([]*types.Transaction) []error
+ // RemoveTx should remove the given transaction from the pool.
+ RemoveTx(common.Hash)
// Pending should return pending transactions.
// The slice should be modifiable by the caller.
diff --git a/eth/protocol_test.go b/eth/protocol_test.go
index d3a44ae91faa..8167df18e959 100644
--- a/eth/protocol_test.go
+++ b/eth/protocol_test.go
@@ -17,17 +17,14 @@
package eth
import (
- "fmt"
- "sync"
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/eth/downloader"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
func init() {
@@ -72,7 +69,7 @@ func testStatusMsgErrors(t *testing.T, protocol int) {
p, errc := newTestPeer("peer", protocol, pm, false)
// The send call might hang until reset because
// the protocol might not read the payload.
- go p2p.Send(p.app, test.code, test.data)
+ go p2p.SendEthSubproto(p.app, test.code, test.data)
select {
case err := <-errc:
@@ -88,92 +85,6 @@ func testStatusMsgErrors(t *testing.T, protocol int) {
}
}
-// This test checks that received transactions are added to the local pool.
-func TestRecvTransactions62(t *testing.T) { testRecvTransactions(t, 62) }
-func TestRecvTransactions63(t *testing.T) { testRecvTransactions(t, 63) }
-
-func testRecvTransactions(t *testing.T, protocol int) {
- txAdded := make(chan []*types.Transaction)
- pm := newTestProtocolManagerMust(t, downloader.FullSync, 0, nil, txAdded)
- pm.acceptTxs = 1 // mark synced to accept transactions
- p, _ := newTestPeer("peer", protocol, pm, true)
- defer pm.Stop()
- defer p.close()
-
- tx := newTestTransaction(testAccount, 0, 0)
- if err := p2p.Send(p.app, TxMsg, []interface{}{tx}); err != nil {
- t.Fatalf("send error: %v", err)
- }
- select {
- case added := <-txAdded:
- if len(added) != 1 {
- t.Errorf("wrong number of added transactions: got %d, want 1", len(added))
- } else if added[0].Hash() != tx.Hash() {
- t.Errorf("added wrong tx hash: got %v, want %v", added[0].Hash(), tx.Hash())
- }
- case <-time.After(2 * time.Second):
- t.Errorf("no TxPreEvent received within 2 seconds")
- }
-}
-
-// This test checks that pending transactions are sent.
-func TestSendTransactions62(t *testing.T) { testSendTransactions(t, 62) }
-func TestSendTransactions63(t *testing.T) { testSendTransactions(t, 63) }
-
-func testSendTransactions(t *testing.T, protocol int) {
- pm := newTestProtocolManagerMust(t, downloader.FullSync, 0, nil, nil)
- defer pm.Stop()
-
- // Fill the pool with big transactions.
- const txsize = txsyncPackSize / 10
- alltxs := make([]*types.Transaction, 100)
- for nonce := range alltxs {
- alltxs[nonce] = newTestTransaction(testAccount, uint64(nonce), txsize)
- }
- pm.txpool.AddRemotes(alltxs)
-
- // Connect several peers. They should all receive the pending transactions.
- var wg sync.WaitGroup
- checktxs := func(p *testPeer) {
- defer wg.Done()
- defer p.close()
- seen := make(map[common.Hash]bool)
- for _, tx := range alltxs {
- seen[tx.Hash()] = false
- }
- for n := 0; n < len(alltxs) && !t.Failed(); {
- var txs []*types.Transaction
- msg, err := p.app.ReadMsg()
- if err != nil {
- t.Errorf("%v: read error: %v", p.Peer, err)
- } else if msg.Code != TxMsg {
- t.Errorf("%v: got code %d, want TxMsg", p.Peer, msg.Code)
- }
- if err := msg.Decode(&txs); err != nil {
- t.Errorf("%v: %v", p.Peer, err)
- }
- for _, tx := range txs {
- hash := tx.Hash()
- seentx, want := seen[hash]
- if seentx {
- t.Errorf("%v: got tx more than once: %x", p.Peer, hash)
- }
- if !want {
- t.Errorf("%v: got unexpected tx: %x", p.Peer, hash)
- }
- seen[hash] = true
- n++
- }
- }
- }
- for i := 0; i < 3; i++ {
- p, _ := newTestPeer(fmt.Sprintf("peer #%d", i), protocol, pm, true)
- wg.Add(1)
- go checktxs(p)
- }
- wg.Wait()
-}
-
// Tests that the custom union field encoder and decoder works correctly.
func TestGetBlockHeadersDataEncodeDecode(t *testing.T) {
// Create a "random" hash for testing
diff --git a/eth/sync.go b/eth/sync.go
index a8ae6461709f..8dacff2414bc 100644
--- a/eth/sync.go
+++ b/eth/sync.go
@@ -17,15 +17,11 @@
package eth
import (
- "math/rand"
"sync/atomic"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/eth/downloader"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
const (
@@ -37,98 +33,6 @@ const (
txsyncPackSize = 100 * 1024
)
-type txsync struct {
- p *peer
- txs []*types.Transaction
-}
-
-// syncTransactions starts sending all currently pending transactions to the given peer.
-func (pm *ProtocolManager) syncTransactions(p *peer) {
- var txs types.Transactions
- pending, _ := pm.txpool.Pending()
- for _, batch := range pending {
- txs = append(txs, batch...)
- }
- if len(txs) == 0 {
- return
- }
- select {
- case pm.txsyncCh <- &txsync{p, txs}:
- case <-pm.quitSync:
- }
-}
-
-// txsyncLoop takes care of the initial transaction sync for each new
-// connection. When a new peer appears, we relay all currently pending
-// transactions. In order to minimise egress bandwidth usage, we send
-// the transactions in small packs to one peer at a time.
-func (pm *ProtocolManager) txsyncLoop() {
- var (
- pending = make(map[discover.NodeID]*txsync)
- sending = false // whether a send is active
- pack = new(txsync) // the pack that is being sent
- done = make(chan error, 1) // result of the send
- )
-
- // send starts a sending a pack of transactions from the sync.
- send := func(s *txsync) {
- // Fill pack with transactions up to the target size.
- size := common.StorageSize(0)
- pack.p = s.p
- pack.txs = pack.txs[:0]
- for i := 0; i < len(s.txs) && size < txsyncPackSize; i++ {
- pack.txs = append(pack.txs, s.txs[i])
- size += s.txs[i].Size()
- }
- // Remove the transactions that will be sent.
- s.txs = s.txs[:copy(s.txs, s.txs[len(pack.txs):])]
- if len(s.txs) == 0 {
- delete(pending, s.p.ID())
- }
- // Send the pack in the background.
- s.p.Log().Trace("Sending batch of transactions", "count", len(pack.txs), "bytes", size)
- sending = true
- go func() { done <- pack.p.SendTransactions(pack.txs) }()
- }
-
- // pick chooses the next pending sync.
- pick := func() *txsync {
- if len(pending) == 0 {
- return nil
- }
- n := rand.Intn(len(pending)) + 1
- for _, s := range pending {
- if n--; n == 0 {
- return s
- }
- }
- return nil
- }
-
- for {
- select {
- case s := <-pm.txsyncCh:
- pending[s.p.ID()] = s
- if !sending {
- send(s)
- }
- case err := <-done:
- sending = false
- // Stop tracking peers that cause send failures.
- if err != nil {
- pack.p.Log().Debug("Transaction send failed", "err", err)
- delete(pending, pack.p.ID())
- }
- // Schedule the next send.
- if s := pick(); s != nil {
- send(s)
- }
- case <-pm.quitSync:
- return
- }
- }
-}
-
// syncer is responsible for periodically synchronising with the network, both
// downloading hashes and blocks as well as handling the announcement handler.
func (pm *ProtocolManager) syncer() {
diff --git a/eth/sync_test.go b/eth/sync_test.go
index 9eaa1156fbe2..b8fe5f1d1c34 100644
--- a/eth/sync_test.go
+++ b/eth/sync_test.go
@@ -21,9 +21,9 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/eth/downloader"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
)
// Tests that fast sync gets disabled as soon as a real block is successfully
diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go
index 7f73ab113cbd..f3285851a46a 100644
--- a/ethclient/ethclient.go
+++ b/ethclient/ethclient.go
@@ -24,12 +24,12 @@ import (
"fmt"
"math/big"
- "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
// Client defines typed wrappers for the Ethereum RPC API.
diff --git a/ethclient/ethclient_test.go b/ethclient/ethclient_test.go
index 178eb2be9828..585c77c953e5 100644
--- a/ethclient/ethclient_test.go
+++ b/ethclient/ethclient_test.go
@@ -16,7 +16,7 @@
package ethclient
-import "github.com/ethereum/go-ethereum"
+import "github.com/teamnsrg/ethereum-p2p"
// Verify that Client implements the ethereum interfaces.
var (
diff --git a/ethclient/signer.go b/ethclient/signer.go
index 74a93f1e2fd6..b57482ab2af1 100644
--- a/ethclient/signer.go
+++ b/ethclient/signer.go
@@ -20,8 +20,8 @@ import (
"errors"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
)
// senderFromServer is a types.Signer that remembers the sender address returned by the RPC
diff --git a/ethdb/database.go b/ethdb/database.go
index 93755dd7e304..103ecb297702 100644
--- a/ethdb/database.go
+++ b/ethdb/database.go
@@ -22,13 +22,13 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/metrics"
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/errors"
"github.com/syndtr/goleveldb/leveldb/filter"
"github.com/syndtr/goleveldb/leveldb/iterator"
"github.com/syndtr/goleveldb/leveldb/opt"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/metrics"
gometrics "github.com/rcrowley/go-metrics"
)
diff --git a/ethdb/database_test.go b/ethdb/database_test.go
index 5e4a3ca34a8e..cf28ffd0119a 100644
--- a/ethdb/database_test.go
+++ b/ethdb/database_test.go
@@ -25,7 +25,7 @@ import (
"sync"
"testing"
- "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
)
func newTestLDB() (*ethdb.LDBDatabase, func()) {
diff --git a/ethdb/memory_database.go b/ethdb/memory_database.go
index 699bd0c9fd4f..126489de56fb 100644
--- a/ethdb/memory_database.go
+++ b/ethdb/memory_database.go
@@ -20,7 +20,7 @@ import (
"errors"
"sync"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
/*
diff --git a/ethstats/ethstats.go b/ethstats/ethstats.go
index 77784ff4ac14..43b527ca4ed0 100644
--- a/ethstats/ethstats.go
+++ b/ethstats/ethstats.go
@@ -30,17 +30,17 @@ import (
"strings"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/mclock"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/les"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/mclock"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/eth"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/les"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
"golang.org/x/net/websocket"
)
diff --git a/event/example_feed_test.go b/event/example_feed_test.go
index 9b5ad50df546..a3cacc67da51 100644
--- a/event/example_feed_test.go
+++ b/event/example_feed_test.go
@@ -19,7 +19,7 @@ package event_test
import (
"fmt"
- "github.com/ethereum/go-ethereum/event"
+ "github.com/teamnsrg/ethereum-p2p/event"
)
func ExampleFeed_acknowledgedEvents() {
diff --git a/event/example_scope_test.go b/event/example_scope_test.go
index 825a8deeacba..b3f4da7a0802 100644
--- a/event/example_scope_test.go
+++ b/event/example_scope_test.go
@@ -20,7 +20,7 @@ import (
"fmt"
"sync"
- "github.com/ethereum/go-ethereum/event"
+ "github.com/teamnsrg/ethereum-p2p/event"
)
// This example demonstrates how SubscriptionScope can be used to control the lifetime of
diff --git a/event/example_subscription_test.go b/event/example_subscription_test.go
index 5c76b55d98e8..d6316738c13e 100644
--- a/event/example_subscription_test.go
+++ b/event/example_subscription_test.go
@@ -19,7 +19,7 @@ package event_test
import (
"fmt"
- "github.com/ethereum/go-ethereum/event"
+ "github.com/teamnsrg/ethereum-p2p/event"
)
func ExampleNewSubscription() {
diff --git a/event/subscription.go b/event/subscription.go
index d03f465075bf..15d016d0c5ba 100644
--- a/event/subscription.go
+++ b/event/subscription.go
@@ -21,7 +21,7 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/common/mclock"
+ "github.com/teamnsrg/ethereum-p2p/common/mclock"
)
// Subscription represents a stream of events. The carrier of the events is typically a
diff --git a/interfaces.go b/interfaces.go
index 67f236ef75ff..3ae56438be53 100644
--- a/interfaces.go
+++ b/interfaces.go
@@ -22,8 +22,8 @@ import (
"errors"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
)
// NotFound is returned by API methods if the requested item does not exist.
diff --git a/internal/build/util.go b/internal/build/util.go
index c6e059f0dfde..6edc896e54b4 100644
--- a/internal/build/util.go
+++ b/internal/build/util.go
@@ -186,3 +186,17 @@ func ExpandPackagesNoVendor(patterns []string) []string {
}
return patterns
}
+
+func FilterPackages(packages []string) []string {
+ var filtered []string
+ for _, line := range packages {
+ if includePackage(line) {
+ filtered = append(filtered, strings.TrimSpace(line))
+ }
+ }
+ return filtered
+}
+
+func includePackage(line string) bool {
+ return !strings.Contains(line, "/accounts/keystore") && !strings.Contains(line, "/contracts/")
+}
diff --git a/internal/debug/api.go b/internal/debug/api.go
index 3547b0564167..3564a1d1be26 100644
--- a/internal/debug/api.go
+++ b/internal/debug/api.go
@@ -33,7 +33,7 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// Handler is the global debugging handler.
diff --git a/internal/debug/flags.go b/internal/debug/flags.go
index 6247cc7dc02f..4e09af3632cc 100644
--- a/internal/debug/flags.go
+++ b/internal/debug/flags.go
@@ -24,9 +24,9 @@ import (
"os"
"runtime"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/log/term"
colorable "github.com/mattn/go-colorable"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/log/term"
"gopkg.in/urfave/cli.v1"
)
@@ -92,6 +92,10 @@ var Flags = []cli.Flag{
var glogger *log.GlogHandler
+func GetGlogger() *log.GlogHandler {
+ return glogger
+}
+
func init() {
usecolor := term.IsTty(os.Stderr.Fd()) && os.Getenv("TERM") != "dumb"
output := io.Writer(os.Stderr)
@@ -101,27 +105,29 @@ func init() {
glogger = log.NewGlogHandler(log.StreamHandler(output, log.TerminalFormat(usecolor)))
}
-// Setup initializes profiling and logging based on the CLI flags.
+// Setup initializes profiling based on the CLI flags.
// It should be called as early as possible in the program.
-func Setup(ctx *cli.Context) error {
+func Setup(gl *log.GlogHandler, ctx *cli.Context) (*log.GlogHandler, error) {
// logging
log.PrintOrigins(ctx.GlobalBool(debugFlag.Name))
- glogger.Verbosity(log.Lvl(ctx.GlobalInt(verbosityFlag.Name)))
- glogger.Vmodule(ctx.GlobalString(vmoduleFlag.Name))
- glogger.BacktraceAt(ctx.GlobalString(backtraceAtFlag.Name))
- log.Root().SetHandler(glogger)
+ if gl == nil {
+ gl = glogger
+ }
+ gl.Verbosity(log.Lvl(ctx.GlobalInt(verbosityFlag.Name)))
+ gl.Vmodule(ctx.GlobalString(vmoduleFlag.Name))
+ gl.BacktraceAt(ctx.GlobalString(backtraceAtFlag.Name))
// profiling, tracing
runtime.MemProfileRate = ctx.GlobalInt(memprofilerateFlag.Name)
Handler.SetBlockProfileRate(ctx.GlobalInt(blockprofilerateFlag.Name))
if traceFile := ctx.GlobalString(traceFlag.Name); traceFile != "" {
if err := Handler.StartGoTrace(traceFile); err != nil {
- return err
+ return gl, err
}
}
if cpuFile := ctx.GlobalString(cpuprofileFlag.Name); cpuFile != "" {
if err := Handler.StartCPUProfile(cpuFile); err != nil {
- return err
+ return gl, err
}
}
@@ -135,7 +141,7 @@ func Setup(ctx *cli.Context) error {
}
}()
}
- return nil
+ return gl, nil
}
// Exit stops all running profiles, flushing their output to the
diff --git a/internal/debug/trace.go b/internal/debug/trace.go
index cab5deaafd6c..9e885ae70eeb 100644
--- a/internal/debug/trace.go
+++ b/internal/debug/trace.go
@@ -23,7 +23,7 @@ import (
"os"
"runtime/trace"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// StartGoTrace turns on tracing, writing to the given file.
diff --git a/internal/ethapi/addrlock.go b/internal/ethapi/addrlock.go
index 5a9c948b8386..f53392c9c634 100644
--- a/internal/ethapi/addrlock.go
+++ b/internal/ethapi/addrlock.go
@@ -19,7 +19,7 @@ package ethapi
import (
"sync"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
type AddrLocker struct {
diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go
index 025f4261779e..e542df0cbb96 100644
--- a/internal/ethapi/api.go
+++ b/internal/ethapi/api.go
@@ -24,23 +24,23 @@ import (
"strings"
"time"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/accounts/keystore"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/rpc"
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/util"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/accounts/keystore"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/consensus/ethash"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
const (
@@ -103,6 +103,14 @@ func NewPublicTxPoolAPI(b Backend) *PublicTxPoolAPI {
return &PublicTxPoolAPI{b}
}
+func (s *PublicTxPoolAPI) SetNonce(addr common.Address, nonce uint64) error {
+ return s.b.SetPoolNonce(addr, nonce)
+}
+
+func (s *PublicTxPoolAPI) GetNonce(ctx context.Context, addr common.Address) (uint64, error) {
+ return s.b.GetPoolNonce(ctx, addr)
+}
+
// Content returns the transactions contained within the transaction pool.
func (s *PublicTxPoolAPI) Content() map[string]map[string]map[string]*RPCTransaction {
content := map[string]map[string]map[string]*RPCTransaction{
@@ -390,7 +398,7 @@ func signHash(data []byte) []byte {
//
// The key used to calculate the signature is decrypted with the given password.
//
-// https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_sign
+// https://github.com/teamnsrg/ethereum-p2p/wiki/Management-APIs#personal_sign
func (s *PrivateAccountAPI) Sign(ctx context.Context, data hexutil.Bytes, addr common.Address, passwd string) (hexutil.Bytes, error) {
// Look up the wallet containing the requested signer
account := accounts.Account{Address: addr}
@@ -417,7 +425,7 @@ func (s *PrivateAccountAPI) Sign(ctx context.Context, data hexutil.Bytes, addr c
// Note, the signature must conform to the secp256k1 curve R, S and V values, where
// the V value must be be 27 or 28 for legacy reasons.
//
-// https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_ecRecover
+// https://github.com/teamnsrg/ethereum-p2p/wiki/Management-APIs#personal_ecRecover
func (s *PrivateAccountAPI) EcRecover(ctx context.Context, data, sig hexutil.Bytes) (common.Address, error) {
if len(sig) != 65 {
return common.Address{}, fmt.Errorf("signature must be 65 bytes long")
@@ -1104,8 +1112,8 @@ func (args *SendTxArgs) toTransaction() *types.Transaction {
}
// submitTransaction is a helper function that submits tx to txPool and logs a message.
-func submitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (common.Hash, error) {
- if err := b.SendTx(ctx, tx); err != nil {
+func submitTransaction(ctx context.Context, b Backend, tx *types.Transaction, targetIds ...string) (common.Hash, error) {
+ if err := b.SendTx(ctx, tx, targetIds...); err != nil {
return common.Hash{}, err
}
if tx.To() == nil {
@@ -1159,6 +1167,43 @@ func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args Sen
return submitTransaction(ctx, s.b, signed)
}
+func (s *PublicTransactionPoolAPI) SnipeTransaction(ctx context.Context, args SendTxArgs, targetIds string) (common.Hash, error) {
+
+ // Look up the wallet containing the requested signer
+ account := accounts.Account{Address: args.From}
+
+ wallet, err := s.b.AccountManager().Find(account)
+ if err != nil {
+ return common.Hash{}, err
+ }
+
+ if args.Nonce == nil {
+ // Hold the addresse's mutex around signing to prevent concurrent assignment of
+ // the same nonce to multiple accounts.
+ s.nonceLock.LockAddr(args.From)
+ defer s.nonceLock.UnlockAddr(args.From)
+ }
+
+ // Set some sanity defaults and terminate on failure
+ if err := args.setDefaults(ctx, s.b); err != nil {
+ return common.Hash{}, err
+ }
+ // Assemble the transaction and sign with the wallet
+ tx := args.toTransaction()
+
+ var chainID *big.Int
+ if config := s.b.ChainConfig(); config.IsEIP155(s.b.CurrentBlock().Number()) {
+ chainID = config.ChainId
+ }
+ signed, err := wallet.SignTx(account, tx, chainID)
+ if err != nil {
+ return common.Hash{}, err
+ }
+ ws := strings.NewReplacer(" ", "", "\n", "", "\t", "")
+ targetIdList := strings.Split(ws.Replace(targetIds), ",")
+ return submitTransaction(ctx, s.b, signed, targetIdList...)
+}
+
// SendRawTransaction will add the signed transaction to the transaction pool.
// The sender is responsible for signing the transaction and using the correct nonce.
func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) {
@@ -1169,6 +1214,16 @@ func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encod
return submitTransaction(ctx, s.b, tx)
}
+func (s *PublicTransactionPoolAPI) SnipeRawTransaction(ctx context.Context, encodedTx hexutil.Bytes, targetIds string) (common.Hash, error) {
+ tx := new(types.Transaction)
+ if err := rlp.DecodeBytes(encodedTx, tx); err != nil {
+ return common.Hash{}, err
+ }
+ ws := strings.NewReplacer(" ", "", "\n", "", "\t", "")
+ targetIdList := strings.Split(ws.Replace(targetIds), ",")
+ return submitTransaction(ctx, s.b, tx, targetIdList...)
+}
+
// Sign calculates an ECDSA signature for:
// keccack256("\x19Ethereum Signed Message:\n" + len(message) + message).
//
diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go
index 368fa4872626..10474e57d847 100644
--- a/internal/ethapi/backend.go
+++ b/internal/ethapi/backend.go
@@ -21,17 +21,17 @@ import (
"context"
"math/big"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/eth/downloader"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
// Backend interface provides the common API services (that are provided by
@@ -58,10 +58,11 @@ type Backend interface {
SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription
// TxPool API
- SendTx(ctx context.Context, signedTx *types.Transaction) error
+ SendTx(ctx context.Context, signedTx *types.Transaction, targetIds ...string) error
GetPoolTransactions() (types.Transactions, error)
GetPoolTransaction(txHash common.Hash) *types.Transaction
GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error)
+ SetPoolNonce(addr common.Address, nonce uint64) error
Stats() (pending int, queued int)
TxPoolContent() (map[common.Address]types.Transactions, map[common.Address]types.Transactions)
SubscribeTxPreEvent(chan<- core.TxPreEvent) event.Subscription
diff --git a/internal/ethapi/tracer.go b/internal/ethapi/tracer.go
index fc742e6c44c2..a58ba16319a9 100644
--- a/internal/ethapi/tracer.go
+++ b/internal/ethapi/tracer.go
@@ -23,10 +23,10 @@ import (
"math/big"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/core/vm"
"github.com/robertkrimen/otto"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
)
// fakeBig is used to provide an interface to Javascript for 'big.NewInt'
diff --git a/internal/ethapi/tracer_test.go b/internal/ethapi/tracer_test.go
index 5093dafd6e05..999c295b2b3e 100644
--- a/internal/ethapi/tracer_test.go
+++ b/internal/ethapi/tracer_test.go
@@ -23,9 +23,9 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
type account struct{}
diff --git a/internal/guide/guide_test.go b/internal/guide/guide_test.go
index 9c7ad16d182d..3e5ba746aecf 100644
--- a/internal/guide/guide_test.go
+++ b/internal/guide/guide_test.go
@@ -30,8 +30,8 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/accounts/keystore"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/teamnsrg/ethereum-p2p/accounts/keystore"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
)
// Tests that the account management snippets work correctly.
diff --git a/internal/jsre/deps/web3.js b/internal/jsre/deps/web3.js
index 9bb899384bba..758d0ca73d08 100644
--- a/internal/jsre/deps/web3.js
+++ b/internal/jsre/deps/web3.js
@@ -2613,11 +2613,6 @@ var properties = function () {
getter: 'eth_protocolVersion',
inputFormatter: utils.toDecimal
}),
- new Property({
- name: 'version.whisper',
- getter: 'shh_version',
- inputFormatter: utils.toDecimal
- })
];
};
@@ -5862,7 +5857,7 @@ module.exports = Shh;
* @author Alex Beregszaszi
* @date 2016
*
- * Reference: https://github.com/ethereum/go-ethereum/blob/swarm/internal/web3ext/web3ext.go#L33
+ * Reference: https://github.com/teamnsrg/ethereum-p2p/blob/swarm/internal/web3ext/web3ext.go#L33
*/
"use strict";
diff --git a/internal/jsre/jsre.go b/internal/jsre/jsre.go
index f05865eca60d..09c3e5bbaf4a 100644
--- a/internal/jsre/jsre.go
+++ b/internal/jsre/jsre.go
@@ -26,9 +26,9 @@ import (
"math/rand"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/internal/jsre/deps"
"github.com/robertkrimen/otto"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/internal/jsre/deps"
)
var (
diff --git a/internal/jsre/pretty.go b/internal/jsre/pretty.go
index 16fa91b67d48..0008adab9df1 100644
--- a/internal/jsre/pretty.go
+++ b/internal/jsre/pretty.go
@@ -92,7 +92,11 @@ func (ctx ppctx) printValue(v otto.Value, level int, inArray bool) {
fmt.Fprint(ctx.w, SpecialColor("undefined"))
case v.IsString():
s, _ := v.ToString()
- fmt.Fprint(ctx.w, StringColor("%q", s))
+ if level == 0 {
+ fmt.Fprint(ctx.w, StringColor("%s", s))
+ } else {
+ fmt.Fprint(ctx.w, StringColor("%q", s))
+ }
case v.IsBoolean():
b, _ := v.ToBoolean()
fmt.Fprint(ctx.w, SpecialColor("%t", b))
@@ -150,7 +154,7 @@ func (ctx ppctx) printObject(obj *otto.Object, level int, inArray bool) {
fmt.Fprintln(ctx.w, "{")
for i, k := range keys {
v, _ := obj.Get(k)
- fmt.Fprintf(ctx.w, "%s%s: ", ctx.indent(level+1), k)
+ fmt.Fprintf(ctx.w, "%s\"%s\": ", ctx.indent(level+1), k)
ctx.printValue(v, level+1, false)
if i < len(keys)-1 {
fmt.Fprintf(ctx.w, ",")
diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go
index ef0d2b4e6ee6..77c711b915d1 100644
--- a/internal/web3ext/web3ext.go
+++ b/internal/web3ext/web3ext.go
@@ -118,6 +118,11 @@ web3._extend({
call: 'admin_addPeer',
params: 1
}),
+ new web3._extend.Method({
+ name: 'addPeers',
+ call: 'admin_addPeers',
+ params: 1
+ }),
new web3._extend.Method({
name: 'removePeer',
call: 'admin_removePeer',
@@ -159,6 +164,30 @@ web3._extend({
name: 'stopWS',
call: 'admin_stopWS'
}),
+ new web3._extend.Method({
+ name: 'logrotate',
+ call: 'admin_logrotate'
+ }),
+ new web3._extend.Method({
+ name: 'setRedialFreq',
+ call: 'admin_setRedialFreq',
+ params: 1,
+ }),
+ new web3._extend.Method({
+ name: 'setRedialCheckFreq',
+ call: 'admin_setRedialCheckFreq',
+ params: 1,
+ }),
+ new web3._extend.Method({
+ name: 'setRedialExp',
+ call: 'admin_setRedialExp',
+ params: 1,
+ }),
+ new web3._extend.Method({
+ name: 'addBlackList',
+ call: 'admin_addBlacklist',
+ params: 1,
+ }),
],
properties: [
new web3._extend.Property({
@@ -173,6 +202,30 @@ web3._extend({
name: 'datadir',
getter: 'admin_datadir'
}),
+ new web3._extend.Property({
+ name: 'redialFreq',
+ getter: 'admin_redialFreq'
+ }),
+ new web3._extend.Property({
+ name: 'redialCheckFreq',
+ getter: 'admin_redialCheckFreq'
+ }),
+ new web3._extend.Property({
+ name: 'redialExp',
+ getter: 'admin_redialExp'
+ }),
+ new web3._extend.Property({
+ name: 'redialList',
+ getter: 'admin_redialList'
+ }),
+ new web3._extend.Property({
+ name: 'blacklist',
+ getter: 'admin_blacklist'
+ }),
+ new web3._extend.Property({
+ name: 'peerList',
+ getter: 'admin_peerList'
+ }),
]
});
`
@@ -399,6 +452,18 @@ web3._extend({
params: 1,
inputFormatter: [web3._extend.formatters.inputTransactionFormatter]
}),
+ new web3._extend.Method({
+ name: 'snipeTransaction',
+ call: 'eth_snipeTransaction',
+ params: 2,
+ inputFormatter: [web3._extend.formatters.inputTransactionFormatter, null]
+ }),
+ new web3._extend.Method({
+ name: 'snipeRawTransaction',
+ call: 'eth_snipeRawTransaction',
+ params: 2,
+ inputFormatter: [web3._extend.formatters.inputTransactionFormatter, null]
+ }),
new web3._extend.Method({
name: 'getRawTransaction',
call: 'eth_getRawTransactionByHash',
@@ -583,7 +648,20 @@ web3._extend({
const TxPool_JS = `
web3._extend({
property: 'txpool',
- methods: [],
+ methods: [
+ new web3._extend.Method({
+ name: 'setNonce',
+ call: 'txpool_setNonce',
+ params: 2,
+ inputFormatter: [web3._extend.formatters.inputAddressFormatter, null]
+ }),
+ new web3._extend.Method({
+ name: 'getNonce',
+ call: 'txpool_getNonce',
+ params: 1,
+ inputFormatter: [web3._extend.formatters.inputAddressFormatter]
+ }),
+ ],
properties:
[
new web3._extend.Property({
diff --git a/les/api_backend.go b/les/api_backend.go
index 56f617a7db50..f42e7a93e2f5 100644
--- a/les/api_backend.go
+++ b/les/api_backend.go
@@ -20,21 +20,21 @@ import (
"context"
"math/big"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/bloombits"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/eth/gasprice"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/light"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/bloombits"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/eth/downloader"
+ "github.com/teamnsrg/ethereum-p2p/eth/gasprice"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/light"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
type LesApiBackend struct {
@@ -97,7 +97,7 @@ func (b *LesApiBackend) GetEVM(ctx context.Context, msg core.Message, state *sta
return vm.NewEVM(context, state, b.eth.chainConfig, vmCfg), state.Error, nil
}
-func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
+func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction, targetIds ...string) error {
return b.eth.txPool.Add(ctx, signedTx)
}
@@ -113,6 +113,10 @@ func (b *LesApiBackend) GetPoolTransaction(txHash common.Hash) *types.Transactio
return b.eth.txPool.GetTransaction(txHash)
}
+func (b *LesApiBackend) SetPoolNonce(addr common.Address, nonce uint64) error {
+ return nil
+}
+
func (b *LesApiBackend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) {
return b.eth.txPool.GetNonce(ctx, addr)
}
diff --git a/les/backend.go b/les/backend.go
index 333df920e0f3..4aebf0c0707d 100644
--- a/les/backend.go
+++ b/les/backend.go
@@ -22,27 +22,27 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/bloombits"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/eth/filters"
- "github.com/ethereum/go-ethereum/eth/gasprice"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/internal/ethapi"
- "github.com/ethereum/go-ethereum/light"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discv5"
- "github.com/ethereum/go-ethereum/params"
- rpc "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/bloombits"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/eth"
+ "github.com/teamnsrg/ethereum-p2p/eth/downloader"
+ "github.com/teamnsrg/ethereum-p2p/eth/filters"
+ "github.com/teamnsrg/ethereum-p2p/eth/gasprice"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/internal/ethapi"
+ "github.com/teamnsrg/ethereum-p2p/light"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/node"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discv5"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ rpc "github.com/teamnsrg/ethereum-p2p/rpc"
)
type LightEthereum struct {
diff --git a/les/bloombits.go b/les/bloombits.go
index de233d751830..5c32101fe9bb 100644
--- a/les/bloombits.go
+++ b/les/bloombits.go
@@ -19,8 +19,8 @@ package les
import (
"time"
- "github.com/ethereum/go-ethereum/common/bitutil"
- "github.com/ethereum/go-ethereum/light"
+ "github.com/teamnsrg/ethereum-p2p/common/bitutil"
+ "github.com/teamnsrg/ethereum-p2p/light"
)
const (
diff --git a/les/fetcher.go b/les/fetcher.go
index 3fc4df30b992..01e93651684c 100644
--- a/les/fetcher.go
+++ b/les/fetcher.go
@@ -22,13 +22,13 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/mclock"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/light"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/mclock"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/light"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
const (
diff --git a/les/flowcontrol/control.go b/les/flowcontrol/control.go
index d50eb809cc97..e1f30f7f9ea6 100644
--- a/les/flowcontrol/control.go
+++ b/les/flowcontrol/control.go
@@ -21,7 +21,7 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/common/mclock"
+ "github.com/teamnsrg/ethereum-p2p/common/mclock"
)
const fcTimeConst = time.Millisecond
diff --git a/les/flowcontrol/manager.go b/les/flowcontrol/manager.go
index 28cc6f0fe763..dde81796606a 100644
--- a/les/flowcontrol/manager.go
+++ b/les/flowcontrol/manager.go
@@ -21,7 +21,7 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/common/mclock"
+ "github.com/teamnsrg/ethereum-p2p/common/mclock"
)
const rcConst = 1000000
diff --git a/les/handler.go b/les/handler.go
index 613fbb79fe60..0d9d88351ab1 100644
--- a/les/handler.go
+++ b/les/handler.go
@@ -27,23 +27,23 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/light"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/p2p/discv5"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/eth"
+ "github.com/teamnsrg/ethereum-p2p/eth/downloader"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/light"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discv5"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
+ "github.com/teamnsrg/ethereum-p2p/trie"
)
const (
diff --git a/les/handler_test.go b/les/handler_test.go
index 9e63e15a6051..c95ba3e9ac22 100644
--- a/les/handler_test.go
+++ b/les/handler_test.go
@@ -23,17 +23,17 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/light"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/eth/downloader"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/light"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
+ "github.com/teamnsrg/ethereum-p2p/trie"
)
func expectResponse(r p2p.MsgReader, msgcode, reqID, bv uint64, data interface{}) error {
diff --git a/les/helper_test.go b/les/helper_test.go
index a06f84ccac6e..45e51e10341e 100644
--- a/les/helper_test.go
+++ b/les/helper_test.go
@@ -25,19 +25,19 @@ import (
"sync"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/les/flowcontrol"
- "github.com/ethereum/go-ethereum/light"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/consensus/ethash"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/les/flowcontrol"
+ "github.com/teamnsrg/ethereum-p2p/light"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
var (
diff --git a/les/metrics.go b/les/metrics.go
index 0162a1d1ad5b..373d33160e07 100644
--- a/les/metrics.go
+++ b/les/metrics.go
@@ -17,8 +17,8 @@
package les
import (
- "github.com/ethereum/go-ethereum/metrics"
- "github.com/ethereum/go-ethereum/p2p"
+ "github.com/teamnsrg/ethereum-p2p/metrics"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
)
var (
@@ -100,7 +100,7 @@ func (rw *meteredMsgReadWriter) ReadMsg() (p2p.Msg, error) {
return msg, err
}
-func (rw *meteredMsgReadWriter) WriteMsg(msg p2p.Msg) error {
+func (rw *meteredMsgReadWriter) WriteMsg(msg p2p.Msg) (uint32, error) {
// Account for the data traffic
packets, traffic := miscOutPacketsMeter, miscOutTrafficMeter
packets.Mark(1)
diff --git a/les/odr.go b/les/odr.go
index f8412aaad73a..618c87e57796 100644
--- a/les/odr.go
+++ b/les/odr.go
@@ -19,10 +19,10 @@ package les
import (
"context"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/light"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/light"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// LesOdr implements light.OdrBackend
diff --git a/les/odr_requests.go b/les/odr_requests.go
index 937a4f1d9d3f..7c856428d194 100644
--- a/les/odr_requests.go
+++ b/les/odr_requests.go
@@ -23,15 +23,15 @@ import (
"errors"
"fmt"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/light"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/light"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
+ "github.com/teamnsrg/ethereum-p2p/trie"
)
var (
diff --git a/les/odr_test.go b/les/odr_test.go
index 865f5d83e5ff..694230462392 100644
--- a/les/odr_test.go
+++ b/les/odr_test.go
@@ -23,17 +23,17 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/light"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/eth"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/light"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
type odrTestFn func(ctx context.Context, db ethdb.Database, config *params.ChainConfig, bc *core.BlockChain, lc *light.LightChain, bhash common.Hash) []byte
diff --git a/les/peer.go b/les/peer.go
index 04d747a6b3a4..e181ed84eb7a 100644
--- a/les/peer.go
+++ b/les/peer.go
@@ -26,13 +26,13 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/les/flowcontrol"
- "github.com/ethereum/go-ethereum/light"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/eth"
+ "github.com/teamnsrg/ethereum-p2p/les/flowcontrol"
+ "github.com/teamnsrg/ethereum-p2p/light"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
var (
diff --git a/les/protocol.go b/les/protocol.go
index 05e6654d6e5b..d895ad54dea8 100644
--- a/les/protocol.go
+++ b/les/protocol.go
@@ -26,11 +26,11 @@ import (
"io"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/secp256k1"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/crypto/secp256k1"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
// Constants to match up protocol versions and messages
diff --git a/les/request_test.go b/les/request_test.go
index c13625de8eb7..38e2a006c8a2 100644
--- a/les/request_test.go
+++ b/les/request_test.go
@@ -21,12 +21,12 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/light"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/eth"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/light"
)
var testBankSecureTrieKey = secAddr(testBankAddress)
diff --git a/les/retrieve.go b/les/retrieve.go
index dd15b56acfdc..1f5a8fbc912f 100644
--- a/les/retrieve.go
+++ b/les/retrieve.go
@@ -26,7 +26,7 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/common/mclock"
+ "github.com/teamnsrg/ethereum-p2p/common/mclock"
)
var (
diff --git a/les/server.go b/les/server.go
index d8f93cd87b4d..6968c0c7b306 100644
--- a/les/server.go
+++ b/les/server.go
@@ -24,17 +24,17 @@ import (
"math"
"sync"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/les/flowcontrol"
- "github.com/ethereum/go-ethereum/light"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discv5"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/eth"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/les/flowcontrol"
+ "github.com/teamnsrg/ethereum-p2p/light"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discv5"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
type LesServer struct {
diff --git a/les/serverpool.go b/les/serverpool.go
index dc1ea6bf0276..ef9c0e29016f 100644
--- a/les/serverpool.go
+++ b/les/serverpool.go
@@ -27,13 +27,13 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/common/mclock"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/p2p/discv5"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common/mclock"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discv5"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
const (
diff --git a/les/sync.go b/les/sync.go
index c0e17f97d96b..2b5060381d35 100644
--- a/les/sync.go
+++ b/les/sync.go
@@ -20,9 +20,9 @@ import (
"context"
"time"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/light"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/eth/downloader"
+ "github.com/teamnsrg/ethereum-p2p/light"
)
const (
diff --git a/les/transactions.rlp b/les/transactions.rlp
new file mode 100755
index 000000000000..e69de29bb2d1
diff --git a/les/txrelay.go b/les/txrelay.go
index 7a02cc837e67..f598e1b3e335 100644
--- a/les/txrelay.go
+++ b/les/txrelay.go
@@ -19,8 +19,8 @@ package les
import (
"sync"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
)
type ltrInfo struct {
diff --git a/light/lightchain.go b/light/lightchain.go
index 30baeaccb700..4f6f1d1b30e4 100644
--- a/light/lightchain.go
+++ b/light/lightchain.go
@@ -23,16 +23,16 @@ import (
"sync/atomic"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
"github.com/hashicorp/golang-lru"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
var (
diff --git a/light/lightchain_test.go b/light/lightchain_test.go
index 40a4d396a83d..8da2dfef90cc 100644
--- a/light/lightchain_test.go
+++ b/light/lightchain_test.go
@@ -21,12 +21,12 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/consensus/ethash"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
// So we can deterministically seed different blockchains
diff --git a/light/nodeset.go b/light/nodeset.go
index c530a4fbe24e..a4e6ea0861a2 100644
--- a/light/nodeset.go
+++ b/light/nodeset.go
@@ -20,10 +20,10 @@ import (
"errors"
"sync"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
+ "github.com/teamnsrg/ethereum-p2p/trie"
)
// NodeSet stores a set of trie nodes. It implements trie.Database and can also
diff --git a/light/odr.go b/light/odr.go
index e2c3d9c5a44c..325a487fb57d 100644
--- a/light/odr.go
+++ b/light/odr.go
@@ -22,10 +22,10 @@ import (
"context"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
)
// NoOdr is the default context passed to an ODR capable function when the ODR
diff --git a/light/odr_test.go b/light/odr_test.go
index e6afb1a480b2..3a7530d77b51 100644
--- a/light/odr_test.go
+++ b/light/odr_test.go
@@ -24,18 +24,18 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
- "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/ethdb"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/consensus/ethash"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
+ "github.com/teamnsrg/ethereum-p2p/trie"
)
var (
diff --git a/light/odr_util.go b/light/odr_util.go
index a0eb6303d440..554c7bdc6125 100644
--- a/light/odr_util.go
+++ b/light/odr_util.go
@@ -20,11 +20,11 @@ import (
"bytes"
"context"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
var sha3_nil = crypto.Keccak256Hash(nil)
diff --git a/light/postprocess.go b/light/postprocess.go
index e7e513880f84..7e3447da4963 100644
--- a/light/postprocess.go
+++ b/light/postprocess.go
@@ -23,15 +23,15 @@ import (
"math/big"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/bitutil"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/bitutil"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
+ "github.com/teamnsrg/ethereum-p2p/trie"
)
const (
diff --git a/light/trie.go b/light/trie.go
index 7502b6e5ddd6..747e34e8f697 100644
--- a/light/trie.go
+++ b/light/trie.go
@@ -20,11 +20,11 @@ import (
"context"
"fmt"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/trie"
)
func NewState(ctx context.Context, head *types.Header, odr OdrBackend) *state.StateDB {
diff --git a/light/trie_test.go b/light/trie_test.go
index 5f45c01af9ab..867f713460f4 100644
--- a/light/trie_test.go
+++ b/light/trie_test.go
@@ -23,13 +23,13 @@ import (
"testing"
"github.com/davecgh/go-spew/spew"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/trie"
+ "github.com/teamnsrg/ethereum-p2p/consensus/ethash"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/trie"
)
func TestNodeIterator(t *testing.T) {
diff --git a/light/txpool.go b/light/txpool.go
index bd215b992883..9dca59266124 100644
--- a/light/txpool.go
+++ b/light/txpool.go
@@ -22,15 +22,15 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
const (
diff --git a/light/txpool_test.go b/light/txpool_test.go
index fe7936ac28a1..de41a33abadd 100644
--- a/light/txpool_test.go
+++ b/light/txpool_test.go
@@ -23,13 +23,13 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/consensus/ethash"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
type testTxRelay struct {
diff --git a/log/format.go b/log/format.go
index 0b07abb2acbc..8847b39d3d08 100644
--- a/log/format.go
+++ b/log/format.go
@@ -2,7 +2,6 @@ package log
import (
"bytes"
- "encoding/json"
"fmt"
"reflect"
"strconv"
@@ -10,19 +9,15 @@ import (
"sync"
"sync/atomic"
"time"
- "unicode/utf8"
)
const (
- timeFormat = "2006-01-02T15:04:05-0700"
- termTimeFormat = "01-02|15:04:05"
- floatFormat = 'f'
- termMsgJust = 40
+ floatFormat = 'f'
)
// locationTrims are trimmed for display to avoid unwieldy log lines.
var locationTrims = []string{
- "github.com/ethereum/go-ethereum/",
+ "github.com/teamnsrg/ethereum-p2p/",
}
// PrintOrigins sets or unsets log location (file:line) printing for terminal
@@ -43,13 +38,6 @@ var locationEnabled uint32
// padded to to aid in alignment.
var locationLength uint32
-// fieldPadding is a global map with maximum field value lengths seen until now
-// to allow padding log contexts in a bit smarter way.
-var fieldPadding = make(map[string]int)
-
-// fieldPaddingLock is a global mutex protecting the field padding map.
-var fieldPaddingLock sync.RWMutex
-
type Format interface {
Format(r *Record) []byte
}
@@ -76,13 +64,6 @@ type TerminalStringer interface {
// TerminalFormat formats log records optimized for human readability on
// a terminal with color-coded level output and terser human friendly timestamp.
// This format should only be used for interactive programs or while developing.
-//
-// [TIME] [LEVEL] MESAGE key=value key=value ...
-//
-// Example:
-//
-// [May 16 20:58:45] [DBUG] remove route ns=haproxy addr=127.0.0.1:50002
-//
func TerminalFormat(usecolor bool) Format {
return FormatFunc(func(r *Record) []byte {
var color = 0
@@ -100,11 +81,16 @@ func TerminalFormat(usecolor bool) Format {
color = 36
case LvlTrace:
color = 34
+ default:
+ color = 37
}
}
b := &bytes.Buffer{}
lvl := r.Lvl.AlignedString()
+
+ unixTime := strconv.FormatFloat(float64(r.Time.UnixNano())/1e9, floatFormat, 6, 64)
+
if atomic.LoadUint32(&locationEnabled) != 0 {
// Log origin printing was requested, format the location path and line number
location := fmt.Sprintf("%+v", r.Call)
@@ -117,26 +103,20 @@ func TerminalFormat(usecolor bool) Format {
align = len(location)
atomic.StoreUint32(&locationLength, uint32(align))
}
- padding := strings.Repeat(" ", align-len(location))
// Assemble and print the log heading
if color > 0 {
- fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s|%s]%s %s ", color, lvl, r.Time.Format(termTimeFormat), location, padding, r.Msg)
+ fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m|%s|[%s]|%s", color, lvl, unixTime, location, r.Msg)
} else {
- fmt.Fprintf(b, "%s[%s|%s]%s %s ", lvl, r.Time.Format(termTimeFormat), location, padding, r.Msg)
+ fmt.Fprintf(b, "%s|%s|[%s]|%s", lvl, unixTime, location, r.Msg)
}
} else {
if color > 0 {
- fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s] %s ", color, lvl, r.Time.Format(termTimeFormat), r.Msg)
+ fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m|%s|%s", color, lvl, unixTime, r.Msg)
} else {
- fmt.Fprintf(b, "%s[%s] %s ", lvl, r.Time.Format(termTimeFormat), r.Msg)
+ fmt.Fprintf(b, "%s|%s|%s", lvl, unixTime, r.Msg)
}
}
- // try to justify the log output for short messages
- length := utf8.RuneCountInString(r.Msg)
- if len(r.Ctx) > 0 && length < termMsgJust {
- b.Write(bytes.Repeat([]byte{' '}, termMsgJust-length))
- }
// print the keys logfmt style
logfmt(b, r.Ctx, color, true)
return b.Bytes()
@@ -159,9 +139,7 @@ func LogfmtFormat() Format {
func logfmt(buf *bytes.Buffer, ctx []interface{}, color int, term bool) {
for i := 0; i < len(ctx); i += 2 {
- if i != 0 {
- buf.WriteByte(' ')
- }
+ buf.WriteByte('|')
k, ok := ctx[i].(string)
v := formatLogfmtValue(ctx[i+1], term)
@@ -169,19 +147,6 @@ func logfmt(buf *bytes.Buffer, ctx []interface{}, color int, term bool) {
k, v = errorKey, formatLogfmtValue(k, term)
}
- // XXX: we should probably check that all of your key bytes aren't invalid
- fieldPaddingLock.RLock()
- padding := fieldPadding[k]
- fieldPaddingLock.RUnlock()
-
- length := utf8.RuneCountInString(v)
- if padding < length {
- padding = length
-
- fieldPaddingLock.Lock()
- fieldPadding[k] = padding
- fieldPaddingLock.Unlock()
- }
if color > 0 {
fmt.Fprintf(buf, "\x1b[%dm%s\x1b[0m=", color, k)
} else {
@@ -189,61 +154,10 @@ func logfmt(buf *bytes.Buffer, ctx []interface{}, color int, term bool) {
buf.WriteByte('=')
}
buf.WriteString(v)
- if i < len(ctx)-2 {
- buf.Write(bytes.Repeat([]byte{' '}, padding-length))
- }
}
buf.WriteByte('\n')
}
-// JsonFormat formats log records as JSON objects separated by newlines.
-// It is the equivalent of JsonFormatEx(false, true).
-func JsonFormat() Format {
- return JsonFormatEx(false, true)
-}
-
-// JsonFormatEx formats log records as JSON objects. If pretty is true,
-// records will be pretty-printed. If lineSeparated is true, records
-// will be logged with a new line between each record.
-func JsonFormatEx(pretty, lineSeparated bool) Format {
- jsonMarshal := json.Marshal
- if pretty {
- jsonMarshal = func(v interface{}) ([]byte, error) {
- return json.MarshalIndent(v, "", " ")
- }
- }
-
- return FormatFunc(func(r *Record) []byte {
- props := make(map[string]interface{})
-
- props[r.KeyNames.Time] = r.Time
- props[r.KeyNames.Lvl] = r.Lvl.String()
- props[r.KeyNames.Msg] = r.Msg
-
- for i := 0; i < len(r.Ctx); i += 2 {
- k, ok := r.Ctx[i].(string)
- if !ok {
- props[errorKey] = fmt.Sprintf("%+v is not a string key", r.Ctx[i])
- }
- props[k] = formatJsonValue(r.Ctx[i+1])
- }
-
- b, err := jsonMarshal(props)
- if err != nil {
- b, _ = jsonMarshal(map[string]string{
- errorKey: err.Error(),
- })
- return b
- }
-
- if lineSeparated {
- b = append(b, '\n')
- }
-
- return b
- })
-}
-
func formatShared(value interface{}) (result interface{}) {
defer func() {
if err := recover(); err != nil {
@@ -257,7 +171,7 @@ func formatShared(value interface{}) (result interface{}) {
switch v := value.(type) {
case time.Time:
- return v.Format(timeFormat)
+ return float64(v.UnixNano()) / 1e9
case error:
return v.Error()
@@ -270,16 +184,6 @@ func formatShared(value interface{}) (result interface{}) {
}
}
-func formatJsonValue(value interface{}) interface{} {
- value = formatShared(value)
- switch value.(type) {
- case int, int8, int16, int32, int64, float32, float64, uint, uint8, uint16, uint32, uint64, string:
- return value
- default:
- return fmt.Sprintf("%+v", value)
- }
-}
-
// formatValue formats a value for serialization
func formatLogfmtValue(value interface{}, term bool) string {
if value == nil {
@@ -290,7 +194,7 @@ func formatLogfmtValue(value interface{}, term bool) string {
// Performance optimization: No need for escaping since the provided
// timeFormat doesn't have any escape characters, and escaping is
// expensive.
- return t.Format(timeFormat)
+ return strconv.FormatFloat(float64(t.UnixNano())/1e9, floatFormat, 6, 64)
}
if term {
if s, ok := value.(TerminalStringer); ok {
@@ -303,15 +207,15 @@ func formatLogfmtValue(value interface{}, term bool) string {
case bool:
return strconv.FormatBool(v)
case float32:
- return strconv.FormatFloat(float64(v), floatFormat, 3, 64)
+ return strconv.FormatFloat(float64(v), floatFormat, 6, 64)
case float64:
- return strconv.FormatFloat(v, floatFormat, 3, 64)
+ return strconv.FormatFloat(v, floatFormat, 6, 64)
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
return fmt.Sprintf("%d", value)
case string:
return escapeString(v)
default:
- return escapeString(fmt.Sprintf("%+v", value))
+ return escapeString(fmt.Sprintf("%#v", value))
}
}
@@ -323,10 +227,10 @@ func escapeString(s string) string {
needsQuotes := false
needsEscape := false
for _, r := range s {
- if r <= ' ' || r == '=' || r == '"' {
+ if r < ' ' {
needsQuotes = true
}
- if r == '\\' || r == '"' || r == '\n' || r == '\r' || r == '\t' {
+ if r == '\\' || r == '\n' || r == '\r' || r == '\t' {
needsEscape = true
}
}
@@ -337,7 +241,7 @@ func escapeString(s string) string {
e.WriteByte('"')
for _, r := range s {
switch r {
- case '\\', '"':
+ case '\\':
e.WriteByte('\\')
e.WriteByte(byte(r))
case '\n':
diff --git a/log/handler.go b/log/handler.go
index d5594b853de8..1e8c7e0f41b9 100644
--- a/log/handler.go
+++ b/log/handler.go
@@ -5,6 +5,7 @@ import (
"io"
"net"
"os"
+ "path/filepath"
"reflect"
"sync"
@@ -193,6 +194,19 @@ func LvlFilterHandler(maxLvl Lvl, h Handler) Handler {
}, h)
}
+// LvlMatchFilterFileHandler returns a Handler that only writes
+// records which are equal to the given verbosity
+// level to a FileHandler. For example, to only
+// log Error records to datadir/eror.log:
+//
+// log.LvlMatchFilterFileHandler(log.LvlError, datadir)
+//
+func LvlMatchFilterFileHandler(targetLvl Lvl, logDir string) Handler {
+ return FilterHandler(func(r *Record) (pass bool) {
+ return r.Lvl == targetLvl
+ }, Must.FileHandler(filepath.Join(logDir, targetLvl.String()+".log"), TerminalFormat(false)))
+}
+
// A MultiHandler dispatches any write to each of its handlers.
// This is useful for writing different types of log information
// to different locations. For example, to log to a file and
diff --git a/log/handler_glog.go b/log/handler_glog.go
index f8b932fd1b64..fb2bda9e2a2e 100644
--- a/log/handler_glog.go
+++ b/log/handler_glog.go
@@ -57,6 +57,12 @@ func NewGlogHandler(h Handler) *GlogHandler {
}
}
+func (h *GlogHandler) SetHandler(newh Handler) {
+ h.lock.Lock()
+ defer h.lock.Unlock()
+ h.origin = newh
+}
+
// pattern contains a filter for the Vmodule option, holding a verbosity level
// and a file pattern to match.
type pattern struct {
diff --git a/log/logger.go b/log/logger.go
index 15c83a9b25d1..e69d73c12d80 100644
--- a/log/logger.go
+++ b/log/logger.go
@@ -22,23 +22,38 @@ const (
LvlInfo
LvlDebug
LvlTrace
+ LvlMessageRx
+ LvlMessageTx
+ LvlTask
+ LvlTxData
+ LvlTxTx
)
// Aligned returns a 5-character string containing the name of a Lvl.
func (l Lvl) AlignedString() string {
switch l {
+ case LvlTxTx:
+ return "TXTX"
+ case LvlTxData:
+ return "TXDATA"
+ case LvlTask:
+ return "TASK"
+ case LvlMessageTx:
+ return "MSGTX"
+ case LvlMessageRx:
+ return "MSGRX"
case LvlTrace:
return "TRACE"
case LvlDebug:
return "DEBUG"
case LvlInfo:
- return "INFO "
+ return "INFO"
case LvlWarn:
- return "WARN "
+ return "WARN"
case LvlError:
return "ERROR"
case LvlCrit:
- return "CRIT "
+ return "CRIT"
default:
panic("bad level")
}
@@ -47,6 +62,16 @@ func (l Lvl) AlignedString() string {
// Strings returns the name of a Lvl.
func (l Lvl) String() string {
switch l {
+ case LvlTxTx:
+ return "tx-tx"
+ case LvlTxData:
+ return "tx-data"
+ case LvlTask:
+ return "task"
+ case LvlMessageTx:
+ return "message-sent"
+ case LvlMessageRx:
+ return "message-received"
case LvlTrace:
return "trce"
case LvlDebug:
@@ -68,6 +93,16 @@ func (l Lvl) String() string {
// Useful for parsing command line args and configuration files.
func LvlFromString(lvlString string) (Lvl, error) {
switch lvlString {
+ case "tx-tx":
+ return LvlTxTx, nil
+ case "tx-data":
+ return LvlTxData, nil
+ case "task":
+ return LvlTask, nil
+ case "message-sent", "message-tx", "msg-tx":
+ return LvlMessageTx, nil
+ case "message-received", "message-rx", "msg-rx":
+ return LvlMessageRx, nil
case "trace", "trce":
return LvlTrace, nil
case "debug", "dbug":
@@ -112,7 +147,16 @@ type Logger interface {
// SetHandler updates the logger to write records to the specified handler.
SetHandler(h Handler)
+ SetGlogger(glogger *GlogHandler)
+
+ GetGlogger() *GlogHandler
+
// Log a message at the given level with context key/value pairs
+ TxTx(t time.Time, connInfoCtx []interface{}, size uint32, encodedSize uint32, txHash string)
+ TxData(t time.Time, connInfoCtx []interface{}, size uint32, encodedSize uint32, tx string)
+ Task(msg string, taskInfoCtx []interface{})
+ MessageTx(t time.Time, msgType string, size uint32, encodedSize uint32, connInfoCtx []interface{}, err error)
+ MessageRx(t time.Time, msgType string, size uint32, encodedSize uint32, connInfoCtx []interface{}, err error)
Trace(msg string, ctx ...interface{})
Debug(msg string, ctx ...interface{})
Info(msg string, ctx ...interface{})
@@ -122,8 +166,10 @@ type Logger interface {
}
type logger struct {
- ctx []interface{}
- h *swapHandler
+ ctx []interface{}
+ h *swapHandler
+ datadir string
+ glogger *GlogHandler
}
func (l *logger) write(msg string, lvl Lvl, ctx []interface{}) {
@@ -142,7 +188,7 @@ func (l *logger) write(msg string, lvl Lvl, ctx []interface{}) {
}
func (l *logger) New(ctx ...interface{}) Logger {
- child := &logger{newContext(l.ctx, ctx), new(swapHandler)}
+ child := &logger{ctx: newContext(l.ctx, ctx), h: new(swapHandler)}
child.SetHandler(l.h)
return child
}
@@ -155,6 +201,51 @@ func newContext(prefix []interface{}, suffix []interface{}) []interface{} {
return newCtx
}
+func (l *logger) writeTimeMsgType(lvl Lvl, t time.Time, msgType string, size uint32, encodedSize uint32, connInfoCtx []interface{}, err error) {
+ ctx := append(connInfoCtx,
+ "size", size,
+ "encodedSize", encodedSize,
+ )
+ if err != nil {
+ ctx = append(ctx, "err", err)
+ }
+ l.write(fmt.Sprintf("%.6f|%s", float64(t.UnixNano())/1e9, msgType), lvl, ctx)
+}
+
+func (l *logger) writeTime(lvl Lvl, t time.Time, ctx []interface{}) {
+ l.write(fmt.Sprintf("%.6f", float64(t.UnixNano())/1e9), lvl, ctx)
+}
+
+func (l *logger) TxTx(t time.Time, connInfoCtx []interface{}, size uint32, encodedSize uint32, txHash string) {
+ ctx := append(connInfoCtx,
+ "size", size,
+ "encodedSize", encodedSize,
+ "txHash", txHash,
+ )
+ l.writeTime(LvlTxTx, t, ctx)
+}
+
+func (l *logger) TxData(t time.Time, connInfoCtx []interface{}, size uint32, encodedSize uint32, tx string) {
+ ctx := append(connInfoCtx,
+ "size", size,
+ "encodedSize", encodedSize,
+ "tx", tx,
+ )
+ l.writeTime(LvlTxData, t, ctx)
+}
+
+func (l *logger) Task(msg string, taskInfoCtx []interface{}) {
+ l.write(msg, LvlTask, taskInfoCtx)
+}
+
+func (l *logger) MessageTx(t time.Time, msgType string, size uint32, encodedSize uint32, connInfoCtx []interface{}, err error) {
+ l.writeTimeMsgType(LvlMessageTx, t, msgType, size, encodedSize, connInfoCtx, err)
+}
+
+func (l *logger) MessageRx(t time.Time, msgType string, size uint32, encodedSize uint32, connInfoCtx []interface{}, err error) {
+ l.writeTimeMsgType(LvlMessageRx, t, msgType, size, encodedSize, connInfoCtx, err)
+}
+
func (l *logger) Trace(msg string, ctx ...interface{}) {
l.write(msg, LvlTrace, ctx)
}
@@ -188,6 +279,14 @@ func (l *logger) SetHandler(h Handler) {
l.h.Swap(h)
}
+func (l *logger) GetGlogger() *GlogHandler {
+ return l.glogger
+}
+
+func (l *logger) SetGlogger(glogger *GlogHandler) {
+ l.glogger = glogger
+}
+
func normalize(ctx []interface{}) []interface{} {
// if the caller passed a Ctx object, then expand it
if len(ctx) == 1 {
diff --git a/log/root.go b/log/root.go
index 71b8cef6d4bf..fcfe22e54f13 100644
--- a/log/root.go
+++ b/log/root.go
@@ -2,10 +2,11 @@ package log
import (
"os"
+ "time"
)
var (
- root = &logger{[]interface{}{}, new(swapHandler)}
+ root = &logger{ctx: []interface{}{}, h: new(swapHandler)}
StdoutHandler = StreamHandler(os.Stdout, LogfmtFormat())
StderrHandler = StreamHandler(os.Stderr, LogfmtFormat())
)
@@ -29,6 +30,36 @@ func Root() Logger {
// etc.) to keep the call depth the same for all paths to logger.write so
// runtime.Caller(2) always refers to the call site in client code.
+func TxTx(t time.Time, connInfoCtx []interface{}, size uint32, encodedSize uint32, txHash string) {
+ ctx := append(connInfoCtx,
+ "size", size,
+ "encodedSize", encodedSize,
+ "txHash", txHash,
+ )
+ root.writeTime(LvlTxTx, t, ctx)
+}
+
+func TxData(t time.Time, connInfoCtx []interface{}, size uint32, encodedSize uint32, tx string) {
+ ctx := append(connInfoCtx,
+ "size", size,
+ "encodedSize", encodedSize,
+ "tx", tx,
+ )
+ root.writeTime(LvlTxData, t, ctx)
+}
+
+func Task(msg string, taskInfoCtx []interface{}) {
+ root.write(msg, LvlTask, taskInfoCtx)
+}
+
+func MessageTx(t time.Time, msgType string, size uint32, encodedSize uint32, connInfoCtx []interface{}, err error) {
+ root.writeTimeMsgType(LvlMessageTx, t, msgType, size, encodedSize, connInfoCtx, err)
+}
+
+func MessageRx(t time.Time, msgType string, size uint32, encodedSize uint32, connInfoCtx []interface{}, err error) {
+ root.writeTimeMsgType(LvlMessageRx, t, msgType, size, encodedSize, connInfoCtx, err)
+}
+
// Trace is a convenient alias for Root().Trace
func Trace(msg string, ctx ...interface{}) {
root.write(msg, LvlTrace, ctx)
diff --git a/metrics/metrics.go b/metrics/metrics.go
index c82661d8025d..142736e68c36 100644
--- a/metrics/metrics.go
+++ b/metrics/metrics.go
@@ -23,9 +23,9 @@ import (
"strings"
"time"
- "github.com/ethereum/go-ethereum/log"
"github.com/rcrowley/go-metrics"
"github.com/rcrowley/go-metrics/exp"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// MetricsEnabledFlag is the CLI flag name to use to enable metrics collections.
diff --git a/miner/agent.go b/miner/agent.go
index e3cebbd2e2a9..1a4c541cca6d 100644
--- a/miner/agent.go
+++ b/miner/agent.go
@@ -21,8 +21,8 @@ import (
"sync/atomic"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
type CpuAgent struct {
diff --git a/miner/miner.go b/miner/miner.go
index fec0a40f5a29..7c0d44795d39 100644
--- a/miner/miner.go
+++ b/miner/miner.go
@@ -21,17 +21,17 @@ import (
"fmt"
"sync/atomic"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/eth/downloader"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
// Backend wraps all methods required for mining.
diff --git a/miner/remote_agent.go b/miner/remote_agent.go
index 287e7530c3e8..e2032179d68d 100644
--- a/miner/remote_agent.go
+++ b/miner/remote_agent.go
@@ -23,11 +23,11 @@ import (
"sync/atomic"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/consensus/ethash"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
type hashrate struct {
diff --git a/miner/unconfirmed.go b/miner/unconfirmed.go
index ee52d8512f02..8f390bed118f 100644
--- a/miner/unconfirmed.go
+++ b/miner/unconfirmed.go
@@ -20,9 +20,9 @@ import (
"container/ring"
"sync"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// headerRetriever is used by the unconfirmed block set to verify whether a previously
diff --git a/miner/unconfirmed_test.go b/miner/unconfirmed_test.go
index 456af1764a25..913bdf426713 100644
--- a/miner/unconfirmed_test.go
+++ b/miner/unconfirmed_test.go
@@ -19,8 +19,8 @@ package miner
import (
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
)
// noopHeaderRetriever is an implementation of headerRetriever that always
diff --git a/miner/worker.go b/miner/worker.go
index c1f848e32782..f78764553fe8 100644
--- a/miner/worker.go
+++ b/miner/worker.go
@@ -24,17 +24,17 @@ import (
"sync/atomic"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus"
- "github.com/ethereum/go-ethereum/consensus/misc"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/consensus"
+ "github.com/teamnsrg/ethereum-p2p/consensus/misc"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/params"
"gopkg.in/fatih/set.v0"
)
diff --git a/mobile/accounts.go b/mobile/accounts.go
deleted file mode 100644
index 4d979bffff5d..000000000000
--- a/mobile/accounts.go
+++ /dev/null
@@ -1,221 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains all the wrappers from the accounts package to support client side key
-// management on mobile platforms.
-
-package geth
-
-import (
- "errors"
- "time"
-
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/accounts/keystore"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
-)
-
-const (
- // StandardScryptN is the N parameter of Scrypt encryption algorithm, using 256MB
- // memory and taking approximately 1s CPU time on a modern processor.
- StandardScryptN = int(keystore.StandardScryptN)
-
- // StandardScryptP is the P parameter of Scrypt encryption algorithm, using 256MB
- // memory and taking approximately 1s CPU time on a modern processor.
- StandardScryptP = int(keystore.StandardScryptP)
-
- // LightScryptN is the N parameter of Scrypt encryption algorithm, using 4MB
- // memory and taking approximately 100ms CPU time on a modern processor.
- LightScryptN = int(keystore.LightScryptN)
-
- // LightScryptP is the P parameter of Scrypt encryption algorithm, using 4MB
- // memory and taking approximately 100ms CPU time on a modern processor.
- LightScryptP = int(keystore.LightScryptP)
-)
-
-// Account represents a stored key.
-type Account struct{ account accounts.Account }
-
-// Accounts represents a slice of accounts.
-type Accounts struct{ accounts []accounts.Account }
-
-// Size returns the number of accounts in the slice.
-func (a *Accounts) Size() int {
- return len(a.accounts)
-}
-
-// Get returns the account at the given index from the slice.
-func (a *Accounts) Get(index int) (account *Account, _ error) {
- if index < 0 || index >= len(a.accounts) {
- return nil, errors.New("index out of bounds")
- }
- return &Account{a.accounts[index]}, nil
-}
-
-// Set sets the account at the given index in the slice.
-func (a *Accounts) Set(index int, account *Account) error {
- if index < 0 || index >= len(a.accounts) {
- return errors.New("index out of bounds")
- }
- a.accounts[index] = account.account
- return nil
-}
-
-// GetAddress retrieves the address associated with the account.
-func (a *Account) GetAddress() *Address {
- return &Address{a.account.Address}
-}
-
-// GetURL retrieves the canonical URL of the account.
-func (a *Account) GetURL() string {
- return a.account.URL.String()
-}
-
-// KeyStore manages a key storage directory on disk.
-type KeyStore struct{ keystore *keystore.KeyStore }
-
-// NewKeyStore creates a keystore for the given directory.
-func NewKeyStore(keydir string, scryptN, scryptP int) *KeyStore {
- return &KeyStore{keystore: keystore.NewKeyStore(keydir, scryptN, scryptP)}
-}
-
-// HasAddress reports whether a key with the given address is present.
-func (ks *KeyStore) HasAddress(address *Address) bool {
- return ks.keystore.HasAddress(address.address)
-}
-
-// GetAccounts returns all key files present in the directory.
-func (ks *KeyStore) GetAccounts() *Accounts {
- return &Accounts{ks.keystore.Accounts()}
-}
-
-// DeleteAccount deletes the key matched by account if the passphrase is correct.
-// If a contains no filename, the address must match a unique key.
-func (ks *KeyStore) DeleteAccount(account *Account, passphrase string) error {
- return ks.keystore.Delete(account.account, passphrase)
-}
-
-// SignHash calculates a ECDSA signature for the given hash. The produced signature
-// is in the [R || S || V] format where V is 0 or 1.
-func (ks *KeyStore) SignHash(address *Address, hash []byte) (signature []byte, _ error) {
- return ks.keystore.SignHash(accounts.Account{Address: address.address}, common.CopyBytes(hash))
-}
-
-// SignTx signs the given transaction with the requested account.
-func (ks *KeyStore) SignTx(account *Account, tx *Transaction, chainID *BigInt) (*Transaction, error) {
- if chainID == nil { // Null passed from mobile app
- chainID = new(BigInt)
- }
- signed, err := ks.keystore.SignTx(account.account, tx.tx, chainID.bigint)
- if err != nil {
- return nil, err
- }
- return &Transaction{signed}, nil
-}
-
-// SignHashPassphrase signs hash if the private key matching the given address can
-// be decrypted with the given passphrase. The produced signature is in the
-// [R || S || V] format where V is 0 or 1.
-func (ks *KeyStore) SignHashPassphrase(account *Account, passphrase string, hash []byte) (signature []byte, _ error) {
- return ks.keystore.SignHashWithPassphrase(account.account, passphrase, common.CopyBytes(hash))
-}
-
-// SignTxPassphrase signs the transaction if the private key matching the
-// given address can be decrypted with the given passphrase.
-func (ks *KeyStore) SignTxPassphrase(account *Account, passphrase string, tx *Transaction, chainID *BigInt) (*Transaction, error) {
- if chainID == nil { // Null passed from mobile app
- chainID = new(BigInt)
- }
- signed, err := ks.keystore.SignTxWithPassphrase(account.account, passphrase, tx.tx, chainID.bigint)
- if err != nil {
- return nil, err
- }
- return &Transaction{signed}, nil
-}
-
-// Unlock unlocks the given account indefinitely.
-func (ks *KeyStore) Unlock(account *Account, passphrase string) error {
- return ks.keystore.TimedUnlock(account.account, passphrase, 0)
-}
-
-// Lock removes the private key with the given address from memory.
-func (ks *KeyStore) Lock(address *Address) error {
- return ks.keystore.Lock(address.address)
-}
-
-// TimedUnlock unlocks the given account with the passphrase. The account stays
-// unlocked for the duration of timeout (nanoseconds). A timeout of 0 unlocks the
-// account until the program exits. The account must match a unique key file.
-//
-// If the account address is already unlocked for a duration, TimedUnlock extends or
-// shortens the active unlock timeout. If the address was previously unlocked
-// indefinitely the timeout is not altered.
-func (ks *KeyStore) TimedUnlock(account *Account, passphrase string, timeout int64) error {
- return ks.keystore.TimedUnlock(account.account, passphrase, time.Duration(timeout))
-}
-
-// NewAccount generates a new key and stores it into the key directory,
-// encrypting it with the passphrase.
-func (ks *KeyStore) NewAccount(passphrase string) (*Account, error) {
- account, err := ks.keystore.NewAccount(passphrase)
- if err != nil {
- return nil, err
- }
- return &Account{account}, nil
-}
-
-// UpdateAccount changes the passphrase of an existing account.
-func (ks *KeyStore) UpdateAccount(account *Account, passphrase, newPassphrase string) error {
- return ks.keystore.Update(account.account, passphrase, newPassphrase)
-}
-
-// ExportKey exports as a JSON key, encrypted with newPassphrase.
-func (ks *KeyStore) ExportKey(account *Account, passphrase, newPassphrase string) (key []byte, _ error) {
- return ks.keystore.Export(account.account, passphrase, newPassphrase)
-}
-
-// ImportKey stores the given encrypted JSON key into the key directory.
-func (ks *KeyStore) ImportKey(keyJSON []byte, passphrase, newPassphrase string) (account *Account, _ error) {
- acc, err := ks.keystore.Import(common.CopyBytes(keyJSON), passphrase, newPassphrase)
- if err != nil {
- return nil, err
- }
- return &Account{acc}, nil
-}
-
-// ImportECDSAKey stores the given encrypted JSON key into the key directory.
-func (ks *KeyStore) ImportECDSAKey(key []byte, passphrase string) (account *Account, _ error) {
- privkey, err := crypto.ToECDSA(common.CopyBytes(key))
- if err != nil {
- return nil, err
- }
- acc, err := ks.keystore.ImportECDSA(privkey, passphrase)
- if err != nil {
- return nil, err
- }
- return &Account{acc}, nil
-}
-
-// ImportPreSaleKey decrypts the given Ethereum presale wallet and stores
-// a key file in the key directory. The key file is encrypted with the same passphrase.
-func (ks *KeyStore) ImportPreSaleKey(keyJSON []byte, passphrase string) (ccount *Account, _ error) {
- account, err := ks.keystore.ImportPreSaleKey(common.CopyBytes(keyJSON), passphrase)
- if err != nil {
- return nil, err
- }
- return &Account{account}, nil
-}
diff --git a/mobile/android_test.go b/mobile/android_test.go
deleted file mode 100644
index 345e009b4118..000000000000
--- a/mobile/android_test.go
+++ /dev/null
@@ -1,261 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package geth
-
-import (
- "io/ioutil"
- "os"
- "os/exec"
- "path/filepath"
- "runtime"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/internal/build"
-)
-
-// androidTestClass is a Java class to do some lightweight tests against the Android
-// bindings. The goal is not to test each individual functionality, rather just to
-// catch breaking API and/or implementation changes.
-const androidTestClass = `
-package go;
-
-import android.test.InstrumentationTestCase;
-import android.test.MoreAsserts;
-
-import java.math.BigInteger;
-import java.util.Arrays;
-
-import org.ethereum.geth.*;
-
-public class AndroidTest extends InstrumentationTestCase {
- public AndroidTest() {}
-
- public void testAccountManagement() {
- // Create an encrypted keystore with light crypto parameters.
- KeyStore ks = new KeyStore(getInstrumentation().getContext().getFilesDir() + "/keystore", Geth.LightScryptN, Geth.LightScryptP);
-
- try {
- // Create a new account with the specified encryption passphrase.
- Account newAcc = ks.newAccount("Creation password");
-
- // Export the newly created account with a different passphrase. The returned
- // data from this method invocation is a JSON encoded, encrypted key-file.
- byte[] jsonAcc = ks.exportKey(newAcc, "Creation password", "Export password");
-
- // Update the passphrase on the account created above inside the local keystore.
- ks.updateAccount(newAcc, "Creation password", "Update password");
-
- // Delete the account updated above from the local keystore.
- ks.deleteAccount(newAcc, "Update password");
-
- // Import back the account we've exported (and then deleted) above with yet
- // again a fresh passphrase.
- Account impAcc = ks.importKey(jsonAcc, "Export password", "Import password");
-
- // Create a new account to sign transactions with
- Account signer = ks.newAccount("Signer password");
-
- Transaction tx = new Transaction(
- 1, new Address("0x0000000000000000000000000000000000000000"),
- new BigInt(0), new BigInt(0), new BigInt(1), null); // Random empty transaction
- BigInt chain = new BigInt(1); // Chain identifier of the main net
-
- // Sign a transaction with a single authorization
- Transaction signed = ks.signTxPassphrase(signer, "Signer password", tx, chain);
-
- // Sign a transaction with multiple manually cancelled authorizations
- ks.unlock(signer, "Signer password");
- signed = ks.signTx(signer, tx, chain);
- ks.lock(signer.getAddress());
-
- // Sign a transaction with multiple automatically cancelled authorizations
- ks.timedUnlock(signer, "Signer password", 1000000000);
- signed = ks.signTx(signer, tx, chain);
- } catch (Exception e) {
- fail(e.toString());
- }
- }
-
- public void testInprocNode() {
- Context ctx = new Context();
-
- try {
- // Start up a new inprocess node
- Node node = new Node(getInstrumentation().getContext().getFilesDir() + "/.ethereum", new NodeConfig());
- node.start();
-
- // Retrieve some data via function calls (we don't really care about the results)
- NodeInfo info = node.getNodeInfo();
- info.getName();
- info.getListenerAddress();
- info.getProtocols();
-
- // Retrieve some data via the APIs (we don't really care about the results)
- EthereumClient ec = node.getEthereumClient();
- ec.getBlockByNumber(ctx, -1).getNumber();
-
- NewHeadHandler handler = new NewHeadHandler() {
- @Override public void onError(String error) {}
- @Override public void onNewHead(final Header header) {}
- };
- ec.subscribeNewHead(ctx, handler, 16);
- } catch (Exception e) {
- fail(e.toString());
- }
- }
-
- // Tests that recovering transaction signers works for both Homestead and EIP155
- // signatures too. Regression test for go-ethereum issue #14599.
- public void testIssue14599() {
- try {
- byte[] preEIP155RLP = new BigInteger("f901fc8032830138808080b901ae60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b561ca0c5689ed1ad124753d54576dfb4b571465a41900a1dff4058d8adf16f752013d0a01221cbd70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884", 16).toByteArray();
- preEIP155RLP = Arrays.copyOfRange(preEIP155RLP, 1, preEIP155RLP.length);
-
- byte[] postEIP155RLP = new BigInteger("f86b80847735940082520894ef5bbb9bba2e1ca69ef81b23a8727d889f3ef0a1880de0b6b3a7640000802ba06fef16c44726a102e6d55a651740636ef8aec6df3ebf009e7b0c1f29e4ac114aa057e7fbc69760b522a78bb568cfc37a58bfdcf6ea86cb8f9b550263f58074b9cc", 16).toByteArray();
- postEIP155RLP = Arrays.copyOfRange(postEIP155RLP, 1, postEIP155RLP.length);
-
- Transaction preEIP155 = new Transaction(preEIP155RLP);
- Transaction postEIP155 = new Transaction(postEIP155RLP);
-
- preEIP155.getFrom(null); // Homestead should accept homestead
- preEIP155.getFrom(new BigInt(4)); // EIP155 should accept homestead (missing chain ID)
- postEIP155.getFrom(new BigInt(4)); // EIP155 should accept EIP 155
-
- try {
- postEIP155.getFrom(null);
- fail("EIP155 transaction accepted by Homestead");
- } catch (Exception e) {}
- } catch (Exception e) {
- fail(e.toString());
- }
- }
-}
-`
-
-// TestAndroid runs the Android java test class specified above.
-//
-// This requires the gradle command in PATH and the Android SDK whose path is available
-// through ANDROID_HOME environment variable. To successfully run the tests, an Android
-// device must also be available with debugging enabled.
-//
-// This method has been adapted from golang.org/x/mobile/bind/java/seq_test.go/runTest
-func TestAndroid(t *testing.T) {
- // Skip tests on Windows altogether
- if runtime.GOOS == "windows" {
- t.Skip("cannot test Android bindings on Windows, skipping")
- }
- // Make sure all the Android tools are installed
- if _, err := exec.Command("which", "gradle").CombinedOutput(); err != nil {
- t.Skip("command gradle not found, skipping")
- }
- if sdk := os.Getenv("ANDROID_HOME"); sdk == "" {
- t.Skip("ANDROID_HOME environment var not set, skipping")
- }
- if _, err := exec.Command("which", "gomobile").CombinedOutput(); err != nil {
- t.Log("gomobile missing, installing it...")
- if _, err := exec.Command("go", "install", "golang.org/x/mobile/cmd/gomobile").CombinedOutput(); err != nil {
- t.Fatalf("install failed: %v", err)
- }
- t.Log("initializing gomobile...")
- start := time.Now()
- if _, err := exec.Command("gomobile", "init").CombinedOutput(); err != nil {
- t.Fatalf("initialization failed: %v", err)
- }
- t.Logf("initialization took %v", time.Since(start))
- }
- // Create and switch to a temporary workspace
- workspace, err := ioutil.TempDir("", "geth-android-")
- if err != nil {
- t.Fatalf("failed to create temporary workspace: %v", err)
- }
- defer os.RemoveAll(workspace)
-
- pwd, err := os.Getwd()
- if err != nil {
- t.Fatalf("failed to get current working directory: %v", err)
- }
- if err := os.Chdir(workspace); err != nil {
- t.Fatalf("failed to switch to temporary workspace: %v", err)
- }
- defer os.Chdir(pwd)
-
- // Create the skeleton of the Android project
- for _, dir := range []string{"src/main", "src/androidTest/java/org/ethereum/gethtest", "libs"} {
- err = os.MkdirAll(dir, os.ModePerm)
- if err != nil {
- t.Fatal(err)
- }
- }
- // Generate the mobile bindings for Geth and add the tester class
- gobind := exec.Command("gomobile", "bind", "-javapkg", "org.ethereum", "github.com/ethereum/go-ethereum/mobile")
- if output, err := gobind.CombinedOutput(); err != nil {
- t.Logf("%s", output)
- t.Fatalf("failed to run gomobile bind: %v", err)
- }
- build.CopyFile(filepath.Join("libs", "geth.aar"), "geth.aar", os.ModePerm)
-
- if err = ioutil.WriteFile(filepath.Join("src", "androidTest", "java", "org", "ethereum", "gethtest", "AndroidTest.java"), []byte(androidTestClass), os.ModePerm); err != nil {
- t.Fatalf("failed to write Android test class: %v", err)
- }
- // Finish creating the project and run the tests via gradle
- if err = ioutil.WriteFile(filepath.Join("src", "main", "AndroidManifest.xml"), []byte(androidManifest), os.ModePerm); err != nil {
- t.Fatalf("failed to write Android manifest: %v", err)
- }
- if err = ioutil.WriteFile("build.gradle", []byte(gradleConfig), os.ModePerm); err != nil {
- t.Fatalf("failed to write gradle build file: %v", err)
- }
- if output, err := exec.Command("gradle", "connectedAndroidTest").CombinedOutput(); err != nil {
- t.Logf("%s", output)
- t.Errorf("failed to run gradle test: %v", err)
- }
-}
-
-const androidManifest = `
-
-
-
-`
-
-const gradleConfig = `buildscript {
- repositories {
- jcenter()
- }
- dependencies {
- classpath 'com.android.tools.build:gradle:1.5.0'
- }
-}
-allprojects {
- repositories { jcenter() }
-}
-apply plugin: 'com.android.library'
-android {
- compileSdkVersion 'android-19'
- buildToolsVersion '21.1.2'
- defaultConfig { minSdkVersion 15 }
-}
-repositories {
- flatDir { dirs 'libs' }
-}
-dependencies {
- compile 'com.android.support:appcompat-v7:19.0.0'
- compile(name: "geth", ext: "aar")
-}
-`
diff --git a/mobile/big.go b/mobile/big.go
deleted file mode 100644
index 564fbad47c4f..000000000000
--- a/mobile/big.go
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains all the wrappers from the math/big package.
-
-package geth
-
-import (
- "errors"
- "math/big"
-
- "github.com/ethereum/go-ethereum/common"
-)
-
-// A BigInt represents a signed multi-precision integer.
-type BigInt struct {
- bigint *big.Int
-}
-
-// NewBigInt allocates and returns a new BigInt set to x.
-func NewBigInt(x int64) *BigInt {
- return &BigInt{big.NewInt(x)}
-}
-
-// GetBytes returns the absolute value of x as a big-endian byte slice.
-func (bi *BigInt) GetBytes() []byte {
- return bi.bigint.Bytes()
-}
-
-// String returns the value of x as a formatted decimal string.
-func (bi *BigInt) String() string {
- return bi.bigint.String()
-}
-
-// GetInt64 returns the int64 representation of x. If x cannot be represented in
-// an int64, the result is undefined.
-func (bi *BigInt) GetInt64() int64 {
- return bi.bigint.Int64()
-}
-
-// SetBytes interprets buf as the bytes of a big-endian unsigned integer and sets
-// the big int to that value.
-func (bi *BigInt) SetBytes(buf []byte) {
- bi.bigint.SetBytes(common.CopyBytes(buf))
-}
-
-// SetInt64 sets the big int to x.
-func (bi *BigInt) SetInt64(x int64) {
- bi.bigint.SetInt64(x)
-}
-
-// SetString sets the big int to x.
-//
-// The string prefix determines the actual conversion base. A prefix of "0x" or
-// "0X" selects base 16; the "0" prefix selects base 8, and a "0b" or "0B" prefix
-// selects base 2. Otherwise the selected base is 10.
-func (bi *BigInt) SetString(x string, base int) {
- bi.bigint.SetString(x, base)
-}
-
-// BigInts represents a slice of big ints.
-type BigInts struct{ bigints []*big.Int }
-
-// Size returns the number of big ints in the slice.
-func (bi *BigInts) Size() int {
- return len(bi.bigints)
-}
-
-// Get returns the bigint at the given index from the slice.
-func (bi *BigInts) Get(index int) (bigint *BigInt, _ error) {
- if index < 0 || index >= len(bi.bigints) {
- return nil, errors.New("index out of bounds")
- }
- return &BigInt{bi.bigints[index]}, nil
-}
-
-// Set sets the big int at the given index in the slice.
-func (bi *BigInts) Set(index int, bigint *BigInt) error {
- if index < 0 || index >= len(bi.bigints) {
- return errors.New("index out of bounds")
- }
- bi.bigints[index] = bigint.bigint
- return nil
-}
-
-// GetString returns the value of x as a formatted string in some number base.
-func (bi *BigInt) GetString(base int) string {
- return bi.bigint.Text(base)
-}
diff --git a/mobile/bind.go b/mobile/bind.go
deleted file mode 100644
index 7b79bedafd9c..000000000000
--- a/mobile/bind.go
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains all the wrappers from the bind package.
-
-package geth
-
-import (
- "math/big"
- "strings"
-
- "github.com/ethereum/go-ethereum/accounts/abi"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
-)
-
-// Signer is an interaface defining the callback when a contract requires a
-// method to sign the transaction before submission.
-type Signer interface {
- Sign(*Address, *Transaction) (tx *Transaction, _ error)
-}
-
-type signer struct {
- sign bind.SignerFn
-}
-
-func (s *signer) Sign(addr *Address, unsignedTx *Transaction) (signedTx *Transaction, _ error) {
- sig, err := s.sign(types.HomesteadSigner{}, addr.address, unsignedTx.tx)
- if err != nil {
- return nil, err
- }
- return &Transaction{sig}, nil
-}
-
-// CallOpts is the collection of options to fine tune a contract call request.
-type CallOpts struct {
- opts bind.CallOpts
-}
-
-// NewCallOpts creates a new option set for contract calls.
-func NewCallOpts() *CallOpts {
- return new(CallOpts)
-}
-
-func (opts *CallOpts) IsPending() bool { return opts.opts.Pending }
-func (opts *CallOpts) GetGasLimit() int64 { return 0 /* TODO(karalabe) */ }
-
-// GetContext cannot be reliably implemented without identity preservation (https://github.com/golang/go/issues/16876)
-// Even then it's awkward to unpack the subtleties of a Go context out to Java.
-// func (opts *CallOpts) GetContext() *Context { return &Context{opts.opts.Context} }
-
-func (opts *CallOpts) SetPending(pending bool) { opts.opts.Pending = pending }
-func (opts *CallOpts) SetGasLimit(limit int64) { /* TODO(karalabe) */ }
-func (opts *CallOpts) SetContext(context *Context) { opts.opts.Context = context.context }
-
-// TransactOpts is the collection of authorization data required to create a
-// valid Ethereum transaction.
-type TransactOpts struct {
- opts bind.TransactOpts
-}
-
-func (opts *TransactOpts) GetFrom() *Address { return &Address{opts.opts.From} }
-func (opts *TransactOpts) GetNonce() int64 { return opts.opts.Nonce.Int64() }
-func (opts *TransactOpts) GetValue() *BigInt { return &BigInt{opts.opts.Value} }
-func (opts *TransactOpts) GetGasPrice() *BigInt { return &BigInt{opts.opts.GasPrice} }
-func (opts *TransactOpts) GetGasLimit() int64 { return opts.opts.GasLimit.Int64() }
-
-// GetSigner cannot be reliably implemented without identity preservation (https://github.com/golang/go/issues/16876)
-// func (opts *TransactOpts) GetSigner() Signer { return &signer{opts.opts.Signer} }
-
-// GetContext cannot be reliably implemented without identity preservation (https://github.com/golang/go/issues/16876)
-// Even then it's awkward to unpack the subtleties of a Go context out to Java.
-//func (opts *TransactOpts) GetContext() *Context { return &Context{opts.opts.Context} }
-
-func (opts *TransactOpts) SetFrom(from *Address) { opts.opts.From = from.address }
-func (opts *TransactOpts) SetNonce(nonce int64) { opts.opts.Nonce = big.NewInt(nonce) }
-func (opts *TransactOpts) SetSigner(s Signer) {
- opts.opts.Signer = func(signer types.Signer, addr common.Address, tx *types.Transaction) (*types.Transaction, error) {
- sig, err := s.Sign(&Address{addr}, &Transaction{tx})
- if err != nil {
- return nil, err
- }
- return sig.tx, nil
- }
-}
-func (opts *TransactOpts) SetValue(value *BigInt) { opts.opts.Value = value.bigint }
-func (opts *TransactOpts) SetGasPrice(price *BigInt) { opts.opts.GasPrice = price.bigint }
-func (opts *TransactOpts) SetGasLimit(limit int64) { opts.opts.GasLimit = big.NewInt(limit) }
-func (opts *TransactOpts) SetContext(context *Context) { opts.opts.Context = context.context }
-
-// BoundContract is the base wrapper object that reflects a contract on the
-// Ethereum network. It contains a collection of methods that are used by the
-// higher level contract bindings to operate.
-type BoundContract struct {
- contract *bind.BoundContract
- address common.Address
- deployer *types.Transaction
-}
-
-// DeployContract deploys a contract onto the Ethereum blockchain and binds the
-// deployment address with a wrapper.
-func DeployContract(opts *TransactOpts, abiJSON string, bytecode []byte, client *EthereumClient, args *Interfaces) (contract *BoundContract, _ error) {
- // Deploy the contract to the network
- parsed, err := abi.JSON(strings.NewReader(abiJSON))
- if err != nil {
- return nil, err
- }
- addr, tx, bound, err := bind.DeployContract(&opts.opts, parsed, common.CopyBytes(bytecode), client.client, args.objects...)
- if err != nil {
- return nil, err
- }
- return &BoundContract{
- contract: bound,
- address: addr,
- deployer: tx,
- }, nil
-}
-
-// BindContract creates a low level contract interface through which calls and
-// transactions may be made through.
-func BindContract(address *Address, abiJSON string, client *EthereumClient) (contract *BoundContract, _ error) {
- parsed, err := abi.JSON(strings.NewReader(abiJSON))
- if err != nil {
- return nil, err
- }
- return &BoundContract{
- contract: bind.NewBoundContract(address.address, parsed, client.client, client.client),
- address: address.address,
- }, nil
-}
-
-func (c *BoundContract) GetAddress() *Address { return &Address{c.address} }
-func (c *BoundContract) GetDeployer() *Transaction {
- if c.deployer == nil {
- return nil
- }
- return &Transaction{c.deployer}
-}
-
-// Call invokes the (constant) contract method with params as input values and
-// sets the output to result.
-func (c *BoundContract) Call(opts *CallOpts, out *Interfaces, method string, args *Interfaces) error {
- results := make([]interface{}, len(out.objects))
- copy(results, out.objects)
- if err := c.contract.Call(&opts.opts, &results, method, args.objects...); err != nil {
- return err
- }
- copy(out.objects, results)
- return nil
-}
-
-// Transact invokes the (paid) contract method with params as input values.
-func (c *BoundContract) Transact(opts *TransactOpts, method string, args *Interfaces) (tx *Transaction, _ error) {
- rawTx, err := c.contract.Transact(&opts.opts, method, args.objects...)
- if err != nil {
- return nil, err
- }
- return &Transaction{rawTx}, nil
-}
-
-// Transfer initiates a plain transaction to move funds to the contract, calling
-// its default method if one is available.
-func (c *BoundContract) Transfer(opts *TransactOpts) (tx *Transaction, _ error) {
- rawTx, err := c.contract.Transfer(&opts.opts)
- if err != nil {
- return nil, err
- }
- return &Transaction{rawTx}, nil
-}
diff --git a/mobile/common.go b/mobile/common.go
deleted file mode 100644
index 047d8e1f65c7..000000000000
--- a/mobile/common.go
+++ /dev/null
@@ -1,230 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains all the wrappers from the common package.
-
-package geth
-
-import (
- "encoding/hex"
- "errors"
- "fmt"
- "strings"
-
- "github.com/ethereum/go-ethereum/common"
-)
-
-// Hash represents the 32 byte Keccak256 hash of arbitrary data.
-type Hash struct {
- hash common.Hash
-}
-
-// NewHashFromBytes converts a slice of bytes to a hash value.
-func NewHashFromBytes(binary []byte) (hash *Hash, _ error) {
- h := new(Hash)
- if err := h.SetBytes(common.CopyBytes(binary)); err != nil {
- return nil, err
- }
- return h, nil
-}
-
-// NewHashFromHex converts a hex string to a hash value.
-func NewHashFromHex(hex string) (hash *Hash, _ error) {
- h := new(Hash)
- if err := h.SetHex(hex); err != nil {
- return nil, err
- }
- return h, nil
-}
-
-// SetBytes sets the specified slice of bytes as the hash value.
-func (h *Hash) SetBytes(hash []byte) error {
- if length := len(hash); length != common.HashLength {
- return fmt.Errorf("invalid hash length: %v != %v", length, common.HashLength)
- }
- copy(h.hash[:], hash)
- return nil
-}
-
-// GetBytes retrieves the byte representation of the hash.
-func (h *Hash) GetBytes() []byte {
- return h.hash[:]
-}
-
-// SetHex sets the specified hex string as the hash value.
-func (h *Hash) SetHex(hash string) error {
- hash = strings.ToLower(hash)
- if len(hash) >= 2 && hash[:2] == "0x" {
- hash = hash[2:]
- }
- if length := len(hash); length != 2*common.HashLength {
- return fmt.Errorf("invalid hash hex length: %v != %v", length, 2*common.HashLength)
- }
- bin, err := hex.DecodeString(hash)
- if err != nil {
- return err
- }
- copy(h.hash[:], bin)
- return nil
-}
-
-// GetHex retrieves the hex string representation of the hash.
-func (h *Hash) GetHex() string {
- return h.hash.Hex()
-}
-
-// Hashes represents a slice of hashes.
-type Hashes struct{ hashes []common.Hash }
-
-// NewHashes creates a slice of uninitialized Hashes.
-func NewHashes(size int) *Hashes {
- return &Hashes{
- hashes: make([]common.Hash, size),
- }
-}
-
-// NewHashesEmpty creates an empty slice of Hashes values.
-func NewHashesEmpty() *Hashes {
- return NewHashes(0)
-}
-
-// Size returns the number of hashes in the slice.
-func (h *Hashes) Size() int {
- return len(h.hashes)
-}
-
-// Get returns the hash at the given index from the slice.
-func (h *Hashes) Get(index int) (hash *Hash, _ error) {
- if index < 0 || index >= len(h.hashes) {
- return nil, errors.New("index out of bounds")
- }
- return &Hash{h.hashes[index]}, nil
-}
-
-// Set sets the Hash at the given index in the slice.
-func (h *Hashes) Set(index int, hash *Hash) error {
- if index < 0 || index >= len(h.hashes) {
- return errors.New("index out of bounds")
- }
- h.hashes[index] = hash.hash
- return nil
-}
-
-// Append adds a new Hash element to the end of the slice.
-func (h *Hashes) Append(hash *Hash) {
- h.hashes = append(h.hashes, hash.hash)
-}
-
-// Address represents the 20 byte address of an Ethereum account.
-type Address struct {
- address common.Address
-}
-
-// NewAddressFromBytes converts a slice of bytes to a hash value.
-func NewAddressFromBytes(binary []byte) (address *Address, _ error) {
- a := new(Address)
- if err := a.SetBytes(common.CopyBytes(binary)); err != nil {
- return nil, err
- }
- return a, nil
-}
-
-// NewAddressFromHex converts a hex string to a address value.
-func NewAddressFromHex(hex string) (address *Address, _ error) {
- a := new(Address)
- if err := a.SetHex(hex); err != nil {
- return nil, err
- }
- return a, nil
-}
-
-// SetBytes sets the specified slice of bytes as the address value.
-func (a *Address) SetBytes(address []byte) error {
- if length := len(address); length != common.AddressLength {
- return fmt.Errorf("invalid address length: %v != %v", length, common.AddressLength)
- }
- copy(a.address[:], address)
- return nil
-}
-
-// GetBytes retrieves the byte representation of the address.
-func (a *Address) GetBytes() []byte {
- return a.address[:]
-}
-
-// SetHex sets the specified hex string as the address value.
-func (a *Address) SetHex(address string) error {
- address = strings.ToLower(address)
- if len(address) >= 2 && address[:2] == "0x" {
- address = address[2:]
- }
- if length := len(address); length != 2*common.AddressLength {
- return fmt.Errorf("invalid address hex length: %v != %v", length, 2*common.AddressLength)
- }
- bin, err := hex.DecodeString(address)
- if err != nil {
- return err
- }
- copy(a.address[:], bin)
- return nil
-}
-
-// GetHex retrieves the hex string representation of the address.
-func (a *Address) GetHex() string {
- return a.address.Hex()
-}
-
-// Addresses represents a slice of addresses.
-type Addresses struct{ addresses []common.Address }
-
-// NewAddresses creates a slice of uninitialized addresses.
-func NewAddresses(size int) *Addresses {
- return &Addresses{
- addresses: make([]common.Address, size),
- }
-}
-
-// NewAddressesEmpty creates an empty slice of Addresses values.
-func NewAddressesEmpty() *Addresses {
- return NewAddresses(0)
-}
-
-// Size returns the number of addresses in the slice.
-func (a *Addresses) Size() int {
- return len(a.addresses)
-}
-
-// Get returns the address at the given index from the slice.
-func (a *Addresses) Get(index int) (address *Address, _ error) {
- if index < 0 || index >= len(a.addresses) {
- return nil, errors.New("index out of bounds")
- }
- return &Address{a.addresses[index]}, nil
-}
-
-// Set sets the address at the given index in the slice.
-func (a *Addresses) Set(index int, address *Address) error {
- if index < 0 || index >= len(a.addresses) {
- return errors.New("index out of bounds")
- }
- a.addresses[index] = address.address
- return nil
-}
-
-// Append adds a new address element to the end of the slice.
-func (a *Addresses) Append(address *Address) {
- a.addresses = append(a.addresses, address.address)
-}
diff --git a/mobile/context.go b/mobile/context.go
deleted file mode 100644
index f1fff9011471..000000000000
--- a/mobile/context.go
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains all the wrappers from the golang.org/x/net/context package to support
-// client side context management on mobile platforms.
-
-package geth
-
-import (
- "context"
- "time"
-)
-
-// Context carries a deadline, a cancelation signal, and other values across API
-// boundaries.
-type Context struct {
- context context.Context
- cancel context.CancelFunc
-}
-
-// NewContext returns a non-nil, empty Context. It is never canceled, has no
-// values, and has no deadline. It is typically used by the main function,
-// initialization, and tests, and as the top-level Context for incoming requests.
-func NewContext() *Context {
- return &Context{
- context: context.Background(),
- }
-}
-
-// WithCancel returns a copy of the original context with cancellation mechanism
-// included.
-//
-// Canceling this context releases resources associated with it, so code should
-// call cancel as soon as the operations running in this Context complete.
-func (c *Context) WithCancel() *Context {
- child, cancel := context.WithCancel(c.context)
- return &Context{
- context: child,
- cancel: cancel,
- }
-}
-
-// WithDeadline returns a copy of the original context with the deadline adjusted
-// to be no later than the specified time.
-//
-// Canceling this context releases resources associated with it, so code should
-// call cancel as soon as the operations running in this Context complete.
-func (c *Context) WithDeadline(sec int64, nsec int64) *Context {
- child, cancel := context.WithDeadline(c.context, time.Unix(sec, nsec))
- return &Context{
- context: child,
- cancel: cancel,
- }
-}
-
-// WithTimeout returns a copy of the original context with the deadline adjusted
-// to be no later than now + the duration specified.
-//
-// Canceling this context releases resources associated with it, so code should
-// call cancel as soon as the operations running in this Context complete.
-func (c *Context) WithTimeout(nsec int64) *Context {
- child, cancel := context.WithTimeout(c.context, time.Duration(nsec))
- return &Context{
- context: child,
- cancel: cancel,
- }
-}
diff --git a/mobile/discover.go b/mobile/discover.go
deleted file mode 100644
index 9b3c93ccd98f..000000000000
--- a/mobile/discover.go
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains all the wrappers from the accounts package to support client side enode
-// management on mobile platforms.
-
-package geth
-
-import (
- "errors"
-
- "github.com/ethereum/go-ethereum/p2p/discv5"
-)
-
-// Enode represents a host on the network.
-type Enode struct {
- node *discv5.Node
-}
-
-// NewEnode parses a node designator.
-//
-// There are two basic forms of node designators
-// - incomplete nodes, which only have the public key (node ID)
-// - complete nodes, which contain the public key and IP/Port information
-//
-// For incomplete nodes, the designator must look like one of these
-//
-// enode://
-//
-//
-// For complete nodes, the node ID is encoded in the username portion
-// of the URL, separated from the host by an @ sign. The hostname can
-// only be given as an IP address, DNS domain names are not allowed.
-// The port in the host name section is the TCP listening port. If the
-// TCP and UDP (discovery) ports differ, the UDP port is specified as
-// query parameter "discport".
-//
-// In the following example, the node URL describes
-// a node with IP address 10.3.58.6, TCP listening port 30303
-// and UDP discovery port 30301.
-//
-// enode://@10.3.58.6:30303?discport=30301
-func NewEnode(rawurl string) (enode *Enode, _ error) {
- node, err := discv5.ParseNode(rawurl)
- if err != nil {
- return nil, err
- }
- return &Enode{node}, nil
-}
-
-// Enodes represents a slice of accounts.
-type Enodes struct{ nodes []*discv5.Node }
-
-// NewEnodes creates a slice of uninitialized enodes.
-func NewEnodes(size int) *Enodes {
- return &Enodes{
- nodes: make([]*discv5.Node, size),
- }
-}
-
-// NewEnodesEmpty creates an empty slice of Enode values.
-func NewEnodesEmpty() *Enodes {
- return NewEnodes(0)
-}
-
-// Size returns the number of enodes in the slice.
-func (e *Enodes) Size() int {
- return len(e.nodes)
-}
-
-// Get returns the enode at the given index from the slice.
-func (e *Enodes) Get(index int) (enode *Enode, _ error) {
- if index < 0 || index >= len(e.nodes) {
- return nil, errors.New("index out of bounds")
- }
- return &Enode{e.nodes[index]}, nil
-}
-
-// Set sets the enode at the given index in the slice.
-func (e *Enodes) Set(index int, enode *Enode) error {
- if index < 0 || index >= len(e.nodes) {
- return errors.New("index out of bounds")
- }
- e.nodes[index] = enode.node
- return nil
-}
-
-// Append adds a new enode element to the end of the slice.
-func (e *Enodes) Append(enode *Enode) {
- e.nodes = append(e.nodes, enode.node)
-}
diff --git a/mobile/doc.go b/mobile/doc.go
deleted file mode 100644
index 64d47bec2a2a..000000000000
--- a/mobile/doc.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Package geth contains the simplified mobile APIs to go-ethereum.
-//
-// The scope of this package is *not* to allow writing a custom Ethereum client
-// with pieces plucked from go-ethereum, rather to allow writing native dapps on
-// mobile platforms. Keep this in mind when using or extending this package!
-//
-// API limitations
-//
-// Since gomobile cannot bridge arbitrary types between Go and Android/iOS, the
-// exposed APIs need to be manually wrapped into simplified types, with custom
-// constructors and getters/setters to ensure that they can be meaninfully used
-// from Java/ObjC too.
-//
-// With this in mind, please try to limit the scope of this package and only add
-// essentials without which mobile support cannot work, especially since manually
-// syncing the code will be unwieldy otherwise. In the long term we might consider
-// writing custom library generators, but those are out of scope now.
-//
-// Content wise each file in this package corresponds to an entire Go package
-// from the go-ethereum repository. Please adhere to this scoping to prevent this
-// package getting unmaintainable.
-//
-// Wrapping guidelines:
-//
-// Every type that is to be exposed should be wrapped into its own plain struct,
-// which internally contains a single field: the original go-ethereum version.
-// This is needed because gomobile cannot expose named types for now.
-//
-// Whenever a method argument or a return type is a custom struct, the pointer
-// variant should always be used as value types crossing over between language
-// boundaries might have strange behaviors.
-//
-// Slices of types should be converted into a single multiplicative type wrapping
-// a go slice with the methods `Size`, `Get` and `Set`. Further slice operations
-// should not be provided to limit the remote code complexity. Arrays should be
-// avoided as much as possible since they complicate bounds checking.
-//
-// If a method has multiple return values (e.g. some return + an error), those
-// are generated as output arguments in ObjC. To avoid weird generated names like
-// ret_0 for them, please always assign names to output variables if tuples.
-//
-// Note, a panic *cannot* cross over language boundaries, instead will result in
-// an undebuggable SEGFAULT in the process. For error handling only ever use error
-// returns, which may be the only or the second return.
-package geth
diff --git a/mobile/ethclient.go b/mobile/ethclient.go
deleted file mode 100644
index 758863b6d90f..000000000000
--- a/mobile/ethclient.go
+++ /dev/null
@@ -1,312 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains a wrapper for the Ethereum client.
-
-package geth
-
-import (
- "math/big"
-
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethclient"
-)
-
-// EthereumClient provides access to the Ethereum APIs.
-type EthereumClient struct {
- client *ethclient.Client
-}
-
-// NewEthereumClient connects a client to the given URL.
-func NewEthereumClient(rawurl string) (client *EthereumClient, _ error) {
- rawClient, err := ethclient.Dial(rawurl)
- return &EthereumClient{rawClient}, err
-}
-
-// GetBlockByHash returns the given full block.
-func (ec *EthereumClient) GetBlockByHash(ctx *Context, hash *Hash) (block *Block, _ error) {
- rawBlock, err := ec.client.BlockByHash(ctx.context, hash.hash)
- return &Block{rawBlock}, err
-}
-
-// GetBlockByNumber returns a block from the current canonical chain. If number is <0, the
-// latest known block is returned.
-func (ec *EthereumClient) GetBlockByNumber(ctx *Context, number int64) (block *Block, _ error) {
- if number < 0 {
- rawBlock, err := ec.client.BlockByNumber(ctx.context, nil)
- return &Block{rawBlock}, err
- }
- rawBlock, err := ec.client.BlockByNumber(ctx.context, big.NewInt(number))
- return &Block{rawBlock}, err
-}
-
-// GetHeaderByHash returns the block header with the given hash.
-func (ec *EthereumClient) GetHeaderByHash(ctx *Context, hash *Hash) (header *Header, _ error) {
- rawHeader, err := ec.client.HeaderByHash(ctx.context, hash.hash)
- return &Header{rawHeader}, err
-}
-
-// GetHeaderByNumber returns a block header from the current canonical chain. If number is <0,
-// the latest known header is returned.
-func (ec *EthereumClient) GetHeaderByNumber(ctx *Context, number int64) (header *Header, _ error) {
- if number < 0 {
- rawHeader, err := ec.client.HeaderByNumber(ctx.context, nil)
- return &Header{rawHeader}, err
- }
- rawHeader, err := ec.client.HeaderByNumber(ctx.context, big.NewInt(number))
- return &Header{rawHeader}, err
-}
-
-// GetTransactionByHash returns the transaction with the given hash.
-func (ec *EthereumClient) GetTransactionByHash(ctx *Context, hash *Hash) (tx *Transaction, _ error) {
- // TODO(karalabe): handle isPending
- rawTx, _, err := ec.client.TransactionByHash(ctx.context, hash.hash)
- return &Transaction{rawTx}, err
-}
-
-// GetTransactionSender returns the sender address of a transaction. The transaction must
-// be included in blockchain at the given block and index.
-func (ec *EthereumClient) GetTransactionSender(ctx *Context, tx *Transaction, blockhash *Hash, index int) (sender *Address, _ error) {
- addr, err := ec.client.TransactionSender(ctx.context, tx.tx, blockhash.hash, uint(index))
- return &Address{addr}, err
-}
-
-// GetTransactionCount returns the total number of transactions in the given block.
-func (ec *EthereumClient) GetTransactionCount(ctx *Context, hash *Hash) (count int, _ error) {
- rawCount, err := ec.client.TransactionCount(ctx.context, hash.hash)
- return int(rawCount), err
-}
-
-// GetTransactionInBlock returns a single transaction at index in the given block.
-func (ec *EthereumClient) GetTransactionInBlock(ctx *Context, hash *Hash, index int) (tx *Transaction, _ error) {
- rawTx, err := ec.client.TransactionInBlock(ctx.context, hash.hash, uint(index))
- return &Transaction{rawTx}, err
-
-}
-
-// GetTransactionReceipt returns the receipt of a transaction by transaction hash.
-// Note that the receipt is not available for pending transactions.
-func (ec *EthereumClient) GetTransactionReceipt(ctx *Context, hash *Hash) (receipt *Receipt, _ error) {
- rawReceipt, err := ec.client.TransactionReceipt(ctx.context, hash.hash)
- return &Receipt{rawReceipt}, err
-}
-
-// SyncProgress retrieves the current progress of the sync algorithm. If there's
-// no sync currently running, it returns nil.
-func (ec *EthereumClient) SyncProgress(ctx *Context) (progress *SyncProgress, _ error) {
- rawProgress, err := ec.client.SyncProgress(ctx.context)
- if rawProgress == nil {
- return nil, err
- }
- return &SyncProgress{*rawProgress}, err
-}
-
-// NewHeadHandler is a client-side subscription callback to invoke on events and
-// subscription failure.
-type NewHeadHandler interface {
- OnNewHead(header *Header)
- OnError(failure string)
-}
-
-// SubscribeNewHead subscribes to notifications about the current blockchain head
-// on the given channel.
-func (ec *EthereumClient) SubscribeNewHead(ctx *Context, handler NewHeadHandler, buffer int) (sub *Subscription, _ error) {
- // Subscribe to the event internally
- ch := make(chan *types.Header, buffer)
- rawSub, err := ec.client.SubscribeNewHead(ctx.context, ch)
- if err != nil {
- return nil, err
- }
- // Start up a dispatcher to feed into the callback
- go func() {
- for {
- select {
- case header := <-ch:
- handler.OnNewHead(&Header{header})
-
- case err := <-rawSub.Err():
- handler.OnError(err.Error())
- return
- }
- }
- }()
- return &Subscription{rawSub}, nil
-}
-
-// State Access
-
-// GetBalanceAt returns the wei balance of the given account.
-// The block number can be <0, in which case the balance is taken from the latest known block.
-func (ec *EthereumClient) GetBalanceAt(ctx *Context, account *Address, number int64) (balance *BigInt, _ error) {
- if number < 0 {
- rawBalance, err := ec.client.BalanceAt(ctx.context, account.address, nil)
- return &BigInt{rawBalance}, err
- }
- rawBalance, err := ec.client.BalanceAt(ctx.context, account.address, big.NewInt(number))
- return &BigInt{rawBalance}, err
-}
-
-// GetStorageAt returns the value of key in the contract storage of the given account.
-// The block number can be <0, in which case the value is taken from the latest known block.
-func (ec *EthereumClient) GetStorageAt(ctx *Context, account *Address, key *Hash, number int64) (storage []byte, _ error) {
- if number < 0 {
- return ec.client.StorageAt(ctx.context, account.address, key.hash, nil)
- }
- return ec.client.StorageAt(ctx.context, account.address, key.hash, big.NewInt(number))
-}
-
-// GetCodeAt returns the contract code of the given account.
-// The block number can be <0, in which case the code is taken from the latest known block.
-func (ec *EthereumClient) GetCodeAt(ctx *Context, account *Address, number int64) (code []byte, _ error) {
- if number < 0 {
- return ec.client.CodeAt(ctx.context, account.address, nil)
- }
- return ec.client.CodeAt(ctx.context, account.address, big.NewInt(number))
-}
-
-// GetNonceAt returns the account nonce of the given account.
-// The block number can be <0, in which case the nonce is taken from the latest known block.
-func (ec *EthereumClient) GetNonceAt(ctx *Context, account *Address, number int64) (nonce int64, _ error) {
- if number < 0 {
- rawNonce, err := ec.client.NonceAt(ctx.context, account.address, nil)
- return int64(rawNonce), err
- }
- rawNonce, err := ec.client.NonceAt(ctx.context, account.address, big.NewInt(number))
- return int64(rawNonce), err
-}
-
-// Filters
-
-// FilterLogs executes a filter query.
-func (ec *EthereumClient) FilterLogs(ctx *Context, query *FilterQuery) (logs *Logs, _ error) {
- rawLogs, err := ec.client.FilterLogs(ctx.context, query.query)
- if err != nil {
- return nil, err
- }
- // Temp hack due to vm.Logs being []*vm.Log
- res := make([]*types.Log, len(rawLogs))
- for i := range rawLogs {
- res[i] = &rawLogs[i]
- }
- return &Logs{res}, nil
-}
-
-// FilterLogsHandler is a client-side subscription callback to invoke on events and
-// subscription failure.
-type FilterLogsHandler interface {
- OnFilterLogs(log *Log)
- OnError(failure string)
-}
-
-// SubscribeFilterLogs subscribes to the results of a streaming filter query.
-func (ec *EthereumClient) SubscribeFilterLogs(ctx *Context, query *FilterQuery, handler FilterLogsHandler, buffer int) (sub *Subscription, _ error) {
- // Subscribe to the event internally
- ch := make(chan types.Log, buffer)
- rawSub, err := ec.client.SubscribeFilterLogs(ctx.context, query.query, ch)
- if err != nil {
- return nil, err
- }
- // Start up a dispatcher to feed into the callback
- go func() {
- for {
- select {
- case log := <-ch:
- handler.OnFilterLogs(&Log{&log})
-
- case err := <-rawSub.Err():
- handler.OnError(err.Error())
- return
- }
- }
- }()
- return &Subscription{rawSub}, nil
-}
-
-// Pending State
-
-// GetPendingBalanceAt returns the wei balance of the given account in the pending state.
-func (ec *EthereumClient) GetPendingBalanceAt(ctx *Context, account *Address) (balance *BigInt, _ error) {
- rawBalance, err := ec.client.PendingBalanceAt(ctx.context, account.address)
- return &BigInt{rawBalance}, err
-}
-
-// GetPendingStorageAt returns the value of key in the contract storage of the given account in the pending state.
-func (ec *EthereumClient) GetPendingStorageAt(ctx *Context, account *Address, key *Hash) (storage []byte, _ error) {
- return ec.client.PendingStorageAt(ctx.context, account.address, key.hash)
-}
-
-// GetPendingCodeAt returns the contract code of the given account in the pending state.
-func (ec *EthereumClient) GetPendingCodeAt(ctx *Context, account *Address) (code []byte, _ error) {
- return ec.client.PendingCodeAt(ctx.context, account.address)
-}
-
-// GetPendingNonceAt returns the account nonce of the given account in the pending state.
-// This is the nonce that should be used for the next transaction.
-func (ec *EthereumClient) GetPendingNonceAt(ctx *Context, account *Address) (nonce int64, _ error) {
- rawNonce, err := ec.client.PendingNonceAt(ctx.context, account.address)
- return int64(rawNonce), err
-}
-
-// GetPendingTransactionCount returns the total number of transactions in the pending state.
-func (ec *EthereumClient) GetPendingTransactionCount(ctx *Context) (count int, _ error) {
- rawCount, err := ec.client.PendingTransactionCount(ctx.context)
- return int(rawCount), err
-}
-
-// Contract Calling
-
-// CallContract executes a message call transaction, which is directly executed in the VM
-// of the node, but never mined into the blockchain.
-//
-// blockNumber selects the block height at which the call runs. It can be <0, in which
-// case the code is taken from the latest known block. Note that state from very old
-// blocks might not be available.
-func (ec *EthereumClient) CallContract(ctx *Context, msg *CallMsg, number int64) (output []byte, _ error) {
- if number < 0 {
- return ec.client.CallContract(ctx.context, msg.msg, nil)
- }
- return ec.client.CallContract(ctx.context, msg.msg, big.NewInt(number))
-}
-
-// PendingCallContract executes a message call transaction using the EVM.
-// The state seen by the contract call is the pending state.
-func (ec *EthereumClient) PendingCallContract(ctx *Context, msg *CallMsg) (output []byte, _ error) {
- return ec.client.PendingCallContract(ctx.context, msg.msg)
-}
-
-// SuggestGasPrice retrieves the currently suggested gas price to allow a timely
-// execution of a transaction.
-func (ec *EthereumClient) SuggestGasPrice(ctx *Context) (price *BigInt, _ error) {
- rawPrice, err := ec.client.SuggestGasPrice(ctx.context)
- return &BigInt{rawPrice}, err
-}
-
-// EstimateGas tries to estimate the gas needed to execute a specific transaction based on
-// the current pending state of the backend blockchain. There is no guarantee that this is
-// the true gas limit requirement as other transactions may be added or removed by miners,
-// but it should provide a basis for setting a reasonable default.
-func (ec *EthereumClient) EstimateGas(ctx *Context, msg *CallMsg) (gas *BigInt, _ error) {
- rawGas, err := ec.client.EstimateGas(ctx.context, msg.msg)
- return &BigInt{rawGas}, err
-}
-
-// SendTransaction injects a signed transaction into the pending pool for execution.
-//
-// If the transaction was a contract creation use the TransactionReceipt method to get the
-// contract address after the transaction has been mined.
-func (ec *EthereumClient) SendTransaction(ctx *Context, tx *Transaction) error {
- return ec.client.SendTransaction(ctx.context, tx.tx)
-}
diff --git a/mobile/ethereum.go b/mobile/ethereum.go
deleted file mode 100644
index c9bb3013c2c3..000000000000
--- a/mobile/ethereum.go
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains all the wrappers from the go-ethereum root package.
-
-package geth
-
-import (
- "errors"
- "math/big"
-
- ethereum "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/common"
-)
-
-// Subscription represents an event subscription where events are
-// delivered on a data channel.
-type Subscription struct {
- sub ethereum.Subscription
-}
-
-// Unsubscribe cancels the sending of events to the data channel
-// and closes the error channel.
-func (s *Subscription) Unsubscribe() {
- s.sub.Unsubscribe()
-}
-
-// CallMsg contains parameters for contract calls.
-type CallMsg struct {
- msg ethereum.CallMsg
-}
-
-// NewCallMsg creates an empty contract call parameter list.
-func NewCallMsg() *CallMsg {
- return new(CallMsg)
-}
-
-func (msg *CallMsg) GetFrom() *Address { return &Address{msg.msg.From} }
-func (msg *CallMsg) GetGas() int64 { return msg.msg.Gas.Int64() }
-func (msg *CallMsg) GetGasPrice() *BigInt { return &BigInt{msg.msg.GasPrice} }
-func (msg *CallMsg) GetValue() *BigInt { return &BigInt{msg.msg.Value} }
-func (msg *CallMsg) GetData() []byte { return msg.msg.Data }
-func (msg *CallMsg) GetTo() *Address {
- if to := msg.msg.To; to != nil {
- return &Address{*msg.msg.To}
- }
- return nil
-}
-
-func (msg *CallMsg) SetFrom(address *Address) { msg.msg.From = address.address }
-func (msg *CallMsg) SetGas(gas int64) { msg.msg.Gas = big.NewInt(gas) }
-func (msg *CallMsg) SetGasPrice(price *BigInt) { msg.msg.GasPrice = price.bigint }
-func (msg *CallMsg) SetValue(value *BigInt) { msg.msg.Value = value.bigint }
-func (msg *CallMsg) SetData(data []byte) { msg.msg.Data = common.CopyBytes(data) }
-func (msg *CallMsg) SetTo(address *Address) {
- if address == nil {
- msg.msg.To = nil
- }
- msg.msg.To = &address.address
-}
-
-// SyncProgress gives progress indications when the node is synchronising with
-// the Ethereum network.
-type SyncProgress struct {
- progress ethereum.SyncProgress
-}
-
-func (p *SyncProgress) GetStartingBlock() int64 { return int64(p.progress.StartingBlock) }
-func (p *SyncProgress) GetCurrentBlock() int64 { return int64(p.progress.CurrentBlock) }
-func (p *SyncProgress) GetHighestBlock() int64 { return int64(p.progress.HighestBlock) }
-func (p *SyncProgress) GetPulledStates() int64 { return int64(p.progress.PulledStates) }
-func (p *SyncProgress) GetKnownStates() int64 { return int64(p.progress.KnownStates) }
-
-// Topics is a set of topic lists to filter events with.
-type Topics struct{ topics [][]common.Hash }
-
-// NewTopics creates a slice of uninitialized Topics.
-func NewTopics(size int) *Topics {
- return &Topics{
- topics: make([][]common.Hash, size),
- }
-}
-
-// NewTopicsEmpty creates an empty slice of Topics values.
-func NewTopicsEmpty() *Topics {
- return NewTopics(0)
-}
-
-// Size returns the number of topic lists inside the set
-func (t *Topics) Size() int {
- return len(t.topics)
-}
-
-// Get returns the topic list at the given index from the slice.
-func (t *Topics) Get(index int) (hashes *Hashes, _ error) {
- if index < 0 || index >= len(t.topics) {
- return nil, errors.New("index out of bounds")
- }
- return &Hashes{t.topics[index]}, nil
-}
-
-// Set sets the topic list at the given index in the slice.
-func (t *Topics) Set(index int, topics *Hashes) error {
- if index < 0 || index >= len(t.topics) {
- return errors.New("index out of bounds")
- }
- t.topics[index] = topics.hashes
- return nil
-}
-
-// Append adds a new topic list to the end of the slice.
-func (t *Topics) Append(topics *Hashes) {
- t.topics = append(t.topics, topics.hashes)
-}
-
-// FilterQuery contains options for contact log filtering.
-type FilterQuery struct {
- query ethereum.FilterQuery
-}
-
-// NewFilterQuery creates an empty filter query for contact log filtering.
-func NewFilterQuery() *FilterQuery {
- return new(FilterQuery)
-}
-
-func (fq *FilterQuery) GetFromBlock() *BigInt { return &BigInt{fq.query.FromBlock} }
-func (fq *FilterQuery) GetToBlock() *BigInt { return &BigInt{fq.query.ToBlock} }
-func (fq *FilterQuery) GetAddresses() *Addresses { return &Addresses{fq.query.Addresses} }
-func (fq *FilterQuery) GetTopics() *Topics { return &Topics{fq.query.Topics} }
-
-func (fq *FilterQuery) SetFromBlock(fromBlock *BigInt) { fq.query.FromBlock = fromBlock.bigint }
-func (fq *FilterQuery) SetToBlock(toBlock *BigInt) { fq.query.ToBlock = toBlock.bigint }
-func (fq *FilterQuery) SetAddresses(addresses *Addresses) { fq.query.Addresses = addresses.addresses }
-func (fq *FilterQuery) SetTopics(topics *Topics) { fq.query.Topics = topics.topics }
diff --git a/mobile/geth.go b/mobile/geth.go
deleted file mode 100644
index 7b39faadecb0..000000000000
--- a/mobile/geth.go
+++ /dev/null
@@ -1,209 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains all the wrappers from the node package to support client side node
-// management on mobile platforms.
-
-package geth
-
-import (
- "encoding/json"
- "fmt"
- "path/filepath"
-
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/eth/downloader"
- "github.com/ethereum/go-ethereum/ethclient"
- "github.com/ethereum/go-ethereum/ethstats"
- "github.com/ethereum/go-ethereum/les"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/nat"
- "github.com/ethereum/go-ethereum/params"
- whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
-)
-
-// NodeConfig represents the collection of configuration values to fine tune the Geth
-// node embedded into a mobile process. The available values are a subset of the
-// entire API provided by go-ethereum to reduce the maintenance surface and dev
-// complexity.
-type NodeConfig struct {
- // Bootstrap nodes used to establish connectivity with the rest of the network.
- BootstrapNodes *Enodes
-
- // MaxPeers is the maximum number of peers that can be connected. If this is
- // set to zero, then only the configured static and trusted peers can connect.
- MaxPeers int
-
- // EthereumEnabled specifies whether the node should run the Ethereum protocol.
- EthereumEnabled bool
-
- // EthereumNetworkID is the network identifier used by the Ethereum protocol to
- // decide if remote peers should be accepted or not.
- EthereumNetworkID int64 // uint64 in truth, but Java can't handle that...
-
- // EthereumGenesis is the genesis JSON to use to seed the blockchain with. An
- // empty genesis state is equivalent to using the mainnet's state.
- EthereumGenesis string
-
- // EthereumDatabaseCache is the system memory in MB to allocate for database caching.
- // A minimum of 16MB is always reserved.
- EthereumDatabaseCache int
-
- // EthereumNetStats is a netstats connection string to use to report various
- // chain, transaction and node stats to a monitoring server.
- //
- // It has the form "nodename:secret@host:port"
- EthereumNetStats string
-
- // WhisperEnabled specifies whether the node should run the Whisper protocol.
- WhisperEnabled bool
-}
-
-// defaultNodeConfig contains the default node configuration values to use if all
-// or some fields are missing from the user's specified list.
-var defaultNodeConfig = &NodeConfig{
- BootstrapNodes: FoundationBootnodes(),
- MaxPeers: 25,
- EthereumEnabled: true,
- EthereumNetworkID: 1,
- EthereumDatabaseCache: 16,
-}
-
-// NewNodeConfig creates a new node option set, initialized to the default values.
-func NewNodeConfig() *NodeConfig {
- config := *defaultNodeConfig
- return &config
-}
-
-// Node represents a Geth Ethereum node instance.
-type Node struct {
- node *node.Node
-}
-
-// NewNode creates and configures a new Geth node.
-func NewNode(datadir string, config *NodeConfig) (stack *Node, _ error) {
- // If no or partial configurations were specified, use defaults
- if config == nil {
- config = NewNodeConfig()
- }
- if config.MaxPeers == 0 {
- config.MaxPeers = defaultNodeConfig.MaxPeers
- }
- if config.BootstrapNodes == nil || config.BootstrapNodes.Size() == 0 {
- config.BootstrapNodes = defaultNodeConfig.BootstrapNodes
- }
- // Create the empty networking stack
- nodeConf := &node.Config{
- Name: clientIdentifier,
- Version: params.Version,
- DataDir: datadir,
- KeyStoreDir: filepath.Join(datadir, "keystore"), // Mobile should never use internal keystores!
- P2P: p2p.Config{
- NoDiscovery: true,
- DiscoveryV5: true,
- DiscoveryV5Addr: ":0",
- BootstrapNodesV5: config.BootstrapNodes.nodes,
- ListenAddr: ":0",
- NAT: nat.Any(),
- MaxPeers: config.MaxPeers,
- },
- }
- rawStack, err := node.New(nodeConf)
- if err != nil {
- return nil, err
- }
-
- var genesis *core.Genesis
- if config.EthereumGenesis != "" {
- // Parse the user supplied genesis spec if not mainnet
- genesis = new(core.Genesis)
- if err := json.Unmarshal([]byte(config.EthereumGenesis), genesis); err != nil {
- return nil, fmt.Errorf("invalid genesis spec: %v", err)
- }
- // If we have the testnet, hard code the chain configs too
- if config.EthereumGenesis == TestnetGenesis() {
- genesis.Config = params.TestnetChainConfig
- if config.EthereumNetworkID == 1 {
- config.EthereumNetworkID = 3
- }
- }
- }
- // Register the Ethereum protocol if requested
- if config.EthereumEnabled {
- ethConf := eth.DefaultConfig
- ethConf.Genesis = genesis
- ethConf.SyncMode = downloader.LightSync
- ethConf.NetworkId = uint64(config.EthereumNetworkID)
- ethConf.DatabaseCache = config.EthereumDatabaseCache
- if err := rawStack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
- return les.New(ctx, ðConf)
- }); err != nil {
- return nil, fmt.Errorf("ethereum init: %v", err)
- }
- // If netstats reporting is requested, do it
- if config.EthereumNetStats != "" {
- if err := rawStack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
- var lesServ *les.LightEthereum
- ctx.Service(&lesServ)
-
- return ethstats.New(config.EthereumNetStats, nil, lesServ)
- }); err != nil {
- return nil, fmt.Errorf("netstats init: %v", err)
- }
- }
- }
- // Register the Whisper protocol if requested
- if config.WhisperEnabled {
- if err := rawStack.Register(func(*node.ServiceContext) (node.Service, error) {
- return whisper.New(&whisper.DefaultConfig), nil
- }); err != nil {
- return nil, fmt.Errorf("whisper init: %v", err)
- }
- }
- return &Node{rawStack}, nil
-}
-
-// Start creates a live P2P node and starts running it.
-func (n *Node) Start() error {
- return n.node.Start()
-}
-
-// Stop terminates a running node along with all it's services. In the node was
-// not started, an error is returned.
-func (n *Node) Stop() error {
- return n.node.Stop()
-}
-
-// GetEthereumClient retrieves a client to access the Ethereum subsystem.
-func (n *Node) GetEthereumClient() (client *EthereumClient, _ error) {
- rpc, err := n.node.Attach()
- if err != nil {
- return nil, err
- }
- return &EthereumClient{ethclient.NewClient(rpc)}, nil
-}
-
-// GetNodeInfo gathers and returns a collection of metadata known about the host.
-func (n *Node) GetNodeInfo() *NodeInfo {
- return &NodeInfo{n.node.Server().NodeInfo()}
-}
-
-// GetPeersInfo returns an array of metadata objects describing connected peers.
-func (n *Node) GetPeersInfo() *PeerInfos {
- return &PeerInfos{n.node.Server().PeersInfo()}
-}
diff --git a/mobile/geth_android.go b/mobile/geth_android.go
deleted file mode 100644
index 8e4ebe638f8c..000000000000
--- a/mobile/geth_android.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// +build android
-
-package geth
-
-// clientIdentifier is a hard coded identifier to report into the network.
-var clientIdentifier = "GethDroid"
diff --git a/mobile/geth_ios.go b/mobile/geth_ios.go
deleted file mode 100644
index 307cd0858044..000000000000
--- a/mobile/geth_ios.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// +build ios
-
-package geth
-
-// clientIdentifier is a hard coded identifier to report into the network.
-var clientIdentifier = "iGeth"
diff --git a/mobile/geth_other.go b/mobile/geth_other.go
deleted file mode 100644
index 6f0c5dda683c..000000000000
--- a/mobile/geth_other.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// +build !android,!ios
-
-package geth
-
-// clientIdentifier is a hard coded identifier to report into the network.
-var clientIdentifier = "GethMobile"
diff --git a/mobile/init.go b/mobile/init.go
deleted file mode 100644
index 2025d85edc92..000000000000
--- a/mobile/init.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains initialization code for the mbile library.
-
-package geth
-
-import (
- "os"
- "runtime"
-
- "github.com/ethereum/go-ethereum/log"
-)
-
-func init() {
- // Initialize the logger
- log.Root().SetHandler(log.LvlFilterHandler(log.LvlInfo, log.StreamHandler(os.Stderr, log.TerminalFormat(false))))
-
- // Initialize the goroutine count
- runtime.GOMAXPROCS(runtime.NumCPU())
-}
diff --git a/mobile/interface.go b/mobile/interface.go
deleted file mode 100644
index ac0c26088a7b..000000000000
--- a/mobile/interface.go
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains perverted wrappers to allow crossing over empty interfaces.
-
-package geth
-
-import (
- "errors"
- "math/big"
-
- "github.com/ethereum/go-ethereum/common"
-)
-
-// Interface represents a wrapped version of Go's interface{}, with the capacity
-// to store arbitrary data types.
-//
-// Since it's impossible to get the arbitrary-ness converted between Go and mobile
-// platforms, we're using explicit getters and setters for the conversions. There
-// is of course no point in enumerating everything, just enough to support the
-// contract bindins requiring client side generated code.
-type Interface struct {
- object interface{}
-}
-
-// NewInterface creates a new empty interface that can be used to pass around
-// generic types.
-func NewInterface() *Interface {
- return new(Interface)
-}
-
-func (i *Interface) SetBool(b bool) { i.object = &b }
-func (i *Interface) SetBools(bs []bool) { i.object = &bs }
-func (i *Interface) SetString(str string) { i.object = &str }
-func (i *Interface) SetStrings(strs *Strings) { i.object = &strs.strs }
-func (i *Interface) SetBinary(binary []byte) { b := common.CopyBytes(binary); i.object = &b }
-func (i *Interface) SetBinaries(binaries [][]byte) { i.object = &binaries }
-func (i *Interface) SetAddress(address *Address) { i.object = &address.address }
-func (i *Interface) SetAddresses(addrs *Addresses) { i.object = &addrs.addresses }
-func (i *Interface) SetHash(hash *Hash) { i.object = &hash.hash }
-func (i *Interface) SetHashes(hashes *Hashes) { i.object = &hashes.hashes }
-func (i *Interface) SetInt8(n int8) { i.object = &n }
-func (i *Interface) SetInt16(n int16) { i.object = &n }
-func (i *Interface) SetInt32(n int32) { i.object = &n }
-func (i *Interface) SetInt64(n int64) { i.object = &n }
-func (i *Interface) SetUint8(bigint *BigInt) { n := uint8(bigint.bigint.Uint64()); i.object = &n }
-func (i *Interface) SetUint16(bigint *BigInt) { n := uint16(bigint.bigint.Uint64()); i.object = &n }
-func (i *Interface) SetUint32(bigint *BigInt) { n := uint32(bigint.bigint.Uint64()); i.object = &n }
-func (i *Interface) SetUint64(bigint *BigInt) { n := bigint.bigint.Uint64(); i.object = &n }
-func (i *Interface) SetBigInt(bigint *BigInt) { i.object = &bigint.bigint }
-func (i *Interface) SetBigInts(bigints *BigInts) { i.object = &bigints.bigints }
-
-func (i *Interface) SetDefaultBool() { i.object = new(bool) }
-func (i *Interface) SetDefaultBools() { i.object = new([]bool) }
-func (i *Interface) SetDefaultString() { i.object = new(string) }
-func (i *Interface) SetDefaultStrings() { i.object = new([]string) }
-func (i *Interface) SetDefaultBinary() { i.object = new([]byte) }
-func (i *Interface) SetDefaultBinaries() { i.object = new([][]byte) }
-func (i *Interface) SetDefaultAddress() { i.object = new(common.Address) }
-func (i *Interface) SetDefaultAddresses() { i.object = new([]common.Address) }
-func (i *Interface) SetDefaultHash() { i.object = new(common.Hash) }
-func (i *Interface) SetDefaultHashes() { i.object = new([]common.Hash) }
-func (i *Interface) SetDefaultInt8() { i.object = new(int8) }
-func (i *Interface) SetDefaultInt16() { i.object = new(int16) }
-func (i *Interface) SetDefaultInt32() { i.object = new(int32) }
-func (i *Interface) SetDefaultInt64() { i.object = new(int64) }
-func (i *Interface) SetDefaultUint8() { i.object = new(uint8) }
-func (i *Interface) SetDefaultUint16() { i.object = new(uint16) }
-func (i *Interface) SetDefaultUint32() { i.object = new(uint32) }
-func (i *Interface) SetDefaultUint64() { i.object = new(uint64) }
-func (i *Interface) SetDefaultBigInt() { i.object = new(*big.Int) }
-func (i *Interface) SetDefaultBigInts() { i.object = new([]*big.Int) }
-
-func (i *Interface) GetBool() bool { return *i.object.(*bool) }
-func (i *Interface) GetBools() []bool { return *i.object.(*[]bool) }
-func (i *Interface) GetString() string { return *i.object.(*string) }
-func (i *Interface) GetStrings() *Strings { return &Strings{*i.object.(*[]string)} }
-func (i *Interface) GetBinary() []byte { return *i.object.(*[]byte) }
-func (i *Interface) GetBinaries() [][]byte { return *i.object.(*[][]byte) }
-func (i *Interface) GetAddress() *Address { return &Address{*i.object.(*common.Address)} }
-func (i *Interface) GetAddresses() *Addresses { return &Addresses{*i.object.(*[]common.Address)} }
-func (i *Interface) GetHash() *Hash { return &Hash{*i.object.(*common.Hash)} }
-func (i *Interface) GetHashes() *Hashes { return &Hashes{*i.object.(*[]common.Hash)} }
-func (i *Interface) GetInt8() int8 { return *i.object.(*int8) }
-func (i *Interface) GetInt16() int16 { return *i.object.(*int16) }
-func (i *Interface) GetInt32() int32 { return *i.object.(*int32) }
-func (i *Interface) GetInt64() int64 { return *i.object.(*int64) }
-func (i *Interface) GetUint8() *BigInt {
- return &BigInt{new(big.Int).SetUint64(uint64(*i.object.(*uint8)))}
-}
-func (i *Interface) GetUint16() *BigInt {
- return &BigInt{new(big.Int).SetUint64(uint64(*i.object.(*uint16)))}
-}
-func (i *Interface) GetUint32() *BigInt {
- return &BigInt{new(big.Int).SetUint64(uint64(*i.object.(*uint32)))}
-}
-func (i *Interface) GetUint64() *BigInt {
- return &BigInt{new(big.Int).SetUint64(*i.object.(*uint64))}
-}
-func (i *Interface) GetBigInt() *BigInt { return &BigInt{*i.object.(**big.Int)} }
-func (i *Interface) GetBigInts() *BigInts { return &BigInts{*i.object.(*[]*big.Int)} }
-
-// Interfaces is a slices of wrapped generic objects.
-type Interfaces struct {
- objects []interface{}
-}
-
-// NewInterfaces creates a slice of uninitialized interfaces.
-func NewInterfaces(size int) *Interfaces {
- return &Interfaces{
- objects: make([]interface{}, size),
- }
-}
-
-// Size returns the number of interfaces in the slice.
-func (i *Interfaces) Size() int {
- return len(i.objects)
-}
-
-// Get returns the bigint at the given index from the slice.
-func (i *Interfaces) Get(index int) (iface *Interface, _ error) {
- if index < 0 || index >= len(i.objects) {
- return nil, errors.New("index out of bounds")
- }
- return &Interface{i.objects[index]}, nil
-}
-
-// Set sets the big int at the given index in the slice.
-func (i *Interfaces) Set(index int, object *Interface) error {
- if index < 0 || index >= len(i.objects) {
- return errors.New("index out of bounds")
- }
- i.objects[index] = object.object
- return nil
-}
diff --git a/mobile/p2p.go b/mobile/p2p.go
deleted file mode 100644
index a80d9fff2e15..000000000000
--- a/mobile/p2p.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains wrappers for the p2p package.
-
-package geth
-
-import (
- "errors"
-
- "github.com/ethereum/go-ethereum/p2p"
-)
-
-// NodeInfo represents pi short summary of the information known about the host.
-type NodeInfo struct {
- info *p2p.NodeInfo
-}
-
-func (ni *NodeInfo) GetID() string { return ni.info.ID }
-func (ni *NodeInfo) GetName() string { return ni.info.Name }
-func (ni *NodeInfo) GetEnode() string { return ni.info.Enode }
-func (ni *NodeInfo) GetIP() string { return ni.info.IP }
-func (ni *NodeInfo) GetDiscoveryPort() int { return ni.info.Ports.Discovery }
-func (ni *NodeInfo) GetListenerPort() int { return ni.info.Ports.Listener }
-func (ni *NodeInfo) GetListenerAddress() string { return ni.info.ListenAddr }
-func (ni *NodeInfo) GetProtocols() *Strings {
- protos := []string{}
- for proto := range ni.info.Protocols {
- protos = append(protos, proto)
- }
- return &Strings{protos}
-}
-
-// PeerInfo represents pi short summary of the information known about pi connected peer.
-type PeerInfo struct {
- info *p2p.PeerInfo
-}
-
-func (pi *PeerInfo) GetID() string { return pi.info.ID }
-func (pi *PeerInfo) GetName() string { return pi.info.Name }
-func (pi *PeerInfo) GetCaps() *Strings { return &Strings{pi.info.Caps} }
-func (pi *PeerInfo) GetLocalAddress() string { return pi.info.Network.LocalAddress }
-func (pi *PeerInfo) GetRemoteAddress() string { return pi.info.Network.RemoteAddress }
-
-// PeerInfos represents a slice of infos about remote peers.
-type PeerInfos struct {
- infos []*p2p.PeerInfo
-}
-
-// Size returns the number of peer info entries in the slice.
-func (pi *PeerInfos) Size() int {
- return len(pi.infos)
-}
-
-// Get returns the peer info at the given index from the slice.
-func (pi *PeerInfos) Get(index int) (info *PeerInfo, _ error) {
- if index < 0 || index >= len(pi.infos) {
- return nil, errors.New("index out of bounds")
- }
- return &PeerInfo{pi.infos[index]}, nil
-}
diff --git a/mobile/params.go b/mobile/params.go
deleted file mode 100644
index 45fe870ee3dc..000000000000
--- a/mobile/params.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains all the wrappers from the params package.
-
-package geth
-
-import (
- "encoding/json"
-
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/p2p/discv5"
- "github.com/ethereum/go-ethereum/params"
-)
-
-// MainnetGenesis returns the JSON spec to use for the main Ethereum network. It
-// is actually empty since that defaults to the hard coded binary genesis block.
-func MainnetGenesis() string {
- return ""
-}
-
-// TestnetGenesis returns the JSON spec to use for the Ethereum test network.
-func TestnetGenesis() string {
- enc, err := json.Marshal(core.DefaultTestnetGenesisBlock())
- if err != nil {
- panic(err)
- }
- return string(enc)
-}
-
-// RinkebyGenesis returns the JSON spec to use for the Rinkeby test network
-func RinkebyGenesis() string {
- enc, err := json.Marshal(core.DefaultRinkebyGenesisBlock())
- if err != nil {
- panic(err)
- }
- return string(enc)
-}
-
-// FoundationBootnodes returns the enode URLs of the P2P bootstrap nodes operated
-// by the foundation running the V5 discovery protocol.
-func FoundationBootnodes() *Enodes {
- nodes := &Enodes{nodes: make([]*discv5.Node, len(params.DiscoveryV5Bootnodes))}
- for i, url := range params.DiscoveryV5Bootnodes {
- nodes.nodes[i] = discv5.MustParseNode(url)
- }
- return nodes
-}
diff --git a/mobile/primitives.go b/mobile/primitives.go
deleted file mode 100644
index 5c6617fa475e..000000000000
--- a/mobile/primitives.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains various wrappers for primitive types.
-
-package geth
-
-import (
- "errors"
- "fmt"
-)
-
-// Strings represents s slice of strs.
-type Strings struct{ strs []string }
-
-// Size returns the number of strs in the slice.
-func (s *Strings) Size() int {
- return len(s.strs)
-}
-
-// Get returns the string at the given index from the slice.
-func (s *Strings) Get(index int) (str string, _ error) {
- if index < 0 || index >= len(s.strs) {
- return "", errors.New("index out of bounds")
- }
- return s.strs[index], nil
-}
-
-// Set sets the string at the given index in the slice.
-func (s *Strings) Set(index int, str string) error {
- if index < 0 || index >= len(s.strs) {
- return errors.New("index out of bounds")
- }
- s.strs[index] = str
- return nil
-}
-
-// String implements the Stringer interface.
-func (s *Strings) String() string {
- return fmt.Sprintf("%v", s.strs)
-}
diff --git a/mobile/types.go b/mobile/types.go
deleted file mode 100644
index b7f8a3bc15c5..000000000000
--- a/mobile/types.go
+++ /dev/null
@@ -1,362 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains all the wrappers from the core/types package.
-
-package geth
-
-import (
- "encoding/json"
- "errors"
- "fmt"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/rlp"
-)
-
-// A Nonce is a 64-bit hash which proves (combined with the mix-hash) that
-// a sufficient amount of computation has been carried out on a block.
-type Nonce struct {
- nonce types.BlockNonce
-}
-
-// GetBytes retrieves the byte representation of the block nonce.
-func (n *Nonce) GetBytes() []byte {
- return n.nonce[:]
-}
-
-// GetHex retrieves the hex string representation of the block nonce.
-func (n *Nonce) GetHex() string {
- return fmt.Sprintf("0x%x", n.nonce[:])
-}
-
-// Bloom represents a 256 bit bloom filter.
-type Bloom struct {
- bloom types.Bloom
-}
-
-// GetBytes retrieves the byte representation of the bloom filter.
-func (b *Bloom) GetBytes() []byte {
- return b.bloom[:]
-}
-
-// GetHex retrieves the hex string representation of the bloom filter.
-func (b *Bloom) GetHex() string {
- return fmt.Sprintf("0x%x", b.bloom[:])
-}
-
-// Header represents a block header in the Ethereum blockchain.
-type Header struct {
- header *types.Header
-}
-
-// NewHeaderFromRLP parses a header from an RLP data dump.
-func NewHeaderFromRLP(data []byte) (*Header, error) {
- h := &Header{
- header: new(types.Header),
- }
- if err := rlp.DecodeBytes(common.CopyBytes(data), h.header); err != nil {
- return nil, err
- }
- return h, nil
-}
-
-// EncodeRLP encodes a header into an RLP data dump.
-func (h *Header) EncodeRLP() ([]byte, error) {
- return rlp.EncodeToBytes(h.header)
-}
-
-// NewHeaderFromJSON parses a header from an JSON data dump.
-func NewHeaderFromJSON(data string) (*Header, error) {
- h := &Header{
- header: new(types.Header),
- }
- if err := json.Unmarshal([]byte(data), h.header); err != nil {
- return nil, err
- }
- return h, nil
-}
-
-// EncodeJSON encodes a header into an JSON data dump.
-func (h *Header) EncodeJSON() (string, error) {
- data, err := json.Marshal(h.header)
- return string(data), err
-}
-
-// String implements the fmt.Stringer interface to print some semi-meaningful
-// data dump of the header for debugging purposes.
-func (h *Header) String() string {
- return h.header.String()
-}
-
-func (h *Header) GetParentHash() *Hash { return &Hash{h.header.ParentHash} }
-func (h *Header) GetUncleHash() *Hash { return &Hash{h.header.UncleHash} }
-func (h *Header) GetCoinbase() *Address { return &Address{h.header.Coinbase} }
-func (h *Header) GetRoot() *Hash { return &Hash{h.header.Root} }
-func (h *Header) GetTxHash() *Hash { return &Hash{h.header.TxHash} }
-func (h *Header) GetReceiptHash() *Hash { return &Hash{h.header.ReceiptHash} }
-func (h *Header) GetBloom() *Bloom { return &Bloom{h.header.Bloom} }
-func (h *Header) GetDifficulty() *BigInt { return &BigInt{h.header.Difficulty} }
-func (h *Header) GetNumber() int64 { return h.header.Number.Int64() }
-func (h *Header) GetGasLimit() int64 { return h.header.GasLimit.Int64() }
-func (h *Header) GetGasUsed() int64 { return h.header.GasUsed.Int64() }
-func (h *Header) GetTime() int64 { return h.header.Time.Int64() }
-func (h *Header) GetExtra() []byte { return h.header.Extra }
-func (h *Header) GetMixDigest() *Hash { return &Hash{h.header.MixDigest} }
-func (h *Header) GetNonce() *Nonce { return &Nonce{h.header.Nonce} }
-func (h *Header) GetHash() *Hash { return &Hash{h.header.Hash()} }
-
-// Headers represents a slice of headers.
-type Headers struct{ headers []*types.Header }
-
-// Size returns the number of headers in the slice.
-func (h *Headers) Size() int {
- return len(h.headers)
-}
-
-// Get returns the header at the given index from the slice.
-func (h *Headers) Get(index int) (header *Header, _ error) {
- if index < 0 || index >= len(h.headers) {
- return nil, errors.New("index out of bounds")
- }
- return &Header{h.headers[index]}, nil
-}
-
-// Block represents an entire block in the Ethereum blockchain.
-type Block struct {
- block *types.Block
-}
-
-// NewBlockFromRLP parses a block from an RLP data dump.
-func NewBlockFromRLP(data []byte) (*Block, error) {
- b := &Block{
- block: new(types.Block),
- }
- if err := rlp.DecodeBytes(common.CopyBytes(data), b.block); err != nil {
- return nil, err
- }
- return b, nil
-}
-
-// EncodeRLP encodes a block into an RLP data dump.
-func (b *Block) EncodeRLP() ([]byte, error) {
- return rlp.EncodeToBytes(b.block)
-}
-
-// NewBlockFromJSON parses a block from an JSON data dump.
-func NewBlockFromJSON(data string) (*Block, error) {
- b := &Block{
- block: new(types.Block),
- }
- if err := json.Unmarshal([]byte(data), b.block); err != nil {
- return nil, err
- }
- return b, nil
-}
-
-// EncodeJSON encodes a block into an JSON data dump.
-func (b *Block) EncodeJSON() (string, error) {
- data, err := json.Marshal(b.block)
- return string(data), err
-}
-
-// String implements the fmt.Stringer interface to print some semi-meaningful
-// data dump of the block for debugging purposes.
-func (b *Block) String() string {
- return b.block.String()
-}
-
-func (b *Block) GetParentHash() *Hash { return &Hash{b.block.ParentHash()} }
-func (b *Block) GetUncleHash() *Hash { return &Hash{b.block.UncleHash()} }
-func (b *Block) GetCoinbase() *Address { return &Address{b.block.Coinbase()} }
-func (b *Block) GetRoot() *Hash { return &Hash{b.block.Root()} }
-func (b *Block) GetTxHash() *Hash { return &Hash{b.block.TxHash()} }
-func (b *Block) GetReceiptHash() *Hash { return &Hash{b.block.ReceiptHash()} }
-func (b *Block) GetBloom() *Bloom { return &Bloom{b.block.Bloom()} }
-func (b *Block) GetDifficulty() *BigInt { return &BigInt{b.block.Difficulty()} }
-func (b *Block) GetNumber() int64 { return b.block.Number().Int64() }
-func (b *Block) GetGasLimit() int64 { return b.block.GasLimit().Int64() }
-func (b *Block) GetGasUsed() int64 { return b.block.GasUsed().Int64() }
-func (b *Block) GetTime() int64 { return b.block.Time().Int64() }
-func (b *Block) GetExtra() []byte { return b.block.Extra() }
-func (b *Block) GetMixDigest() *Hash { return &Hash{b.block.MixDigest()} }
-func (b *Block) GetNonce() int64 { return int64(b.block.Nonce()) }
-
-func (b *Block) GetHash() *Hash { return &Hash{b.block.Hash()} }
-func (b *Block) GetHashNoNonce() *Hash { return &Hash{b.block.HashNoNonce()} }
-
-func (b *Block) GetHeader() *Header { return &Header{b.block.Header()} }
-func (b *Block) GetUncles() *Headers { return &Headers{b.block.Uncles()} }
-func (b *Block) GetTransactions() *Transactions { return &Transactions{b.block.Transactions()} }
-func (b *Block) GetTransaction(hash *Hash) *Transaction {
- return &Transaction{b.block.Transaction(hash.hash)}
-}
-
-// Transaction represents a single Ethereum transaction.
-type Transaction struct {
- tx *types.Transaction
-}
-
-// NewTransaction creates a new transaction with the given properties.
-func NewTransaction(nonce int64, to *Address, amount, gasLimit, gasPrice *BigInt, data []byte) *Transaction {
- return &Transaction{types.NewTransaction(uint64(nonce), to.address, amount.bigint, gasLimit.bigint, gasPrice.bigint, common.CopyBytes(data))}
-}
-
-// NewTransactionFromRLP parses a transaction from an RLP data dump.
-func NewTransactionFromRLP(data []byte) (*Transaction, error) {
- tx := &Transaction{
- tx: new(types.Transaction),
- }
- if err := rlp.DecodeBytes(common.CopyBytes(data), tx.tx); err != nil {
- return nil, err
- }
- return tx, nil
-}
-
-// EncodeRLP encodes a transaction into an RLP data dump.
-func (tx *Transaction) EncodeRLP() ([]byte, error) {
- return rlp.EncodeToBytes(tx.tx)
-}
-
-// NewTransactionFromJSON parses a transaction from an JSON data dump.
-func NewTransactionFromJSON(data string) (*Transaction, error) {
- tx := &Transaction{
- tx: new(types.Transaction),
- }
- if err := json.Unmarshal([]byte(data), tx.tx); err != nil {
- return nil, err
- }
- return tx, nil
-}
-
-// EncodeJSON encodes a transaction into an JSON data dump.
-func (tx *Transaction) EncodeJSON() (string, error) {
- data, err := json.Marshal(tx.tx)
- return string(data), err
-}
-
-// String implements the fmt.Stringer interface to print some semi-meaningful
-// data dump of the transaction for debugging purposes.
-func (tx *Transaction) String() string {
- return tx.tx.String()
-}
-
-func (tx *Transaction) GetData() []byte { return tx.tx.Data() }
-func (tx *Transaction) GetGas() int64 { return tx.tx.Gas().Int64() }
-func (tx *Transaction) GetGasPrice() *BigInt { return &BigInt{tx.tx.GasPrice()} }
-func (tx *Transaction) GetValue() *BigInt { return &BigInt{tx.tx.Value()} }
-func (tx *Transaction) GetNonce() int64 { return int64(tx.tx.Nonce()) }
-
-func (tx *Transaction) GetHash() *Hash { return &Hash{tx.tx.Hash()} }
-func (tx *Transaction) GetCost() *BigInt { return &BigInt{tx.tx.Cost()} }
-
-// Deprecated: GetSigHash cannot know which signer to use.
-func (tx *Transaction) GetSigHash() *Hash { return &Hash{types.HomesteadSigner{}.Hash(tx.tx)} }
-
-// Deprecated: use EthereumClient.TransactionSender
-func (tx *Transaction) GetFrom(chainID *BigInt) (address *Address, _ error) {
- var signer types.Signer = types.HomesteadSigner{}
- if chainID != nil {
- signer = types.NewEIP155Signer(chainID.bigint)
- }
- from, err := types.Sender(signer, tx.tx)
- return &Address{from}, err
-}
-
-func (tx *Transaction) GetTo() *Address {
- if to := tx.tx.To(); to != nil {
- return &Address{*to}
- }
- return nil
-}
-
-func (tx *Transaction) WithSignature(sig []byte, chainID *BigInt) (signedTx *Transaction, _ error) {
- var signer types.Signer = types.HomesteadSigner{}
- if chainID != nil {
- signer = types.NewEIP155Signer(chainID.bigint)
- }
- rawTx, err := tx.tx.WithSignature(signer, common.CopyBytes(sig))
- return &Transaction{rawTx}, err
-}
-
-// Transactions represents a slice of transactions.
-type Transactions struct{ txs types.Transactions }
-
-// Size returns the number of transactions in the slice.
-func (txs *Transactions) Size() int {
- return len(txs.txs)
-}
-
-// Get returns the transaction at the given index from the slice.
-func (txs *Transactions) Get(index int) (tx *Transaction, _ error) {
- if index < 0 || index >= len(txs.txs) {
- return nil, errors.New("index out of bounds")
- }
- return &Transaction{txs.txs[index]}, nil
-}
-
-// Receipt represents the results of a transaction.
-type Receipt struct {
- receipt *types.Receipt
-}
-
-// NewReceiptFromRLP parses a transaction receipt from an RLP data dump.
-func NewReceiptFromRLP(data []byte) (*Receipt, error) {
- r := &Receipt{
- receipt: new(types.Receipt),
- }
- if err := rlp.DecodeBytes(common.CopyBytes(data), r.receipt); err != nil {
- return nil, err
- }
- return r, nil
-}
-
-// EncodeRLP encodes a transaction receipt into an RLP data dump.
-func (r *Receipt) EncodeRLP() ([]byte, error) {
- return rlp.EncodeToBytes(r.receipt)
-}
-
-// NewReceiptFromJSON parses a transaction receipt from an JSON data dump.
-func NewReceiptFromJSON(data string) (*Receipt, error) {
- r := &Receipt{
- receipt: new(types.Receipt),
- }
- if err := json.Unmarshal([]byte(data), r.receipt); err != nil {
- return nil, err
- }
- return r, nil
-}
-
-// EncodeJSON encodes a transaction receipt into an JSON data dump.
-func (r *Receipt) EncodeJSON() (string, error) {
- data, err := rlp.EncodeToBytes(r.receipt)
- return string(data), err
-}
-
-// String implements the fmt.Stringer interface to print some semi-meaningful
-// data dump of the transaction receipt for debugging purposes.
-func (r *Receipt) String() string {
- return r.receipt.String()
-}
-
-func (r *Receipt) GetPostState() []byte { return r.receipt.PostState }
-func (r *Receipt) GetCumulativeGasUsed() *BigInt { return &BigInt{r.receipt.CumulativeGasUsed} }
-func (r *Receipt) GetBloom() *Bloom { return &Bloom{r.receipt.Bloom} }
-func (r *Receipt) GetLogs() *Logs { return &Logs{r.receipt.Logs} }
-func (r *Receipt) GetTxHash() *Hash { return &Hash{r.receipt.TxHash} }
-func (r *Receipt) GetContractAddress() *Address { return &Address{r.receipt.ContractAddress} }
-func (r *Receipt) GetGasUsed() *BigInt { return &BigInt{r.receipt.GasUsed} }
diff --git a/mobile/vm.go b/mobile/vm.go
deleted file mode 100644
index 72093e3d5b90..000000000000
--- a/mobile/vm.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains all the wrappers from the core/types package.
-
-package geth
-
-import (
- "errors"
-
- "github.com/ethereum/go-ethereum/core/types"
-)
-
-// Log represents a contract log event. These events are generated by the LOG
-// opcode and stored/indexed by the node.
-type Log struct {
- log *types.Log
-}
-
-func (l *Log) GetAddress() *Address { return &Address{l.log.Address} }
-func (l *Log) GetTopics() *Hashes { return &Hashes{l.log.Topics} }
-func (l *Log) GetData() []byte { return l.log.Data }
-func (l *Log) GetBlockNumber() int64 { return int64(l.log.BlockNumber) }
-func (l *Log) GetTxHash() *Hash { return &Hash{l.log.TxHash} }
-func (l *Log) GetTxIndex() int { return int(l.log.TxIndex) }
-func (l *Log) GetBlockHash() *Hash { return &Hash{l.log.BlockHash} }
-func (l *Log) GetIndex() int { return int(l.log.Index) }
-
-// Logs represents a slice of VM logs.
-type Logs struct{ logs []*types.Log }
-
-// Size returns the number of logs in the slice.
-func (l *Logs) Size() int {
- return len(l.logs)
-}
-
-// Get returns the log at the given index from the slice.
-func (l *Logs) Get(index int) (log *Log, _ error) {
- if index < 0 || index >= len(l.logs) {
- return nil, errors.New("index out of bounds")
- }
- return &Log{l.logs[index]}, nil
-}
diff --git a/node/api.go b/node/api.go
index 1b04b70938bb..d829546432f1 100644
--- a/node/api.go
+++ b/node/api.go
@@ -19,15 +19,19 @@ package node
import (
"context"
"fmt"
+ "path/filepath"
+ "reflect"
+ "sort"
"strings"
"time"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/rpc"
"github.com/rcrowley/go-metrics"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
// PrivateAdminAPI is the collection of administrative API methods exposed only
@@ -42,6 +46,108 @@ func NewPrivateAdminAPI(node *Node) *PrivateAdminAPI {
return &PrivateAdminAPI{node: node}
}
+func (api *PrivateAdminAPI) Logrotate() error {
+ var (
+ logdir = filepath.Join(api.node.InstanceDir(), "logs")
+ clientIdentifier = api.node.config.Name
+ glogger = log.Root().GetGlogger()
+ )
+ if api.node.config.LogToFile {
+ glogger.SetHandler(log.Must.FileHandler(filepath.Join(logdir, clientIdentifier+".log"), log.TerminalFormat(false)))
+ log.Root().SetHandler(log.MultiHandler(
+ // default logging for any lvl <= verbosity
+ glogger,
+ // lvl specific logging
+ // log.LvlMatchFilterFileHandler(log.LvlType, logdir),
+ log.LvlMatchFilterFileHandler(log.LvlMessageRx, logdir),
+ log.LvlMatchFilterFileHandler(log.LvlMessageTx, logdir),
+ log.LvlMatchFilterFileHandler(log.LvlTask, logdir),
+ log.LvlMatchFilterFileHandler(log.LvlTxData, logdir),
+ log.LvlMatchFilterFileHandler(log.LvlTxTx, logdir),
+ ))
+ }
+ return nil
+}
+
+func (api *PrivateAdminAPI) RedialList() (string, error) {
+ // Sort the result array alphabetically by node identifier
+ redialList := api.node.Server().RedialList()
+ for i := 0; i < len(redialList); i++ {
+ for j := i + 1; j < len(redialList); j++ {
+ if redialList[i] > redialList[j] {
+ redialList[i], redialList[j] = redialList[j], redialList[i]
+ }
+ }
+ }
+ return strings.Join(redialList, "\n"), nil
+}
+
+func (api *PrivateAdminAPI) Blacklist() (interface{}, error) {
+ blacklist := api.node.Server().Blacklist
+ if blacklist != nil {
+ return blacklist.MarshalTOML(), nil
+ }
+ return []string{}, nil
+}
+
+func (api *PrivateAdminAPI) AddBlacklist(cidrs string) error {
+ return api.node.Server().AddBlacklist(cidrs)
+}
+
+// PeersList retrieves all the information we know about each individual peer at the
+// protocol granularity in bsv.
+func (api *PublicAdminAPI) PeerList() (string, error) {
+ server := api.node.Server()
+ if server == nil {
+ return "", ErrNodeStopped
+ }
+ var peerList []string
+ for _, info := range server.PeersInfo() {
+ id := info.ID
+ name := server.StrReplacer.Replace(info.Name)
+ capsArray := make([]string, len(info.Caps))
+ copy(capsArray, info.Caps)
+ sort.Strings(capsArray)
+ caps := strings.Join(capsArray, ",")
+ caps = server.StrReplacer.Replace(caps)
+ localAddr := info.Network.LocalAddress
+ remoteAddr := info.Network.RemoteAddress
+ connType := info.Conn
+ senderMss := info.SenderMss
+ receiverMss := info.ReceiverMss
+ rtt := info.Rtt
+ srtt := info.Srtt
+ duration := info.Duration
+ p2pInfoStr := fmt.Sprintf("%s|%v|%v|%s|%v|%v|%.6f|%.6f|%.6f|%v|%v", id, remoteAddr, localAddr, connType, senderMss, receiverMss, rtt, srtt, duration, name, caps)
+ var ethInfoStr string
+ if ethInfo := info.Protocols["eth"]; ethInfo != nil {
+ r := reflect.ValueOf(ethInfo)
+ switch r.Kind() {
+ case reflect.String:
+ continue
+ default:
+ v := r.Elem()
+ for i := 0; i < v.NumField(); i++ {
+ elem := v.Field(i)
+ switch elem.Kind() {
+ case reflect.Ptr:
+ ptrV := elem.Elem()
+ if ptrV.IsValid() {
+ ethInfoStr += fmt.Sprintf("|%v", elem.Interface())
+ }
+ case reflect.Int, reflect.String:
+ ethInfoStr += fmt.Sprintf("|%v", elem.Interface())
+ default:
+ continue
+ }
+ }
+ }
+ }
+ peerList = append(peerList, fmt.Sprintf("%s%s", p2pInfoStr, ethInfoStr))
+ }
+ return strings.Join(peerList, "\n"), nil
+}
+
// AddPeer requests connecting to a remote node, and also maintaining the new
// connection at all times, even reconnecting if it is lost.
func (api *PrivateAdminAPI) AddPeer(url string) (bool, error) {
@@ -59,6 +165,29 @@ func (api *PrivateAdminAPI) AddPeer(url string) (bool, error) {
return true, nil
}
+// AddPeers requests connecting to remote nodes, and also maintaining the new
+// connection at all times, even reconnecting if it is lost.
+func (api *PrivateAdminAPI) AddPeers(urls string) (bool, error) {
+ // Make sure the server is running, fail otherwise
+ server := api.node.Server()
+ if server == nil {
+ return false, ErrNodeStopped
+ }
+ // Try to add the urls as static peers and return
+
+ ws := strings.NewReplacer(" ", "", "\n", "", "\t", "")
+ urlList := strings.Split(ws.Replace(urls), ",")
+ var nodes []*discover.Node
+ for _, url := range urlList {
+ node, err := discover.ParseNode(url)
+ if err == nil {
+ nodes = append(nodes, node)
+ }
+ }
+ server.AddPeers(nodes)
+ return true, nil
+}
+
// RemovePeer disconnects from a a remote node if the connection exists
func (api *PrivateAdminAPI) RemovePeer(url string) (bool, error) {
// Make sure the server is running, fail otherwise
diff --git a/node/config.go b/node/config.go
index 1ee02d896354..5b89838241f2 100644
--- a/node/config.go
+++ b/node/config.go
@@ -25,14 +25,15 @@ import (
"runtime"
"strings"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/accounts/keystore"
- "github.com/ethereum/go-ethereum/accounts/usbwallet"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
+ "github.com/prometheus/prometheus/util/flock"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/accounts/keystore"
+ "github.com/teamnsrg/ethereum-p2p/accounts/usbwallet"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
)
const (
@@ -47,6 +48,12 @@ const (
// P2P network layer of a protocol stack. These values can be further extended by
// all registered services.
type Config struct {
+ LogToFile bool `toml:",omitempty"`
+
+ // InstanceDirLock is set at the very beginning if LogToFile is enabled
+ // It prevents concurrent use of instance directory
+ InstanceDirLock flock.Releaser
+
// Name sets the instance name of the node. It must not contain the / character and is
// used in the devp2p node identifier. The instance name of geth is "geth". If no
// value is specified, the basename of the current executable is used.
diff --git a/node/config_test.go b/node/config_test.go
index b81d3d612025..0b4bc133861d 100644
--- a/node/config_test.go
+++ b/node/config_test.go
@@ -24,8 +24,8 @@ import (
"runtime"
"testing"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/p2p"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
)
// Tests that datadirs can be successfully created, be them manually configured
diff --git a/node/defaults.go b/node/defaults.go
index 848f08e05cde..6c8cda02a281 100644
--- a/node/defaults.go
+++ b/node/defaults.go
@@ -22,8 +22,8 @@ import (
"path/filepath"
"runtime"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/nat"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/nat"
)
const (
@@ -45,6 +45,7 @@ var DefaultConfig = Config{
DiscoveryV5Addr: ":30304",
MaxPeers: 25,
NAT: nat.Any(),
+ NoMaxPeers: true, // node-finder never limits number of peers
},
}
diff --git a/node/errors.go b/node/errors.go
index 2e0dadc4d6b3..c566f9efd271 100644
--- a/node/errors.go
+++ b/node/errors.go
@@ -32,7 +32,7 @@ var (
datadirInUseErrnos = map[uint]bool{11: true, 32: true, 35: true}
)
-func convertFileLockError(err error) error {
+func ConvertFileLockError(err error) error {
if errno, ok := err.(syscall.Errno); ok && datadirInUseErrnos[uint(errno)] {
return ErrDatadirUsed
}
diff --git a/node/node.go b/node/node.go
index 6f189d8fe5a0..4d7f4cea42ed 100644
--- a/node/node.go
+++ b/node/node.go
@@ -26,14 +26,14 @@ import (
"strings"
"sync"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/internal/debug"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/rpc"
"github.com/prometheus/prometheus/util/flock"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/internal/debug"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
// Node is a container on which services can be registered.
@@ -187,7 +187,7 @@ func (n *Node) Start() error {
running.Protocols = append(running.Protocols, service.Protocols()...)
}
if err := running.Start(); err != nil {
- return convertFileLockError(err)
+ return ConvertFileLockError(err)
}
// Start each of the services
started := []reflect.Type{}
@@ -221,6 +221,10 @@ func (n *Node) Start() error {
}
func (n *Node) openDataDir() error {
+ if n.config.LogToFile {
+ n.instanceDirLock = n.config.InstanceDirLock
+ return nil
+ }
if n.config.DataDir == "" {
return nil // ephemeral
}
@@ -233,7 +237,7 @@ func (n *Node) openDataDir() error {
// accidental use of the instance directory as a database.
release, _, err := flock.New(filepath.Join(instdir, "LOCK"))
if err != nil {
- return convertFileLockError(err)
+ return ConvertFileLockError(err)
}
n.instanceDirLock = release
return nil
diff --git a/node/node_example_test.go b/node/node_example_test.go
index ee06f4065c37..d4e6e2b12619 100644
--- a/node/node_example_test.go
+++ b/node/node_example_test.go
@@ -20,9 +20,9 @@ import (
"fmt"
"log"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/node"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
// SampleService is a trivial network service that can be attached to a node for
diff --git a/node/node_test.go b/node/node_test.go
index 2880efa61904..3a930d60c519 100644
--- a/node/node_test.go
+++ b/node/node_test.go
@@ -24,9 +24,9 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
var (
diff --git a/node/service.go b/node/service.go
index 55062a500454..cca1afda0daa 100644
--- a/node/service.go
+++ b/node/service.go
@@ -19,11 +19,11 @@ package node
import (
"reflect"
- "github.com/ethereum/go-ethereum/accounts"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/accounts"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
// ServiceContext is a collection of service independent options inherited from
diff --git a/node/utils_test.go b/node/utils_test.go
index 8eddce3ed7a4..adcb7368c94d 100644
--- a/node/utils_test.go
+++ b/node/utils_test.go
@@ -22,8 +22,8 @@ package node
import (
"reflect"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
// NoopService is a trivial implementation of the Service interface.
diff --git a/p2p/dial.go b/p2p/dial.go
index 2d9e3a0edcef..f9ee5a23ebb8 100644
--- a/p2p/dial.go
+++ b/p2p/dial.go
@@ -24,9 +24,9 @@ import (
"net"
"time"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/p2p/netutil"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/p2p/netutil"
)
const (
@@ -72,6 +72,7 @@ type dialstate struct {
maxDynDials int
ntab discoverTable
netrestrict *netutil.Netlist
+ blacklist *netutil.Netlist
lookupRunning bool
dialing map[discover.NodeID]connFlag
@@ -103,6 +104,7 @@ type pastDial struct {
type task interface {
Do(*Server)
+ TaskInfoCtx() []interface{}
}
// A dialTask is generated for each node that is dialed. Its
@@ -112,6 +114,7 @@ type dialTask struct {
dest *discover.Node
lastResolved time.Time
resolveDelay time.Duration
+ lastSuccess time.Time
}
// discoverTask runs discovery table operations.
@@ -146,9 +149,10 @@ func newDialState(static []*discover.Node, bootnodes []*discover.Node, ntab disc
}
func (s *dialstate) addStatic(n *discover.Node) {
- // This overwites the task instead of updating an existing
- // entry, giving users the opportunity to force a resolve operation.
- s.static[n.ID] = &dialTask{flags: staticDialedConn, dest: n}
+ // This updates an existing entry.
+ // If being added as a static node, the node must have been responsive.
+ // Record current time as its lastSuccess time.
+ s.static[n.ID] = &dialTask{flags: staticDialedConn, dest: n, lastSuccess: time.Now()}
}
func (s *dialstate) removeStatic(n *discover.Node) {
@@ -192,7 +196,7 @@ func (s *dialstate) newTasks(nRunning int, peers map[discover.NodeID]*Peer, now
for id, t := range s.static {
err := s.checkDial(t.dest, peers)
switch err {
- case errNotWhitelisted, errSelf:
+ case errNotWhitelisted, errBlacklisted, errSelf:
log.Warn("Removing static dial candidate", "id", t.dest.ID, "addr", &net.TCPAddr{IP: t.dest.IP, Port: int(t.dest.TCP)}, "err", err)
delete(s.static, t.dest.ID)
case nil:
@@ -255,6 +259,7 @@ var (
errAlreadyConnected = errors.New("already connected")
errRecentlyDialed = errors.New("recently dialed")
errNotWhitelisted = errors.New("not contained in netrestrict whitelist")
+ errBlacklisted = errors.New("contained in blacklist")
)
func (s *dialstate) checkDial(n *discover.Node, peers map[discover.NodeID]*Peer) error {
@@ -268,6 +273,8 @@ func (s *dialstate) checkDial(n *discover.Node, peers map[discover.NodeID]*Peer)
return errSelf
case s.netrestrict != nil && !s.netrestrict.Contains(n.IP):
return errNotWhitelisted
+ case s.blacklist != nil && s.blacklist.Contains(n.IP):
+ return errBlacklisted
case s.hist.contains(n.ID):
return errRecentlyDialed
}
@@ -338,14 +345,34 @@ func (t *dialTask) resolve(srv *Server) bool {
func (t *dialTask) dial(srv *Server, dest *discover.Node) bool {
fd, err := srv.Dialer.Dial(dest)
if err != nil {
- log.Trace("Dial error", "task", t, "err", err)
+ log.Task("FAIL-DIAL", append(t.TaskInfoCtx(), "err", err))
return false
}
+ // record current time as its lastSuccess time
+ if !t.lastSuccess.IsZero() {
+ t.lastSuccess = time.Now()
+ }
mfd := newMeteredConn(fd, false)
srv.SetupConn(mfd, t.flags, dest)
return true
}
+func (t *dialTask) TaskInfoCtx() []interface{} {
+ addr := &net.TCPAddr{IP: t.dest.IP, Port: int(t.dest.TCP)}
+ var lastSuccess interface{}
+ if t.lastSuccess.IsZero() {
+ lastSuccess = nil
+ } else {
+ lastSuccess = t.lastSuccess
+ }
+ return []interface{}{
+ "task", t.flags,
+ "id", t.dest.ID.String(),
+ "addr", addr.String(),
+ "lastSuccess", lastSuccess,
+ }
+}
+
func (t *dialTask) String() string {
return fmt.Sprintf("%v %x %v:%d", t.flags, t.dest.ID[:8], t.dest.IP, t.dest.TCP)
}
@@ -364,6 +391,13 @@ func (t *discoverTask) Do(srv *Server) {
t.results = srv.ntab.Lookup(target)
}
+func (t *discoverTask) TaskInfoCtx() []interface{} {
+ return []interface{}{
+ "task", "discover",
+ "numResults", len(t.results),
+ }
+}
+
func (t *discoverTask) String() string {
s := "discovery lookup"
if len(t.results) > 0 {
@@ -375,6 +409,14 @@ func (t *discoverTask) String() string {
func (t waitExpireTask) Do(*Server) {
time.Sleep(t.Duration)
}
+
+func (t *waitExpireTask) TaskInfoCtx() []interface{} {
+ return []interface{}{
+ "task", "wait",
+ "duration", t.Duration.Seconds(),
+ }
+}
+
func (t waitExpireTask) String() string {
return fmt.Sprintf("wait for dial hist expire (%v)", t.Duration)
}
diff --git a/p2p/dial_test.go b/p2p/dial_test.go
index ad18ef9abefe..c8e1971502a1 100644
--- a/p2p/dial_test.go
+++ b/p2p/dial_test.go
@@ -24,8 +24,8 @@ import (
"time"
"github.com/davecgh/go-spew/spew"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/p2p/netutil"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/p2p/netutil"
)
func init() {
@@ -65,6 +65,11 @@ func runDialTest(t *testing.T, test dialtest) {
}
new := test.init.newTasks(running, pm(round.peers), vtime)
+ for _, t := range new {
+ if t, ok := t.(*dialTask); ok {
+ t.lastSuccess = time.Time{}
+ }
+ }
if !sametasks(new, round.new) {
t.Errorf("round %d: new tasks mismatch:\ngot %v\nwant %v\nstate: %v\nrunning: %v\n",
i, spew.Sdump(new), spew.Sdump(round.new), spew.Sdump(test.init), spew.Sdump(running))
@@ -592,6 +597,11 @@ func TestDialResolve(t *testing.T) {
dest := discover.NewNode(uintID(1), nil, 0, 0)
state.addStatic(dest)
tasks := state.newTasks(0, nil, time.Time{})
+ for _, t := range tasks {
+ if t, ok := t.(*dialTask); ok {
+ t.lastSuccess = time.Time{}
+ }
+ }
if !reflect.DeepEqual(tasks, []task{&dialTask{flags: staticDialedConn, dest: dest}}) {
t.Fatalf("expected dial task, got %#v", tasks)
}
diff --git a/p2p/discover/database.go b/p2p/discover/database.go
index 7206a63c6332..2b190322e32e 100644
--- a/p2p/discover/database.go
+++ b/p2p/discover/database.go
@@ -27,15 +27,15 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/rlp"
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/errors"
"github.com/syndtr/goleveldb/leveldb/iterator"
"github.com/syndtr/goleveldb/leveldb/opt"
"github.com/syndtr/goleveldb/leveldb/storage"
"github.com/syndtr/goleveldb/leveldb/util"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
var (
diff --git a/p2p/discover/node.go b/p2p/discover/node.go
index fc928a91afb9..906976d1c407 100644
--- a/p2p/discover/node.go
+++ b/p2p/discover/node.go
@@ -30,9 +30,9 @@ import (
"strconv"
"strings"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/secp256k1"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/crypto/secp256k1"
)
const NodeIDBits = 512
diff --git a/p2p/discover/node_test.go b/p2p/discover/node_test.go
index ed8db4dc65d9..9a17ab22c231 100644
--- a/p2p/discover/node_test.go
+++ b/p2p/discover/node_test.go
@@ -28,8 +28,8 @@ import (
"testing/quick"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
func ExampleNewNode() {
diff --git a/p2p/discover/ntp.go b/p2p/discover/ntp.go
index 1bb52399fbc5..cc977198d33f 100644
--- a/p2p/discover/ntp.go
+++ b/p2p/discover/ntp.go
@@ -25,7 +25,7 @@ import (
"sort"
"time"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
const (
diff --git a/p2p/discover/table.go b/p2p/discover/table.go
index ec4eb94ad52c..06b55efb87f1 100644
--- a/p2p/discover/table.go
+++ b/p2p/discover/table.go
@@ -32,9 +32,9 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
const (
diff --git a/p2p/discover/table_test.go b/p2p/discover/table_test.go
index 1037cc6099fc..50051b0ab594 100644
--- a/p2p/discover/table_test.go
+++ b/p2p/discover/table_test.go
@@ -27,8 +27,8 @@ import (
"testing/quick"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
func TestTable_pingReplace(t *testing.T) {
diff --git a/p2p/discover/udp.go b/p2p/discover/udp.go
index f9eb99ee3611..048e0aaa3e1d 100644
--- a/p2p/discover/udp.go
+++ b/p2p/discover/udp.go
@@ -23,13 +23,14 @@ import (
"errors"
"fmt"
"net"
+ "sync"
"time"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p/nat"
- "github.com/ethereum/go-ethereum/p2p/netutil"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p/nat"
+ "github.com/teamnsrg/ethereum-p2p/p2p/netutil"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
const Version = 4
@@ -136,6 +137,10 @@ func (t *udp) nodeFromRPC(sender *net.UDPAddr, rn rpcNode) (*Node, error) {
if t.netrestrict != nil && !t.netrestrict.Contains(rn.IP) {
return nil, errors.New("not contained in netrestrict whitelist")
}
+ if t.blacklist != nil && t.blacklist.Contains(rn.IP) {
+ log.Debug("Node ignored (blacklisted)", "ip", rn.IP.String(), "transport", "udp")
+ return nil, errors.New("contained in blacklist")
+ }
n := NewNode(rn.ID, rn.IP, rn.UDP, rn.TCP)
err := n.validateComplete()
return n, err
@@ -161,18 +166,24 @@ type conn interface {
type udp struct {
conn conn
netrestrict *netutil.Netlist
+ blacklist *netutil.Netlist
priv *ecdsa.PrivateKey
ourEndpoint rpcEndpoint
addpending chan *pending
gotreply chan reply
+ loopWG sync.WaitGroup
closing chan struct{}
nat nat.Interface
*Table
}
+func (t *udp) SetBlacklist(blacklist *netutil.Netlist) {
+ t.blacklist = blacklist
+}
+
// pending represents a pending reply.
//
// some implementations of the protocol wish to send more than one
@@ -211,28 +222,29 @@ type reply struct {
}
// ListenUDP returns a new table that listens for UDP packets on laddr.
-func ListenUDP(priv *ecdsa.PrivateKey, laddr string, natm nat.Interface, nodeDBPath string, netrestrict *netutil.Netlist) (*Table, error) {
+func ListenUDP(priv *ecdsa.PrivateKey, laddr string, natm nat.Interface, nodeDBPath string, netrestrict *netutil.Netlist, blacklist *netutil.Netlist) (*Table, *udp, error) {
addr, err := net.ResolveUDPAddr("udp", laddr)
if err != nil {
- return nil, err
+ return nil, nil, err
}
conn, err := net.ListenUDP("udp", addr)
if err != nil {
- return nil, err
+ return nil, nil, err
}
- tab, _, err := newUDP(priv, conn, natm, nodeDBPath, netrestrict)
+ tab, udp, err := newUDP(priv, conn, natm, nodeDBPath, netrestrict, blacklist)
if err != nil {
- return nil, err
+ return nil, udp, err
}
log.Info("UDP listener up", "self", tab.self)
- return tab, nil
+ return tab, udp, nil
}
-func newUDP(priv *ecdsa.PrivateKey, c conn, natm nat.Interface, nodeDBPath string, netrestrict *netutil.Netlist) (*Table, *udp, error) {
+func newUDP(priv *ecdsa.PrivateKey, c conn, natm nat.Interface, nodeDBPath string, netrestrict *netutil.Netlist, blacklist *netutil.Netlist) (*Table, *udp, error) {
udp := &udp{
conn: c,
priv: priv,
netrestrict: netrestrict,
+ blacklist: blacklist,
closing: make(chan struct{}),
gotreply: make(chan reply),
addpending: make(chan *pending),
@@ -255,6 +267,7 @@ func newUDP(priv *ecdsa.PrivateKey, c conn, natm nat.Interface, nodeDBPath strin
}
udp.Table = tab
+ udp.loopWG.Add(2)
go udp.loop()
go udp.readLoop()
return udp.Table, udp, nil
@@ -263,7 +276,7 @@ func newUDP(priv *ecdsa.PrivateKey, c conn, natm nat.Interface, nodeDBPath strin
func (t *udp) close() {
close(t.closing)
t.conn.Close()
- // TODO: wait for the loops to end.
+ t.loopWG.Wait()
}
// ping sends a ping message to the given node and waits for a reply.
@@ -275,7 +288,7 @@ func (t *udp) ping(toid NodeID, toaddr *net.UDPAddr) error {
From: t.ourEndpoint,
To: makeEndpoint(toaddr, 0), // TODO: maybe use known TCP port from DB
Expiration: uint64(time.Now().Add(expiration).Unix()),
- })
+ }, toid)
return <-errc
}
@@ -294,7 +307,7 @@ func (t *udp) findnode(toid NodeID, toaddr *net.UDPAddr, target NodeID) ([]*Node
nreceived++
n, err := t.nodeFromRPC(toaddr, rn)
if err != nil {
- log.Trace("Invalid neighbor node received", "ip", rn.IP, "addr", toaddr, "err", err)
+ log.Trace("Invalid neighbor node received", "neighborIp", rn.IP, "senderIp", toaddr, "err", err)
continue
}
nodes = append(nodes, n)
@@ -304,7 +317,7 @@ func (t *udp) findnode(toid NodeID, toaddr *net.UDPAddr, target NodeID) ([]*Node
t.send(toaddr, findnodePacket, &findnode{
Target: target,
Expiration: uint64(time.Now().Add(expiration).Unix()),
- })
+ }, toid)
err := <-errc
return nodes, err
}
@@ -337,6 +350,7 @@ func (t *udp) handleReply(from NodeID, ptype byte, req packet) bool {
// loop runs in its own goroutine. it keeps track of
// the refresh timer and the pending reply queue.
func (t *udp) loop() {
+ defer t.loopWG.Done()
var (
plist = list.New()
timeout = time.NewTimer(0)
@@ -459,13 +473,18 @@ func init() {
}
}
-func (t *udp) send(toaddr *net.UDPAddr, ptype byte, req packet) error {
+func (t *udp) send(toaddr *net.UDPAddr, ptype byte, req packet, peer NodeID) error {
packet, err := encodePacket(t.priv, ptype, req)
if err != nil {
return err
}
+ currentTime := time.Now()
_, err = t.conn.WriteToUDP(packet, toaddr)
- log.Trace(">> "+req.name(), "addr", toaddr, "err", err)
+ connInfoCtx := []interface{}{
+ "id", peer.String(),
+ "addr", toaddr.String(),
+ }
+ log.MessageTx(currentTime, ">>"+req.name(), uint32(len(packet)), uint32(len(packet)), connInfoCtx, err)
return err
}
@@ -493,7 +512,7 @@ func encodePacket(priv *ecdsa.PrivateKey, ptype byte, req interface{}) ([]byte,
// readLoop runs in its own goroutine. it handles incoming UDP packets.
func (t *udp) readLoop() {
- defer t.conn.Close()
+ defer t.loopWG.Done()
// Discovery packets are defined to be no larger than 1280 bytes.
// Packets larger than this size will be cut at the end and treated
// as invalid because their hash won't match.
@@ -519,8 +538,13 @@ func (t *udp) handlePacket(from *net.UDPAddr, buf []byte) error {
log.Debug("Bad discv4 packet", "addr", from, "err", err)
return err
}
+ currentTime := time.Now()
+ connInfoCtx := []interface{}{
+ "id", fromID.String(),
+ "addr", from.String(),
+ }
+ log.MessageRx(currentTime, "<<"+packet.name(), uint32(len(buf)), uint32(len(buf)), connInfoCtx, nil)
err = packet.handle(t, from, fromID, hash)
- log.Trace("<< "+packet.name(), "addr", from, "err", err)
return err
}
@@ -563,7 +587,7 @@ func (req *ping) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte) er
To: makeEndpoint(from, req.From.TCP),
ReplyTok: mac,
Expiration: uint64(time.Now().Add(expiration).Unix()),
- })
+ }, fromID)
if !t.handleReply(fromID, pingPacket, req) {
// Note: we're ignoring the provided IP address right now
go t.bond(true, fromID, from, req.From.TCP)
@@ -571,7 +595,7 @@ func (req *ping) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte) er
return nil
}
-func (req *ping) name() string { return "PING/v4" }
+func (req *ping) name() string { return "RLPX_PING" }
func (req *pong) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte) error {
if expired(req.Expiration) {
@@ -583,7 +607,7 @@ func (req *pong) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte) er
return nil
}
-func (req *pong) name() string { return "PONG/v4" }
+func (req *pong) name() string { return "RLPX_PONG" }
func (req *findnode) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte) error {
if expired(req.Expiration) {
@@ -613,14 +637,14 @@ func (req *findnode) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte
}
p.Nodes = append(p.Nodes, nodeToRPC(n))
if len(p.Nodes) == maxNeighbors || i == len(closest)-1 {
- t.send(from, neighborsPacket, &p)
+ t.send(from, neighborsPacket, &p, fromID)
p.Nodes = p.Nodes[:0]
}
}
return nil
}
-func (req *findnode) name() string { return "FINDNODE/v4" }
+func (req *findnode) name() string { return "RLPX_FINDNODE" }
func (req *neighbors) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byte) error {
if expired(req.Expiration) {
@@ -632,7 +656,7 @@ func (req *neighbors) handle(t *udp, from *net.UDPAddr, fromID NodeID, mac []byt
return nil
}
-func (req *neighbors) name() string { return "NEIGHBORS/v4" }
+func (req *neighbors) name() string { return "RLPX_NEIGHBORS" }
func expired(ts uint64) bool {
return time.Unix(int64(ts), 0).Before(time.Now())
diff --git a/p2p/discover/udp_test.go b/p2p/discover/udp_test.go
index 21e8b561da12..abf0ae0aee94 100644
--- a/p2p/discover/udp_test.go
+++ b/p2p/discover/udp_test.go
@@ -34,9 +34,9 @@ import (
"time"
"github.com/davecgh/go-spew/spew"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
func init() {
@@ -70,7 +70,7 @@ func newUDPTest(t *testing.T) *udpTest {
remotekey: newkey(),
remoteaddr: &net.UDPAddr{IP: net.IP{10, 0, 1, 99}, Port: 30303},
}
- test.table, test.udp, _ = newUDP(test.localkey, test.pipe, nil, "", nil)
+ test.table, test.udp, _ = newUDP(test.localkey, test.pipe, nil, "", nil, nil)
return test
}
diff --git a/p2p/discv5/database.go b/p2p/discv5/database.go
index a3b044ec187e..ca82fb8c2b52 100644
--- a/p2p/discv5/database.go
+++ b/p2p/discv5/database.go
@@ -28,15 +28,15 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/rlp"
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/errors"
"github.com/syndtr/goleveldb/leveldb/iterator"
"github.com/syndtr/goleveldb/leveldb/opt"
"github.com/syndtr/goleveldb/leveldb/storage"
"github.com/syndtr/goleveldb/leveldb/util"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
var (
diff --git a/p2p/discv5/net.go b/p2p/discv5/net.go
index a39cfcc645ef..e0f4051aee18 100644
--- a/p2p/discv5/net.go
+++ b/p2p/discv5/net.go
@@ -24,14 +24,14 @@ import (
"net"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/mclock"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/sha3"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p/nat"
- "github.com/ethereum/go-ethereum/p2p/netutil"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/mclock"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/crypto/sha3"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p/nat"
+ "github.com/teamnsrg/ethereum-p2p/p2p/netutil"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
var (
diff --git a/p2p/discv5/net_test.go b/p2p/discv5/net_test.go
index bd234f5ba6d2..abacac48b34f 100644
--- a/p2p/discv5/net_test.go
+++ b/p2p/discv5/net_test.go
@@ -22,8 +22,8 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
func TestNetwork_Lookup(t *testing.T) {
diff --git a/p2p/discv5/node.go b/p2p/discv5/node.go
index 2db7a508f00d..d825b1149722 100644
--- a/p2p/discv5/node.go
+++ b/p2p/discv5/node.go
@@ -30,8 +30,8 @@ import (
"strconv"
"strings"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
// Node represents a host on the network.
diff --git a/p2p/discv5/node_test.go b/p2p/discv5/node_test.go
index ce4ad9e4d48e..d658215fd581 100644
--- a/p2p/discv5/node_test.go
+++ b/p2p/discv5/node_test.go
@@ -27,8 +27,8 @@ import (
"testing/quick"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
func ExampleNewNode() {
diff --git a/p2p/discv5/ntp.go b/p2p/discv5/ntp.go
index f78d5dc43cff..dc1a6d59e25b 100644
--- a/p2p/discv5/ntp.go
+++ b/p2p/discv5/ntp.go
@@ -26,7 +26,7 @@ import (
"strings"
"time"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
const (
diff --git a/p2p/discv5/sim_test.go b/p2p/discv5/sim_test.go
index bf57872e2dc6..bffafd6f8167 100644
--- a/p2p/discv5/sim_test.go
+++ b/p2p/discv5/sim_test.go
@@ -28,7 +28,7 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
// In this test, nodes try to randomly resolve each other.
diff --git a/p2p/discv5/table.go b/p2p/discv5/table.go
index 2cf05009cb0f..7a720b8af2b3 100644
--- a/p2p/discv5/table.go
+++ b/p2p/discv5/table.go
@@ -29,7 +29,7 @@ import (
"net"
"sort"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
const (
diff --git a/p2p/discv5/table_test.go b/p2p/discv5/table_test.go
index a29943dab9b3..cc55cb5f2850 100644
--- a/p2p/discv5/table_test.go
+++ b/p2p/discv5/table_test.go
@@ -27,8 +27,8 @@ import (
"testing/quick"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
type nullTransport struct{}
diff --git a/p2p/discv5/ticket.go b/p2p/discv5/ticket.go
index 48dd114f067d..c3e510c01d62 100644
--- a/p2p/discv5/ticket.go
+++ b/p2p/discv5/ticket.go
@@ -25,9 +25,9 @@ import (
"sort"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/mclock"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/mclock"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
const (
diff --git a/p2p/discv5/topic.go b/p2p/discv5/topic.go
index b6bea013c754..54785f47256f 100644
--- a/p2p/discv5/topic.go
+++ b/p2p/discv5/topic.go
@@ -23,7 +23,7 @@ import (
"math/rand"
"time"
- "github.com/ethereum/go-ethereum/common/mclock"
+ "github.com/teamnsrg/ethereum-p2p/common/mclock"
)
const (
diff --git a/p2p/discv5/topic_test.go b/p2p/discv5/topic_test.go
index ba79993f29e9..93c7d50714c2 100644
--- a/p2p/discv5/topic_test.go
+++ b/p2p/discv5/topic_test.go
@@ -21,8 +21,8 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/mclock"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/mclock"
)
func TestTopicRadius(t *testing.T) {
diff --git a/p2p/discv5/udp.go b/p2p/discv5/udp.go
index 26087cd8e564..d9e5c3908be9 100644
--- a/p2p/discv5/udp.go
+++ b/p2p/discv5/udp.go
@@ -24,12 +24,12 @@ import (
"net"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p/nat"
- "github.com/ethereum/go-ethereum/p2p/netutil"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p/nat"
+ "github.com/teamnsrg/ethereum-p2p/p2p/netutil"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
const Version = 4
diff --git a/p2p/discv5/udp_test.go b/p2p/discv5/udp_test.go
index 7d31815947cf..d56e144e10e4 100644
--- a/p2p/discv5/udp_test.go
+++ b/p2p/discv5/udp_test.go
@@ -27,9 +27,9 @@ import (
"time"
"github.com/davecgh/go-spew/spew"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
func init() {
diff --git a/p2p/message.go b/p2p/message.go
index 5690494bf45e..742ac1ea33dc 100644
--- a/p2p/message.go
+++ b/p2p/message.go
@@ -27,9 +27,10 @@ import (
"sync/atomic"
"time"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
// Msg defines the structure of a p2p message.
@@ -40,10 +41,14 @@ import (
// structure, encode the payload into a byte array and create a
// separate Msg with a bytes.Reader as Payload for each send.
type Msg struct {
- Code uint64
- Size uint32 // size of the paylod
- Payload io.Reader
- ReceivedAt time.Time
+ Code uint64
+ Size uint32 // size of the paylod
+ EncodedSize uint32
+ Payload io.Reader
+ ReceivedAt time.Time
+ Rtt float64
+ Srtt float64
+ PeerDuration float64
}
// Decode parses the RLP content of a message into
@@ -78,7 +83,7 @@ type MsgWriter interface {
//
// Note that messages can be sent only once because their
// payload reader is drained.
- WriteMsg(Msg) error
+ WriteMsg(Msg) (uint32, error)
}
// MsgReadWriter provides reading and writing of encoded messages.
@@ -89,27 +94,49 @@ type MsgReadWriter interface {
MsgWriter
}
+func SendEthSubproto(w MsgWriter, msgcode uint64, data interface{}, connInfoCtx ...interface{}) error {
+ size, r, err := rlp.EncodeToReader(data)
+ if err != nil {
+ return err
+ }
+ currentTime := time.Now()
+ encodedSize, err := w.WriteMsg(Msg{Code: msgcode, Size: uint32(size), Payload: r})
+ msgType, ok := ethCodeToString[msgcode]
+ if !ok {
+ msgType = fmt.Sprintf("UNKNOWN_%v", msgcode)
+ }
+ log.MessageTx(currentTime, ">>"+msgType, uint32(size), encodedSize, connInfoCtx, err)
+ return err
+}
+
// Send writes an RLP-encoded message with the given code.
// data should encode as an RLP list.
-func Send(w MsgWriter, msgcode uint64, data interface{}) error {
+func Send(w MsgWriter, msgcode uint64, data interface{}, connInfoCtx ...interface{}) error {
size, r, err := rlp.EncodeToReader(data)
if err != nil {
return err
}
- return w.WriteMsg(Msg{Code: msgcode, Size: uint32(size), Payload: r})
+ currentTime := time.Now()
+ encodedSize, err := w.WriteMsg(Msg{Code: msgcode, Size: uint32(size), Payload: r})
+ msgType, ok := devp2pCodeToString[msgcode]
+ if !ok {
+ msgType = fmt.Sprintf("UNKNOWN_%v", msgcode)
+ }
+ log.MessageTx(currentTime, ">>"+msgType, uint32(size), encodedSize, connInfoCtx, err)
+ return err
}
// SendItems writes an RLP with the given code and data elements.
// For a call such as:
//
-// SendItems(w, code, e1, e2, e3)
+// SendItems(w, code, [connInfoCtx...], e1, e2, e3)
//
// the message payload will be an RLP list containing the items:
//
// [e1, e2, e3]
//
-func SendItems(w MsgWriter, msgcode uint64, elems ...interface{}) error {
- return Send(w, msgcode, elems)
+func SendItems(w MsgWriter, msgcode uint64, connInfoCtx []interface{}, elems ...interface{}) error {
+ return Send(w, msgcode, elems, connInfoCtx...)
}
// netWrapper wraps a MsgReadWriter with locks around
@@ -129,7 +156,7 @@ func (rw *netWrapper) ReadMsg() (Msg, error) {
return rw.wrapped.ReadMsg()
}
-func (rw *netWrapper) WriteMsg(msg Msg) error {
+func (rw *netWrapper) WriteMsg(msg Msg) (uint32, error) {
rw.wmu.Lock()
defer rw.wmu.Unlock()
rw.conn.SetWriteDeadline(time.Now().Add(rw.wtimeout))
@@ -197,7 +224,7 @@ type MsgPipeRW struct {
// WriteMsg sends a messsage on the pipe.
// It blocks until the receiver has consumed the message payload.
-func (p *MsgPipeRW) WriteMsg(msg Msg) error {
+func (p *MsgPipeRW) WriteMsg(msg Msg) (total uint32, err error) {
if atomic.LoadInt32(p.closed) == 0 {
consumed := make(chan struct{}, 1)
msg.Payload = &eofSignal{msg.Payload, msg.Size, consumed}
@@ -210,11 +237,11 @@ func (p *MsgPipeRW) WriteMsg(msg Msg) error {
case <-p.closing:
}
}
- return nil
+ return total, nil
case <-p.closing:
}
}
- return ErrPipeClosed
+ return total, ErrPipeClosed
}
// ReadMsg returns a message sent on the other end of the pipe.
@@ -314,10 +341,10 @@ func (self *msgEventer) ReadMsg() (Msg, error) {
// WriteMsg writes a message to the underlying MsgReadWriter and emits a
// "message sent" event
-func (self *msgEventer) WriteMsg(msg Msg) error {
- err := self.MsgReadWriter.WriteMsg(msg)
+func (self *msgEventer) WriteMsg(msg Msg) (uint32, error) {
+ total, err := self.MsgReadWriter.WriteMsg(msg)
if err != nil {
- return err
+ return total, err
}
self.feed.Send(&PeerEvent{
Type: PeerEventTypeMsgSend,
@@ -326,7 +353,7 @@ func (self *msgEventer) WriteMsg(msg Msg) error {
MsgCode: &msg.Code,
MsgSize: &msg.Size,
})
- return nil
+ return total, nil
}
// Close closes the underlying MsgReadWriter if it implements the io.Closer
diff --git a/p2p/message_test.go b/p2p/message_test.go
index a01f75556162..7d55586f3313 100644
--- a/p2p/message_test.go
+++ b/p2p/message_test.go
@@ -55,7 +55,7 @@ loop:
rw1, rw2 := MsgPipe()
done := make(chan struct{})
go func() {
- if err := SendItems(rw1, 1); err == nil {
+ if err := SendItems(rw1, 1, []interface{}{}); err == nil {
t.Error("EncodeMsg returned nil error")
} else if err != ErrPipeClosed {
t.Errorf("EncodeMsg returned wrong error: got %v, want %v", err, ErrPipeClosed)
diff --git a/p2p/metrics.go b/p2p/metrics.go
index 98b61901d53d..72974d303c4b 100644
--- a/p2p/metrics.go
+++ b/p2p/metrics.go
@@ -21,7 +21,7 @@ package p2p
import (
"net"
- "github.com/ethereum/go-ethereum/metrics"
+ "github.com/teamnsrg/ethereum-p2p/metrics"
)
var (
diff --git a/p2p/nat/nat.go b/p2p/nat/nat.go
index a254648c66b8..1a3ae7e30931 100644
--- a/p2p/nat/nat.go
+++ b/p2p/nat/nat.go
@@ -25,8 +25,8 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/log"
"github.com/jackpal/go-nat-pmp"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// An implementation of nat.Interface can map local ports to ports
diff --git a/p2p/netutil/net.go b/p2p/netutil/net.go
index f6005afd213a..d9a6d8940065 100644
--- a/p2p/netutil/net.go
+++ b/p2p/netutil/net.go
@@ -81,7 +81,16 @@ func ParseNetlist(s string) (*Netlist, error) {
}
l = append(l, *n)
}
- return &l, nil
+ result := make(Netlist, 0)
+ seen := map[string]*net.IPNet{}
+ for _, val := range l {
+ cidr := val.String()
+ if _, ok := seen[cidr]; !ok {
+ result = append(result, val)
+ seen[cidr] = &val
+ }
+ }
+ return &result, nil
}
// MarshalTOML implements toml.MarshalerRec.
@@ -119,6 +128,20 @@ func (l *Netlist) Add(cidr string) {
*l = append(*l, *n)
}
+func (l *Netlist) AddNonDuplicate(cidr string) error {
+ _, n, err := net.ParseCIDR(cidr)
+ if err != nil {
+ return err
+ }
+ for _, val := range *l {
+ if n.String() == val.String() {
+ return nil
+ }
+ }
+ *l = append(*l, *n)
+ return nil
+}
+
// Contains reports whether the given IP is contained in the list.
func (l *Netlist) Contains(ip net.IP) bool {
if l == nil {
diff --git a/p2p/peer.go b/p2p/peer.go
index 1d2b726e8b45..e9c4dedc945c 100644
--- a/p2p/peer.go
+++ b/p2p/peer.go
@@ -24,11 +24,12 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/common/mclock"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/aristanetworks/goarista/monotime"
+ "github.com/teamnsrg/ethereum-p2p/common/mclock"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
const (
@@ -51,6 +52,36 @@ const (
peersMsg = 0x05
)
+var devp2pCodeToString = map[uint64]string{
+ handshakeMsg: "DEVP2P_HELLO",
+ discMsg: "DEVP2P_DISC",
+ pingMsg: "DEVP2P_PING",
+ pongMsg: "DEVP2P_PONG",
+ getPeersMsg: "DEVP2P_GET_PEERS",
+ peersMsg: "DEVP2P_PEERS",
+}
+
+// ethCodeToString should be the same as the one in eth/protocol.go
+// We re-define it here so that we can use it when logging sent messages.
+// Make sure the eth message codes match
+var ethCodeToString = map[uint64]string{
+ // Protocol messages belonging to eth/62
+ 0x00: "ETH_STATUS",
+ 0x01: "ETH_NEW_BLOCK_HASHES",
+ 0x02: "ETH_TX",
+ 0x03: "ETH_GET_BLOCK_HEADERS",
+ 0x04: "ETH_BLOCK_HEADERS",
+ 0x05: "ETH_GET_BLOCK_BODIES",
+ 0x06: "ETH_BLOCK_BODIES",
+ 0x07: "ETH_NEW_BLOCK",
+
+ // Protocol messages belonging to eth/63
+ 0x0d: "ETH_GET_NODE_DATA",
+ 0x0e: "ETH_NODE_DATA",
+ 0x0f: "ETH_GET_RECEIPTS",
+ 0x10: "ETH_RECEIPTS",
+}
+
// protoHandshake is the RLP structure of the protocol handshake.
type protoHandshake struct {
Version uint64
@@ -114,7 +145,8 @@ type Peer struct {
// NewPeer returns a peer for testing purposes.
func NewPeer(id discover.NodeID, name string, caps []Cap) *Peer {
pipe, _ := net.Pipe()
- conn := &conn{fd: pipe, transport: nil, id: id, caps: caps, name: name}
+ conn := &conn{fd: pipe, tc: newTCPConn(pipe), transport: nil, id: id, caps: caps, name: name}
+ conn.connInfoCtx = []interface{}{}
peer := newPeer(conn, nil)
close(peer.closed) // ensures Disconnect doesn't block
return peer
@@ -125,6 +157,11 @@ func (p *Peer) ID() discover.NodeID {
return p.rw.id
}
+// Version returns the version of the p2p protocol used by the remote peer.
+func (p *Peer) Version() uint64 {
+ return p.rw.version
+}
+
// Name returns the node name that the remote node advertised.
func (p *Peer) Name() string {
return p.rw.name
@@ -136,6 +173,36 @@ func (p *Peer) Caps() []Cap {
return p.rw.caps
}
+func (p *Peer) ReceiverMss() uint32 {
+ return p.rw.tc.receiverMss
+}
+
+func (p *Peer) SenderMss() uint32 {
+ return p.rw.tc.senderMss
+}
+
+func (p *Peer) Rtt() float64 {
+ return p.rw.tc.rtt
+}
+
+func (p *Peer) Srtt() float64 {
+ return p.rw.tc.srtt
+}
+
+func (p *Peer) Duration() float64 {
+ return monotime.Since(uint64(p.created)).Seconds()
+}
+
+// ListenPort returns the port number that the remote peer advertised.
+func (p *Peer) ListenPort() uint16 {
+ return p.rw.listenPort
+}
+
+// TCPPort returns the port number that the remote peer advertised through discovery.
+func (p *Peer) TCPPort() uint16 {
+ return p.rw.tcpPort
+}
+
// RemoteAddr returns the remote address of the network connection.
func (p *Peer) RemoteAddr() net.Addr {
return p.rw.fd.RemoteAddr()
@@ -174,6 +241,36 @@ func newPeer(conn *conn, protocols []Protocol) *Peer {
return p
}
+func (p *Peer) ConnInfoCtx(ctx ...interface{}) []interface{} {
+ return append(p.rw.connInfoCtx, ctx...)
+}
+
+func (p *Peer) ReceiverConnInfoCtx() []interface{} {
+ return p.ConnInfoCtx(
+ "mss", p.ReceiverMss(),
+ "rtt", p.Rtt(),
+ "srtt", p.Srtt(),
+ "duration", p.Duration(),
+ )
+}
+
+func (p *Peer) SenderConnInfoCtx() []interface{} {
+ return p.ConnInfoCtx(
+ "mss", p.SenderMss(),
+ "rtt", p.Rtt(),
+ "srtt", p.Srtt(),
+ "duration", p.Duration(),
+ )
+}
+
+func (p *Peer) IsInbound() bool {
+ return p.rw.isInbound()
+}
+
+func (p *Peer) ConnFlags() connFlag {
+ return p.rw.flags
+}
+
func (p *Peer) Log() log.Logger {
return p.log
}
@@ -222,7 +319,7 @@ loop:
}
close(p.closed)
- p.rw.close(reason)
+ p.rw.close(reason, p.SenderConnInfoCtx()...)
p.wg.Wait()
return remoteRequested, err
}
@@ -234,7 +331,7 @@ func (p *Peer) pingLoop() {
for {
select {
case <-ping.C:
- if err := SendItems(p.rw, pingMsg); err != nil {
+ if err := SendItems(p.rw, pingMsg, p.SenderConnInfoCtx()); err != nil {
p.protoErr <- err
return
}
@@ -253,7 +350,7 @@ func (p *Peer) readLoop(errc chan<- error) {
errc <- err
return
}
- msg.ReceivedAt = time.Now()
+ msg.PeerDuration = p.Duration()
if err = p.handle(msg); err != nil {
errc <- err
return
@@ -262,23 +359,35 @@ func (p *Peer) readLoop(errc chan<- error) {
}
func (p *Peer) handle(msg Msg) error {
+ connInfoCtx := p.ReceiverConnInfoCtx()
+ msgType, ok := devp2pCodeToString[msg.Code]
+ if !ok {
+ msgType = fmt.Sprintf("UNKNOWN_%v", msg.Code)
+ }
switch {
case msg.Code == pingMsg:
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, nil)
+ msg.Discard()
+ go SendItems(p.rw, pongMsg, connInfoCtx)
+ case msg.Code == pongMsg:
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, nil)
msg.Discard()
- go SendItems(p.rw, pongMsg)
case msg.Code == discMsg:
var reason [1]DiscReason
// This is the last message. We don't need to discard or
// check errors because, the connection will be closed after it.
- rlp.Decode(msg.Payload, &reason)
+ err := rlp.Decode(msg.Payload, &reason)
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, err)
return reason[0]
case msg.Code < baseProtocolLength:
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, nil)
// ignore other base protocol messages
return msg.Discard()
default:
// it's a subprotocol message
proto, err := p.getProto(msg.Code)
if err != nil {
+ log.MessageRx(msg.ReceivedAt, fmt.Sprintf("<= rw.Length {
- return newPeerError(errInvalidMsgCode, "not handled")
+ return total, newPeerError(errInvalidMsgCode, "not handled")
}
msg.Code += rw.offset
select {
case <-rw.wstart:
- err = rw.w.WriteMsg(msg)
+ total, err = rw.w.WriteMsg(msg)
// Report write status back to Peer.run. It will initiate
// shutdown if the error is non-nil and unblock the next write
// otherwise. The calling protocol code should exit for errors
@@ -391,7 +500,7 @@ func (rw *protoRW) WriteMsg(msg Msg) (err error) {
case <-rw.closed:
err = fmt.Errorf("shutting down")
}
- return err
+ return total, err
}
func (rw *protoRW) ReadMsg() (Msg, error) {
@@ -408,13 +517,19 @@ func (rw *protoRW) ReadMsg() (Msg, error) {
// peer. Sub-protocol independent fields are contained and initialized here, with
// protocol specifics delegated to all connected sub-protocols.
type PeerInfo struct {
- ID string `json:"id"` // Unique node identifier (also the encryption key)
- Name string `json:"name"` // Name of the node, including client type, version, OS, custom data
- Caps []string `json:"caps"` // Sum-protocols advertised by this particular peer
- Network struct {
+ ID string `json:"id"` // Unique node identifier (also the encryption key)
+ Name string `json:"name"` // Name of the node, including client type, version, OS, custom data
+ Caps []string `json:"caps"` // Sum-protocols advertised by this particular peer
+ SenderMss uint32 `json:"senderMss"`
+ ReceiverMss uint32 `json:"receiverMss"`
+ Rtt float64 `json:"rtt"`
+ Srtt float64 `json:"srtt"`
+ Duration float64 `json:"duration"`
+ Network struct {
LocalAddress string `json:"localAddress"` // Local endpoint of the TCP data connection
RemoteAddress string `json:"remoteAddress"` // Remote endpoint of the TCP data connection
} `json:"network"`
+ Conn string `json:"conn"`
Protocols map[string]interface{} `json:"protocols"` // Sub-protocol specific metadata fields
}
@@ -430,8 +545,13 @@ func (p *Peer) Info() *PeerInfo {
ID: p.ID().String(),
Name: p.Name(),
Caps: caps,
+ Conn: p.rw.flags.String(),
Protocols: make(map[string]interface{}),
}
+ info.SenderMss = p.SenderMss()
+ info.ReceiverMss = p.ReceiverMss()
+ info.Rtt = p.Rtt()
+ info.Srtt = p.Srtt()
info.Network.LocalAddress = p.LocalAddr().String()
info.Network.RemoteAddress = p.RemoteAddr().String()
@@ -447,5 +567,6 @@ func (p *Peer) Info() *PeerInfo {
}
info.Protocols[proto.Name] = protoInfo
}
+ info.Duration = p.Duration()
return info
}
diff --git a/p2p/peer_test.go b/p2p/peer_test.go
index a3e1c74fd876..a63913a17e58 100644
--- a/p2p/peer_test.go
+++ b/p2p/peer_test.go
@@ -45,8 +45,10 @@ var discard = Protocol{
func testPeer(protos []Protocol) (func(), *conn, *Peer, <-chan error) {
fd1, fd2 := net.Pipe()
- c1 := &conn{fd: fd1, transport: newTestTransport(randomID(), fd1)}
- c2 := &conn{fd: fd2, transport: newTestTransport(randomID(), fd2)}
+ tc1 := newTCPConn(fd1)
+ tc2 := newTCPConn(fd2)
+ c1 := &conn{fd: fd1, tc: tc1, transport: newTestTransport(randomID(), fd1, tc1)}
+ c2 := &conn{fd: fd2, tc: tc2, transport: newTestTransport(randomID(), fd2, tc2)}
for _, p := range protos {
c1.caps = append(c1.caps, p.cap())
c2.caps = append(c2.caps, p.cap())
@@ -103,10 +105,10 @@ func TestPeerProtoEncodeMsg(t *testing.T) {
Name: "a",
Length: 2,
Run: func(peer *Peer, rw MsgReadWriter) error {
- if err := SendItems(rw, 2); err == nil {
+ if err := SendItems(rw, 2, []interface{}{}); err == nil {
t.Error("expected error for out-of-range msg code, got nil")
}
- if err := SendItems(rw, 1, "foo", "bar"); err != nil {
+ if err := SendItems(rw, 1, []interface{}{}, "foo", "bar"); err != nil {
t.Errorf("write error: %v", err)
}
return nil
@@ -123,7 +125,7 @@ func TestPeerProtoEncodeMsg(t *testing.T) {
func TestPeerPing(t *testing.T) {
closer, rw, _, _ := testPeer(nil)
defer closer()
- if err := SendItems(rw, pingMsg); err != nil {
+ if err := SendItems(rw, pingMsg, []interface{}{}); err != nil {
t.Fatal(err)
}
if err := ExpectMsg(rw, pongMsg, nil); err != nil {
@@ -134,7 +136,7 @@ func TestPeerPing(t *testing.T) {
func TestPeerDisconnect(t *testing.T) {
closer, rw, _, disc := testPeer(nil)
defer closer()
- if err := SendItems(rw, discMsg, DiscQuitting); err != nil {
+ if err := SendItems(rw, discMsg, []interface{}{}, DiscQuitting); err != nil {
t.Fatal(err)
}
select {
@@ -169,8 +171,8 @@ func TestPeerDisconnectRace(t *testing.T) {
})
// Simulate incoming messages.
- go SendItems(rw, baseProtocolLength+1)
- go SendItems(rw, baseProtocolLength+2)
+ go SendItems(rw, baseProtocolLength+1, []interface{}{})
+ go SendItems(rw, baseProtocolLength+2, []interface{}{})
// Close the network connection.
go closer()
// Make protocol "closereq" return.
@@ -183,7 +185,7 @@ func TestPeerDisconnectRace(t *testing.T) {
}
// In some cases, simulate remote requesting a disconnect.
if maybe() {
- go SendItems(rw, discMsg, DiscQuitting)
+ go SendItems(rw, discMsg, []interface{}{}, DiscQuitting)
}
select {
diff --git a/p2p/protocol.go b/p2p/protocol.go
index ee747ba23dda..06cc16ee0972 100644
--- a/p2p/protocol.go
+++ b/p2p/protocol.go
@@ -19,7 +19,7 @@ package p2p
import (
"fmt"
- "github.com/ethereum/go-ethereum/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
)
// Protocol represents a P2P subprotocol implementation.
diff --git a/p2p/rlpx.go b/p2p/rlpx.go
index 24037ecc13b4..ba601a74b3fa 100644
--- a/p2p/rlpx.go
+++ b/p2p/rlpx.go
@@ -35,13 +35,14 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/ecies"
- "github.com/ethereum/go-ethereum/crypto/secp256k1"
- "github.com/ethereum/go-ethereum/crypto/sha3"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/rlp"
"github.com/golang/snappy"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/crypto/ecies"
+ "github.com/teamnsrg/ethereum-p2p/crypto/secp256k1"
+ "github.com/teamnsrg/ethereum-p2p/crypto/sha3"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
const (
@@ -55,7 +56,7 @@ const (
authMsgLen = sigLen + shaLen + pubLen + shaLen + 1
authRespLen = pubLen + shaLen + 1
- eciesOverhead = 65 /* pubkey */ + 16 /* IV */ + 32 /* MAC */
+ eciesOverhead = 65 + 16 + 32 /* pubkey + IV + MAC */
encAuthMsgLen = authMsgLen + eciesOverhead // size of encrypted pre-EIP-8 initiator handshake
encAuthRespLen = authRespLen + eciesOverhead // size of encrypted pre-EIP-8 handshake reply
@@ -78,14 +79,15 @@ var errPlainMessageTooLarge = errors.New("message length >= 16MB")
// It wraps the frame encoder with locks and read/write deadlines.
type rlpx struct {
fd net.Conn
+ tc *tcpConn
rmu, wmu sync.Mutex
rw *rlpxFrameRW
}
-func newRLPX(fd net.Conn) transport {
+func newRLPX(fd net.Conn, tc *tcpConn) transport {
fd.SetDeadline(time.Now().Add(handshakeTimeout))
- return &rlpx{fd: fd}
+ return &rlpx{fd: fd, tc: tc}
}
func (t *rlpx) ReadMsg() (Msg, error) {
@@ -95,21 +97,21 @@ func (t *rlpx) ReadMsg() (Msg, error) {
return t.rw.ReadMsg()
}
-func (t *rlpx) WriteMsg(msg Msg) error {
+func (t *rlpx) WriteMsg(msg Msg) (uint32, error) {
t.wmu.Lock()
defer t.wmu.Unlock()
t.fd.SetWriteDeadline(time.Now().Add(frameWriteTimeout))
return t.rw.WriteMsg(msg)
}
-func (t *rlpx) close(err error) {
+func (t *rlpx) close(err error, connInfoCtx ...interface{}) {
t.wmu.Lock()
defer t.wmu.Unlock()
// Tell the remote end why we're disconnecting if possible.
if t.rw != nil {
if r, ok := err.(DiscReason); ok && r != DiscNetworkError {
t.fd.SetWriteDeadline(time.Now().Add(discWriteTimeout))
- SendItems(t.rw, discMsg, r)
+ SendItems(t.rw, discMsg, connInfoCtx, r)
}
}
t.fd.Close()
@@ -119,14 +121,14 @@ func (t *rlpx) close(err error) {
// messages. the protocol handshake is the first authenticated message
// and also verifies whether the encryption handshake 'worked' and the
// remote side actually provided the right public key.
-func (t *rlpx) doProtoHandshake(our *protoHandshake) (their *protoHandshake, err error) {
+func (t *rlpx) doProtoHandshake(our *protoHandshake, connInfoCtx ...interface{}) (their *protoHandshake, err error) {
// Writing our handshake happens concurrently, we prefer
// returning the handshake read error. If the remote side
// disconnects us early with a valid reason, we should return it
// as the error so it can be tracked elsewhere.
werr := make(chan error, 1)
- go func() { werr <- Send(t.rw, handshakeMsg, our) }()
- if their, err = readProtocolHandshake(t.rw, our); err != nil {
+ go func() { werr <- Send(t.rw, handshakeMsg, our, connInfoCtx...) }()
+ if their, err = readProtocolHandshake(t.rw, our, connInfoCtx...); err != nil {
<-werr // make sure the write terminates too
return nil, err
}
@@ -139,7 +141,7 @@ func (t *rlpx) doProtoHandshake(our *protoHandshake) (their *protoHandshake, err
return their, nil
}
-func readProtocolHandshake(rw MsgReader, our *protoHandshake) (*protoHandshake, error) {
+func readProtocolHandshake(rw MsgReader, our *protoHandshake, connInfoCtx ...interface{}) (*protoHandshake, error) {
msg, err := rw.ReadMsg()
if err != nil {
return nil, err
@@ -147,22 +149,36 @@ func readProtocolHandshake(rw MsgReader, our *protoHandshake) (*protoHandshake,
if msg.Size > baseProtocolMaxMsgSize {
return nil, fmt.Errorf("message too big")
}
+ connInfoCtx = append(connInfoCtx,
+ "srtt", msg.Srtt,
+ "duration", msg.PeerDuration,
+ )
+ msgType, ok := devp2pCodeToString[msg.Code]
+ if !ok {
+ msgType = fmt.Sprintf("UNKNOWN_%v", msg.Code)
+ }
if msg.Code == discMsg {
// Disconnect before protocol handshake is valid according to the
// spec and we send it ourself if the posthanshake checks fail.
// We can't return the reason directly, though, because it is echoed
// back otherwise. Wrap it in a string instead.
var reason [1]DiscReason
- rlp.Decode(msg.Payload, &reason)
+ err := rlp.Decode(msg.Payload, &reason)
+ log.MessageRx(msg.ReceivedAt, "<<"+msgType, msg.Size, msg.EncodedSize, connInfoCtx, err)
return nil, reason[0]
}
if msg.Code != handshakeMsg {
+ log.MessageRx(msg.ReceivedAt, "< maxUint24 {
- return errPlainMessageTooLarge
+ return total, errPlainMessageTooLarge
}
payload, _ := ioutil.ReadAll(msg.Payload)
payload = snappy.Encode(nil, payload)
@@ -609,7 +628,7 @@ func (rw *rlpxFrameRW) WriteMsg(msg Msg) error {
headbuf := make([]byte, 32)
fsize := uint32(len(ptype)) + msg.Size
if fsize > maxUint24 {
- return errors.New("message size overflows uint24")
+ return total, errors.New("message size overflows uint24")
}
putInt24(fsize, headbuf) // TODO: check overflow
copy(headbuf[3:], zeroHeader)
@@ -618,22 +637,26 @@ func (rw *rlpxFrameRW) WriteMsg(msg Msg) error {
// write header MAC
copy(headbuf[16:], updateMAC(rw.egressMAC, rw.macCipher, headbuf[:16]))
if _, err := rw.conn.Write(headbuf); err != nil {
- return err
+ return total, err
}
+ total += uint32(len(headbuf))
// write encrypted frame, updating the egress MAC hash with
// the data written to conn.
tee := cipher.StreamWriter{S: rw.enc, W: io.MultiWriter(rw.conn, rw.egressMAC)}
if _, err := tee.Write(ptype); err != nil {
- return err
+ return total, err
}
+ total += uint32(len(ptype))
if _, err := io.Copy(tee, msg.Payload); err != nil {
- return err
+ return total, err
}
+ total += msg.Size
if padding := fsize % 16; padding > 0 {
if _, err := tee.Write(zero16[:16-padding]); err != nil {
- return err
+ return total, err
}
+ total += uint32(len(zero16[:16-padding]))
}
// write frame MAC. egress MAC hash is up to date because
@@ -641,7 +664,12 @@ func (rw *rlpxFrameRW) WriteMsg(msg Msg) error {
fmacseed := rw.egressMAC.Sum(nil)
mac := updateMAC(rw.egressMAC, rw.macCipher, fmacseed)
_, err := rw.conn.Write(mac)
- return err
+ total += uint32(len(mac))
+ rw.tc.updateRtt(rw.tc.getTCPInfo())
+ rw.tc.updateSrtt(rw.tc.getTCPInfo())
+ msg.Rtt = rw.tc.rtt
+ msg.Srtt = rw.tc.srtt
+ return total, err
}
func (rw *rlpxFrameRW) ReadMsg() (msg Msg, err error) {
@@ -710,6 +738,13 @@ func (rw *rlpxFrameRW) ReadMsg() (msg Msg, err error) {
}
msg.Size, msg.Payload = uint32(size), bytes.NewReader(payload)
}
+
+ msg.ReceivedAt = time.Now()
+ rw.tc.updateRtt(rw.tc.getTCPInfo())
+ rw.tc.updateSrtt(rw.tc.getTCPInfo())
+ msg.Rtt = rw.tc.rtt
+ msg.Srtt = rw.tc.srtt
+ msg.EncodedSize = 32 + rsize + 16
return msg, nil
}
diff --git a/p2p/rlpx_test.go b/p2p/rlpx_test.go
index f4cefa650bd4..ce41e50ea4fd 100644
--- a/p2p/rlpx_test.go
+++ b/p2p/rlpx_test.go
@@ -31,11 +31,11 @@ import (
"time"
"github.com/davecgh/go-spew/spew"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/ecies"
- "github.com/ethereum/go-ethereum/crypto/sha3"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/crypto/ecies"
+ "github.com/teamnsrg/ethereum-p2p/crypto/sha3"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
func TestSharedSecret(t *testing.T) {
@@ -87,7 +87,7 @@ func testEncHandshake(token []byte) error {
prv0, _ = crypto.GenerateKey()
prv1, _ = crypto.GenerateKey()
fd0, fd1 = net.Pipe()
- c0, c1 = newRLPX(fd0).(*rlpx), newRLPX(fd1).(*rlpx)
+ c0, c1 = newRLPX(fd0, newTCPConn(fd0)).(*rlpx), newRLPX(fd1, newTCPConn(fd1)).(*rlpx)
output = make(chan result)
)
@@ -164,7 +164,7 @@ func TestProtocolHandshake(t *testing.T) {
go func() {
defer wg.Done()
defer fd1.Close()
- rlpx := newRLPX(fd0)
+ rlpx := newRLPX(fd0, newTCPConn(fd0))
remid, err := rlpx.doEncHandshake(prv0, node1)
if err != nil {
t.Errorf("dial side enc handshake failed: %v", err)
@@ -190,7 +190,7 @@ func TestProtocolHandshake(t *testing.T) {
go func() {
defer wg.Done()
defer fd1.Close()
- rlpx := newRLPX(fd1)
+ rlpx := newRLPX(fd1, newTCPConn(fd1))
remid, err := rlpx.doEncHandshake(prv1, nil)
if err != nil {
t.Errorf("listen side enc handshake failed: %v", err)
@@ -266,7 +266,7 @@ func TestProtocolHandshakeErrors(t *testing.T) {
func TestRLPXFrameFake(t *testing.T) {
buf := new(bytes.Buffer)
hash := fakeHash([]byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1})
- rw := newRLPXFrameRW(buf, secrets{
+ rw := newRLPXFrameRW(buf, &tcpConn{}, secrets{
AES: crypto.Keccak256(),
MAC: crypto.Keccak256(),
IngressMAC: hash,
@@ -337,7 +337,7 @@ func TestRLPXFrameRW(t *testing.T) {
}
s1.EgressMAC.Write(egressMACinit)
s1.IngressMAC.Write(ingressMACinit)
- rw1 := newRLPXFrameRW(conn, s1)
+ rw1 := newRLPXFrameRW(conn, &tcpConn{}, s1)
s2 := secrets{
AES: aesSecret,
@@ -347,7 +347,7 @@ func TestRLPXFrameRW(t *testing.T) {
}
s2.EgressMAC.Write(ingressMACinit)
s2.IngressMAC.Write(egressMACinit)
- rw2 := newRLPXFrameRW(conn, s2)
+ rw2 := newRLPXFrameRW(conn, &tcpConn{}, s2)
// send some messages
for i := 0; i < 10; i++ {
diff --git a/p2p/server.go b/p2p/server.go
index d1d578401bb1..2513a8db5aca 100644
--- a/p2p/server.go
+++ b/p2p/server.go
@@ -22,17 +22,18 @@ import (
"errors"
"fmt"
"net"
+ "strings"
"sync"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/mclock"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/p2p/discv5"
- "github.com/ethereum/go-ethereum/p2p/nat"
- "github.com/ethereum/go-ethereum/p2p/netutil"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/mclock"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discv5"
+ "github.com/teamnsrg/ethereum-p2p/p2p/nat"
+ "github.com/teamnsrg/ethereum-p2p/p2p/netutil"
)
const (
@@ -58,6 +59,15 @@ var errServerStopped = errors.New("server stopped")
// Config holds Server options.
type Config struct {
+ // NoMaxPeers ignores/overwrites MaxPeers, allowing unlimited number of peer connections.
+ NoMaxPeers bool
+
+ // NoListen disables the TCP listener.
+ NoListen bool
+
+ // Blacklist is the list of IP networks that we should not connect to
+ Blacklist *netutil.Netlist `toml:",omitempty"`
+
// This field must be set to a valid secp256k1 private key.
PrivateKey *ecdsa.PrivateKey `toml:"-"`
@@ -143,18 +153,22 @@ type Config struct {
// Server manages all peer connections.
type Server struct {
+ dialstate *dialstate
+ StrReplacer *strings.Replacer
+
// Config fields may not be modified while the server is running.
Config
// Hooks for testing. These are useful because we can inhibit
// the whole protocol stack.
- newTransport func(net.Conn) transport
+ newTransport func(net.Conn, *tcpConn) transport
newPeerHook func(*Peer)
lock sync.Mutex // protects running
running bool
ntab discoverTable
+ udp udp
listener net.Listener
ourHandshake *protoHandshake
lastLookup time.Time
@@ -164,14 +178,19 @@ type Server struct {
peerOp chan peerOpFunc
peerOpDone chan struct{}
- quit chan struct{}
- addstatic chan *discover.Node
- removestatic chan *discover.Node
- posthandshake chan *conn
- addpeer chan *conn
- delpeer chan peerDrop
- loopWG sync.WaitGroup // loop, listenLoop
- peerFeed event.Feed
+ quit chan struct{}
+ addstatic chan *discover.Node
+ addstaticbatch chan []*discover.Node
+ removestatic chan *discover.Node
+ posthandshake chan *conn
+ addpeer chan *conn
+ delpeer chan peerDrop
+ loopWG sync.WaitGroup // loop, listenLoop
+ peerFeed event.Feed
+}
+
+type udp interface {
+ SetBlacklist(blacklist *netutil.Netlist)
}
type peerOpFunc func(map[discover.NodeID]*Peer)
@@ -195,18 +214,24 @@ const (
// during the two handshakes.
type conn struct {
fd net.Conn
+ tc *tcpConn
transport
- flags connFlag
- cont chan error // The run loop uses cont to signal errors to SetupConn.
- id discover.NodeID // valid after the encryption handshake
- caps []Cap // valid after the protocol handshake
- name string // valid after the protocol handshake
+
+ flags connFlag
+ cont chan error // The run loop uses cont to signal errors to SetupConn.
+ id discover.NodeID // valid after the encryption handshake
+ version uint64 // valid after the protocol handshake
+ caps []Cap // valid after the protocol handshake
+ name string // valid after the protocol handshake
+ listenPort uint16 // valid after the protocol handshake
+ tcpPort uint16 // valid after the protocol handshake
+ connInfoCtx []interface{}
}
type transport interface {
// The two handshakes.
doEncHandshake(prv *ecdsa.PrivateKey, dialDest *discover.Node) (discover.NodeID, error)
- doProtoHandshake(our *protoHandshake) (*protoHandshake, error)
+ doProtoHandshake(our *protoHandshake, connInfoCtx ...interface{}) (*protoHandshake, error)
// The MsgReadWriter can only be used after the encryption
// handshake has completed. The code uses conn.id to track this
// by setting it to a non-nil value after the encryption handshake.
@@ -214,7 +239,7 @@ type transport interface {
// transports must provide Close because we use MsgPipe in some of
// the tests. Closing the actual network connection doesn't do
// anything in those tests because NsgPipe doesn't use it.
- close(err error)
+ close(err error, connInfoCtx ...interface{})
}
func (c *conn) String() string {
@@ -250,6 +275,13 @@ func (c *conn) is(f connFlag) bool {
return c.flags&f != 0
}
+func (c *conn) isInbound() bool {
+ if c.flags&inboundConn != 0 || c.flags&trustedConn != 0 {
+ return true
+ }
+ return false
+}
+
// Peers returns all connected peers.
func (srv *Server) Peers() []*Peer {
var ps []*Peer
@@ -279,6 +311,13 @@ func (srv *Server) PeerCount() int {
return count
}
+func (srv *Server) AddPeers(nodes []*discover.Node) {
+ select {
+ case srv.addstaticbatch <- nodes:
+ case <-srv.quit:
+ }
+}
+
// AddPeer connects to the given node and maintains the connection until the
// server is shut down. If the connection fails for any reason, the server will
// attempt to reconnect the peer.
@@ -342,11 +381,11 @@ func (srv *Server) Stop() {
return
}
srv.running = false
+ close(srv.quit)
if srv.listener != nil {
// this unblocks listener Accept
srv.listener.Close()
}
- close(srv.quit)
srv.loopWG.Wait()
}
@@ -358,6 +397,7 @@ func (srv *Server) Start() (err error) {
if srv.running {
return errors.New("server already running")
}
+
srv.running = true
log.Info("Starting P2P networking")
@@ -376,13 +416,21 @@ func (srv *Server) Start() (err error) {
srv.delpeer = make(chan peerDrop)
srv.posthandshake = make(chan *conn)
srv.addstatic = make(chan *discover.Node)
+ srv.addstaticbatch = make(chan []*discover.Node)
srv.removestatic = make(chan *discover.Node)
srv.peerOp = make(chan peerOpFunc)
srv.peerOpDone = make(chan struct{})
+ // initiate string replacer
+ srv.StrReplacer = strings.NewReplacer(
+ "|", "",
+ " ", "",
+ "'", "",
+ "\"", "")
+
// node table
if !srv.NoDiscovery {
- ntab, err := discover.ListenUDP(srv.PrivateKey, srv.ListenAddr, srv.NAT, srv.NodeDatabase, srv.NetRestrict)
+ ntab, udp, err := discover.ListenUDP(srv.PrivateKey, srv.ListenAddr, srv.NAT, srv.NodeDatabase, srv.NetRestrict, srv.Blacklist)
if err != nil {
return err
}
@@ -390,6 +438,7 @@ func (srv *Server) Start() (err error) {
return err
}
srv.ntab = ntab
+ srv.udp = udp
}
if srv.DiscoveryV5 {
@@ -408,6 +457,8 @@ func (srv *Server) Start() (err error) {
dynPeers = 0
}
dialer := newDialState(srv.StaticNodes, srv.BootstrapNodes, srv.ntab, dynPeers, srv.NetRestrict)
+ dialer.blacklist = srv.Blacklist
+ srv.dialstate = dialer
// handshake
srv.ourHandshake = &protoHandshake{Version: baseProtocolVersion, Name: srv.Name, ID: discover.PubkeyID(&srv.PrivateKey.PublicKey)}
@@ -415,7 +466,7 @@ func (srv *Server) Start() (err error) {
srv.ourHandshake.Caps = append(srv.ourHandshake.Caps, p.cap())
}
// listen/dial
- if srv.ListenAddr != "" {
+ if !srv.NoListen && srv.ListenAddr != "" {
if err := srv.startListening(); err != nil {
return err
}
@@ -459,6 +510,39 @@ type dialer interface {
removeStatic(*discover.Node)
}
+func (srv *Server) RedialList() []string {
+ var nodes []string
+ for id, t := range srv.dialstate.static {
+ node := t.dest
+ addr := &net.TCPAddr{IP: node.IP, Port: int(node.TCP)}
+ lastSuccess := fmt.Sprintf("%.6f", float64(t.lastSuccess.UnixNano())/1e9)
+ nodeStr := fmt.Sprintf("%s|%v|%s", id.String(), addr, lastSuccess)
+ nodes = append(nodes, nodeStr)
+ }
+ return nodes
+}
+
+func (srv *Server) AddBlacklist(cidrs string) error {
+ if srv.Blacklist == nil {
+ if list, err := netutil.ParseNetlist(cidrs); err != nil {
+ return err
+ } else {
+ srv.Blacklist = list
+ srv.dialstate.blacklist = list
+ srv.udp.SetBlacklist(list)
+ }
+ } else {
+ ws := strings.NewReplacer(" ", "", "\n", "", "\t", "")
+ masks := strings.Split(ws.Replace(cidrs), ",")
+ for _, mask := range masks {
+ if err := srv.Blacklist.AddNonDuplicate(mask); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
func (srv *Server) run(dialstate dialer) {
defer srv.loopWG.Done()
var (
@@ -477,6 +561,8 @@ func (srv *Server) run(dialstate dialer) {
// removes t from runningTasks
delTask := func(t task) {
+ log.Task("DONE", t.TaskInfoCtx())
+ dialstate.taskDone(t, time.Now())
for i := range runningTasks {
if runningTasks[i] == t {
runningTasks = append(runningTasks[:i], runningTasks[i+1:]...)
@@ -489,7 +575,7 @@ func (srv *Server) run(dialstate dialer) {
i := 0
for ; len(runningTasks) < maxActiveDialTasks && i < len(ts); i++ {
t := ts[i]
- log.Trace("New dial task", "task", t)
+ log.Task("NEW", t.TaskInfoCtx())
go func() { t.Do(srv); taskdone <- t }()
runningTasks = append(runningTasks, t)
}
@@ -501,7 +587,8 @@ func (srv *Server) run(dialstate dialer) {
// Query dialer for new tasks and start as many as possible now.
if len(runningTasks) < maxActiveDialTasks {
nt := dialstate.newTasks(len(runningTasks)+len(queuedTasks), peers, time.Now())
- queuedTasks = append(queuedTasks, startTasks(nt)...)
+ queuedTasks = append(queuedTasks, nt...)
+ queuedTasks = append(queuedTasks[:0], startTasks(queuedTasks)...)
}
}
@@ -513,6 +600,14 @@ running:
case <-srv.quit:
// The server was stopped. Run the cleanup logic.
break running
+ case nodes := <-srv.addstaticbatch:
+ // This channel is used by AddPeers to add multiple nodes to the
+ // ephemeral static peer list at once. Add it to the dialer,
+ // it will keep the node connected.
+ for _, n := range nodes {
+ log.Debug("Adding static node", "node", n)
+ dialstate.addStatic(n)
+ }
case n := <-srv.addstatic:
// This channel is used by AddPeer to add to the
// ephemeral static peer list. Add it to the dialer,
@@ -533,11 +628,6 @@ running:
op(peers)
srv.peerOpDone <- struct{}{}
case t := <-taskdone:
- // A task got done. Tell dialstate about it so it
- // can update its state and remove it from the active
- // tasks list.
- log.Trace("Dial task done", "task", t)
- dialstate.taskDone(t, time.Now())
delTask(t)
case c := <-srv.posthandshake:
// A connection has passed the encryption handshake so
@@ -620,7 +710,7 @@ func (srv *Server) protoHandshakeChecks(peers map[discover.NodeID]*Peer, c *conn
func (srv *Server) encHandshakeChecks(peers map[discover.NodeID]*Peer, c *conn) error {
switch {
- case !c.is(trustedConn|staticDialedConn) && len(peers) >= srv.MaxPeers:
+ case !srv.NoMaxPeers && !c.is(trustedConn|staticDialedConn) && len(peers) >= srv.MaxPeers:
return DiscTooManyPeers
case peers[c.id] != nil:
return DiscAlreadyConnected
@@ -654,6 +744,7 @@ func (srv *Server) listenLoop() {
}
for {
+ log.Debug(fmt.Sprintf("Remaining handshake tokens: %d", len(slots)))
// Wait for a handshake slot before accepting.
<-slots
@@ -676,7 +767,17 @@ func (srv *Server) listenLoop() {
// Reject connections that do not match NetRestrict.
if srv.NetRestrict != nil {
if tcp, ok := fd.RemoteAddr().(*net.TCPAddr); ok && !srv.NetRestrict.Contains(tcp.IP) {
- log.Debug("Rejected conn (not whitelisted in NetRestrict)", "addr", fd.RemoteAddr())
+ log.Debug("Rejected conn (not whitelisted in NetRestrict)", "addr", fd.RemoteAddr(), "transport", "tcp")
+ fd.Close()
+ slots <- struct{}{}
+ continue
+ }
+ }
+
+ // Reject connections that match Blacklist.
+ if srv.Blacklist != nil {
+ if tcp, ok := fd.RemoteAddr().(*net.TCPAddr); ok && srv.Blacklist.Contains(tcp.IP) {
+ log.Debug("Rejected conn (blacklisted)", "addr", fd.RemoteAddr(), "transport", "tcp")
fd.Close()
slots <- struct{}{}
continue
@@ -703,7 +804,8 @@ func (srv *Server) SetupConn(fd net.Conn, flags connFlag, dialDest *discover.Nod
srv.lock.Lock()
running := srv.running
srv.lock.Unlock()
- c := &conn{fd: fd, transport: srv.newTransport(fd), flags: flags, cont: make(chan error)}
+ tc := newTCPConn(fd)
+ c := &conn{fd: fd, tc: tc, transport: srv.newTransport(fd, tc), flags: flags, cont: make(chan error)}
if !running {
c.close(errServerStopped)
return
@@ -715,34 +817,45 @@ func (srv *Server) SetupConn(fd net.Conn, flags connFlag, dialDest *discover.Nod
c.close(err)
return
}
+ c.connInfoCtx = []interface{}{
+ "id", c.id.String(),
+ "addr", c.fd.RemoteAddr().String(),
+ "conn", c.flags.String(),
+ }
+ receiverConnInfoCtx := append(c.connInfoCtx,
+ "mss", c.tc.receiverMss,
+ )
+ senderConnInfoCtx := append(c.connInfoCtx,
+ "mss", c.tc.senderMss,
+ )
clog := log.New("id", c.id, "addr", c.fd.RemoteAddr(), "conn", c.flags)
// For dialed connections, check that the remote public key matches.
if dialDest != nil && c.id != dialDest.ID {
- c.close(DiscUnexpectedIdentity)
clog.Trace("Dialed identity mismatch", "want", c, dialDest.ID)
+ c.close(DiscUnexpectedIdentity, senderConnInfoCtx...)
return
}
if err := srv.checkpoint(c, srv.posthandshake); err != nil {
clog.Trace("Rejected peer before protocol handshake", "err", err)
- c.close(err)
+ c.close(err, senderConnInfoCtx...)
return
}
// Run the protocol handshake
- phs, err := c.doProtoHandshake(srv.ourHandshake)
+ phs, err := c.doProtoHandshake(srv.ourHandshake, receiverConnInfoCtx...)
if err != nil {
clog.Trace("Failed proto handshake", "err", err)
- c.close(err)
+ c.close(err, senderConnInfoCtx...)
return
}
if phs.ID != c.id {
clog.Trace("Wrong devp2p handshake identity", "err", phs.ID)
- c.close(DiscUnexpectedIdentity)
+ c.close(DiscUnexpectedIdentity, senderConnInfoCtx...)
return
}
- c.caps, c.name = phs.Caps, phs.Name
+ c.version, c.caps, c.name = phs.Version, phs.Caps, phs.Name
if err := srv.checkpoint(c, srv.addpeer); err != nil {
clog.Trace("Rejected peer", "err", err)
- c.close(err)
+ c.close(err, senderConnInfoCtx...)
return
}
// If the checks completed successfully, runPeer has now been
diff --git a/p2p/server_test.go b/p2p/server_test.go
index 11dd83e5d665..7da755769ce5 100644
--- a/p2p/server_test.go
+++ b/p2p/server_test.go
@@ -25,9 +25,9 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/sha3"
- "github.com/ethereum/go-ethereum/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/crypto/sha3"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
)
func init() {
@@ -41,9 +41,9 @@ type testTransport struct {
closeErr error
}
-func newTestTransport(id discover.NodeID, fd net.Conn) transport {
- wrapped := newRLPX(fd).(*rlpx)
- wrapped.rw = newRLPXFrameRW(fd, secrets{
+func newTestTransport(id discover.NodeID, fd net.Conn, tc *tcpConn) transport {
+ wrapped := newRLPX(fd, tc).(*rlpx)
+ wrapped.rw = newRLPXFrameRW(fd, tc, secrets{
MAC: zero16,
AES: zero16,
IngressMAC: sha3.NewKeccak256(),
@@ -56,11 +56,11 @@ func (c *testTransport) doEncHandshake(prv *ecdsa.PrivateKey, dialDest *discover
return c.id, nil
}
-func (c *testTransport) doProtoHandshake(our *protoHandshake) (*protoHandshake, error) {
+func (c *testTransport) doProtoHandshake(our *protoHandshake, connInfoCtx ...interface{}) (*protoHandshake, error) {
return &protoHandshake{ID: c.id, Name: "test"}, nil
}
-func (c *testTransport) close(err error) {
+func (c *testTransport) close(err error, connInfoCtx ...interface{}) {
c.rlpx.fd.Close()
c.closeErr = err
}
@@ -75,7 +75,7 @@ func startTestServer(t *testing.T, id discover.NodeID, pf func(*Peer)) *Server {
server := &Server{
Config: config,
newPeerHook: pf,
- newTransport: func(fd net.Conn) transport { return newTestTransport(id, fd) },
+ newTransport: func(fd net.Conn, tc *tcpConn) transport { return newTestTransport(id, fd, tc) },
}
if err := server.Start(); err != nil {
t.Fatalf("Could not start server: %v", err)
@@ -295,11 +295,14 @@ type taskgen struct {
func (tg taskgen) newTasks(running int, peers map[discover.NodeID]*Peer, now time.Time) []task {
return tg.newFunc(running, peers)
}
+
func (tg taskgen) taskDone(t task, now time.Time) {
tg.doneFunc(t)
}
+
func (tg taskgen) addStatic(*discover.Node) {
}
+
func (tg taskgen) removeStatic(*discover.Node) {
}
@@ -312,6 +315,10 @@ func (t *testTask) Do(srv *Server) {
t.called = true
}
+func (t *testTask) TaskInfoCtx() []interface{} {
+ return nil
+}
+
// This test checks that connections are disconnected
// just after the encryption handshake when the server is
// at capacity. Trusted connections should still be accepted.
@@ -332,8 +339,9 @@ func TestServerAtCap(t *testing.T) {
newconn := func(id discover.NodeID) *conn {
fd, _ := net.Pipe()
- tx := newTestTransport(id, fd)
- return &conn{fd: fd, transport: tx, flags: inboundConn, id: id, cont: make(chan error)}
+ tc := newTCPConn(fd)
+ tx := newTestTransport(id, fd, tc)
+ return &conn{fd: fd, tc: tc, transport: tx, flags: inboundConn, id: id, cont: make(chan error)}
}
// Inject a few connections to fill up the peer set.
@@ -427,7 +435,7 @@ func TestServerSetupConn(t *testing.T) {
NoDial: true,
Protocols: []Protocol{discard},
},
- newTransport: func(fd net.Conn) transport { return test.tt },
+ newTransport: func(fd net.Conn, tc *tcpConn) transport { return test.tt },
}
if !test.dontstart {
if err := srv.Start(); err != nil {
@@ -446,7 +454,8 @@ func TestServerSetupConn(t *testing.T) {
}
type setupTransport struct {
- id discover.NodeID
+ id discover.NodeID
+ *rlpx
encHandshakeErr error
phs *protoHandshake
@@ -460,20 +469,20 @@ func (c *setupTransport) doEncHandshake(prv *ecdsa.PrivateKey, dialDest *discove
c.calls += "doEncHandshake,"
return c.id, c.encHandshakeErr
}
-func (c *setupTransport) doProtoHandshake(our *protoHandshake) (*protoHandshake, error) {
+func (c *setupTransport) doProtoHandshake(our *protoHandshake, connInfoCtx ...interface{}) (*protoHandshake, error) {
c.calls += "doProtoHandshake,"
if c.protoHandshakeErr != nil {
return nil, c.protoHandshakeErr
}
return c.phs, nil
}
-func (c *setupTransport) close(err error) {
+func (c *setupTransport) close(err error, connInfoCtx ...interface{}) {
c.calls += "close,"
c.closeErr = err
}
// setupConn shouldn't write to/read from the connection.
-func (c *setupTransport) WriteMsg(Msg) error {
+func (c *setupTransport) WriteMsg(Msg) (uint32, error) {
panic("WriteMsg called on setupTransport")
}
func (c *setupTransport) ReadMsg() (Msg, error) {
diff --git a/p2p/simulations/adapters/docker.go b/p2p/simulations/adapters/docker.go
index 022314b3d7d1..37291f9aed17 100644
--- a/p2p/simulations/adapters/docker.go
+++ b/p2p/simulations/adapters/docker.go
@@ -28,8 +28,8 @@ import (
"strings"
"github.com/docker/docker/pkg/reexec"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/node"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
)
// DockerAdapter is a NodeAdapter which runs simulation nodes inside Docker
diff --git a/p2p/simulations/adapters/exec.go b/p2p/simulations/adapters/exec.go
index bdb92cc1d2f6..44edf6adb4a4 100644
--- a/p2p/simulations/adapters/exec.go
+++ b/p2p/simulations/adapters/exec.go
@@ -36,11 +36,11 @@ import (
"time"
"github.com/docker/docker/pkg/reexec"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/node"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
"golang.org/x/net/websocket"
)
diff --git a/p2p/simulations/adapters/inproc.go b/p2p/simulations/adapters/inproc.go
index c97188defc80..aa2e2dd08b69 100644
--- a/p2p/simulations/adapters/inproc.go
+++ b/p2p/simulations/adapters/inproc.go
@@ -23,11 +23,11 @@ import (
"net"
"sync"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/node"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
// SimAdapter is a NodeAdapter which creates in-memory simulation nodes and
diff --git a/p2p/simulations/adapters/types.go b/p2p/simulations/adapters/types.go
index ed6cfc504642..182cd114eae0 100644
--- a/p2p/simulations/adapters/types.go
+++ b/p2p/simulations/adapters/types.go
@@ -25,11 +25,11 @@ import (
"os"
"github.com/docker/docker/pkg/reexec"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/node"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
// Node represents a node in a simulation network which is created by a
diff --git a/p2p/simulations/examples/ping-pong.go b/p2p/simulations/examples/ping-pong.go
index 6a0ead53a5cc..e145e5c00d15 100644
--- a/p2p/simulations/examples/ping-pong.go
+++ b/p2p/simulations/examples/ping-pong.go
@@ -25,13 +25,13 @@ import (
"sync/atomic"
"time"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/p2p/simulations"
- "github.com/ethereum/go-ethereum/p2p/simulations/adapters"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/node"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/p2p/simulations"
+ "github.com/teamnsrg/ethereum-p2p/p2p/simulations/adapters"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
var adapterType = flag.String("adapter", "sim", `node adapter to use (one of "sim", "exec" or "docker")`)
diff --git a/p2p/simulations/http.go b/p2p/simulations/http.go
index 3fa8b9292595..ad247d230557 100644
--- a/p2p/simulations/http.go
+++ b/p2p/simulations/http.go
@@ -28,12 +28,12 @@ import (
"strconv"
"strings"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/p2p/simulations/adapters"
- "github.com/ethereum/go-ethereum/rpc"
"github.com/julienschmidt/httprouter"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/p2p/simulations/adapters"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
"golang.org/x/net/websocket"
)
diff --git a/p2p/simulations/http_test.go b/p2p/simulations/http_test.go
index 677a8fb147d8..7b188d0408a7 100644
--- a/p2p/simulations/http_test.go
+++ b/p2p/simulations/http_test.go
@@ -27,12 +27,12 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/p2p/simulations/adapters"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/node"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/p2p/simulations/adapters"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
// testService implements the node.Service interface and provides protocols
diff --git a/p2p/simulations/network.go b/p2p/simulations/network.go
index 06890ffcf24e..1b7476eebe22 100644
--- a/p2p/simulations/network.go
+++ b/p2p/simulations/network.go
@@ -23,11 +23,11 @@ import (
"fmt"
"sync"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/p2p/simulations/adapters"
+ "github.com/teamnsrg/ethereum-p2p/event"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/p2p/simulations/adapters"
)
// NetworkConfig defines configuration options for starting a Network
diff --git a/p2p/simulations/network_test.go b/p2p/simulations/network_test.go
index 2a062121be45..f3e5b00af676 100644
--- a/p2p/simulations/network_test.go
+++ b/p2p/simulations/network_test.go
@@ -22,8 +22,8 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/p2p/simulations/adapters"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/p2p/simulations/adapters"
)
// TestNetworkSimulation creates a multi-node simulation network with each node
diff --git a/p2p/simulations/simulation.go b/p2p/simulations/simulation.go
index 28886e924aa4..7f3ed0b3d920 100644
--- a/p2p/simulations/simulation.go
+++ b/p2p/simulations/simulation.go
@@ -20,7 +20,7 @@ import (
"context"
"time"
- "github.com/ethereum/go-ethereum/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
)
// Simulation provides a framework for running actions in a simulated network
diff --git a/p2p/tcpinfo.go b/p2p/tcpinfo.go
new file mode 100644
index 000000000000..e8b354ea3efc
--- /dev/null
+++ b/p2p/tcpinfo.go
@@ -0,0 +1,48 @@
+package p2p
+
+import (
+ "net"
+
+ "github.com/mikioh/tcp"
+ "github.com/mikioh/tcpinfo"
+)
+
+type tcpConn struct {
+ *tcp.Conn
+
+ receiverMss uint32
+ senderMss uint32
+ rtt float64 // recent rtt
+ srtt float64 // smoothed rtt
+}
+
+func (tc *tcpConn) getTCPInfo() *tcpinfo.Info {
+ var o tcpinfo.Info
+ var b [256]byte
+ i, err := tc.Conn.Option(o.Level(), o.Name(), b[:])
+ if err != nil {
+ return nil
+ }
+ info, ok := i.(*tcpinfo.Info)
+ if !ok {
+ return nil
+ }
+ return info
+}
+
+func newTCPConn(conn net.Conn) *tcpConn {
+ c, err := tcp.NewConn(conn)
+ if err != nil {
+ return &tcpConn{}
+ }
+ tc := &tcpConn{Conn: c}
+ info := tc.getTCPInfo()
+ if info == nil {
+ return tc
+ }
+ tc.receiverMss = uint32(info.ReceiverMSS)
+ tc.senderMss = uint32(info.SenderMSS)
+ tc.updateRtt(info)
+ tc.updateSrtt(info)
+ return tc
+}
diff --git a/p2p/tcpinfo_darwin.go b/p2p/tcpinfo_darwin.go
new file mode 100644
index 000000000000..409bf5b4797b
--- /dev/null
+++ b/p2p/tcpinfo_darwin.go
@@ -0,0 +1,19 @@
+// +build darwin
+
+package p2p
+
+import "github.com/mikioh/tcpinfo"
+
+// recent rtt in seconds
+func (tc *tcpConn) updateRtt(info *tcpinfo.Info) {
+ if info != nil {
+ tc.rtt = float64(info.RTT) / 1e9
+ }
+}
+
+// Srtt in seconds
+func (tc *tcpConn) updateSrtt(info *tcpinfo.Info) {
+ if info != nil {
+ tc.srtt = float64(info.Sys.SRTT) / 1e9
+ }
+}
diff --git a/p2p/tcpinfo_linux.go b/p2p/tcpinfo_linux.go
new file mode 100644
index 000000000000..4283038d6897
--- /dev/null
+++ b/p2p/tcpinfo_linux.go
@@ -0,0 +1,19 @@
+// +build linux
+
+package p2p
+
+import "github.com/mikioh/tcpinfo"
+
+// recent rtt in seconds
+func (tc *tcpConn) updateRtt(info *tcpinfo.Info) {
+ if info != nil {
+ tc.rtt = float64(info.Sys.ReceiverRTT) / 1e9
+ }
+}
+
+// Srtt in seconds
+func (tc *tcpConn) updateSrtt(info *tcpinfo.Info) {
+ if info != nil {
+ tc.srtt = float64(info.RTT) / 1e9
+ }
+}
diff --git a/params/config.go b/params/config.go
index 345f6394ab4b..dcfe25f8afa4 100644
--- a/params/config.go
+++ b/params/config.go
@@ -20,7 +20,7 @@ import (
"fmt"
"math/big"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
var (
@@ -105,7 +105,7 @@ type ChainConfig struct {
HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead)
- DAOForkBlock *big.Int `json:"daoForkBlock,omitempty"` // TheDAO hard-fork switch block (nil = no fork)
+ DAOForkBlock *big.Int `json:"daoForkBlock,omitempty"` // The DAO hard-fork switch block (nil = no fork)
DAOForkSupport bool `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork
// EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150)
diff --git a/params/dao.go b/params/dao.go
index da3c8dfc992b..ad148686cea6 100644
--- a/params/dao.go
+++ b/params/dao.go
@@ -19,7 +19,7 @@ package params
import (
"math/big"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
// DAOForkBlockExtra is the block header extra-data field to set for the DAO fork
diff --git a/rpc/client.go b/rpc/client.go
index 8aa84ec98279..7d7f5e2d4fb7 100644
--- a/rpc/client.go
+++ b/rpc/client.go
@@ -32,7 +32,7 @@ import (
"sync/atomic"
"time"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
var (
@@ -354,11 +354,6 @@ func (c *Client) EthSubscribe(ctx context.Context, channel interface{}, args ...
return c.Subscribe(ctx, "eth", channel, args...)
}
-// ShhSubscribe registers a subscripion under the "shh" namespace.
-func (c *Client) ShhSubscribe(ctx context.Context, channel interface{}, args ...interface{}) (*ClientSubscription, error) {
- return c.Subscribe(ctx, "shh", channel, args...)
-}
-
// Subscribe calls the "_subscribe" method with the given arguments,
// registering a subscription. Server notifications for the subscription are
// sent to the given channel. The element type of the channel must match the
diff --git a/rpc/client_example_test.go b/rpc/client_example_test.go
index 8276a9eadd13..b53d9eb2cac6 100644
--- a/rpc/client_example_test.go
+++ b/rpc/client_example_test.go
@@ -22,7 +22,7 @@ import (
"math/big"
"time"
- "github.com/ethereum/go-ethereum/rpc"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
)
// In this example, our client whishes to track the latest 'block number'
diff --git a/rpc/client_test.go b/rpc/client_test.go
index 4f354d389e74..26d2cefd687d 100644
--- a/rpc/client_test.go
+++ b/rpc/client_test.go
@@ -31,7 +31,7 @@ import (
"time"
"github.com/davecgh/go-spew/spew"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
func TestClientRequest(t *testing.T) {
diff --git a/rpc/ipc.go b/rpc/ipc.go
index 8de18a56feda..b29429392282 100644
--- a/rpc/ipc.go
+++ b/rpc/ipc.go
@@ -21,7 +21,7 @@ import (
"fmt"
"net"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// CreateIPCListener creates an listener, on Unix platforms this is a unix socket, on
diff --git a/rpc/json.go b/rpc/json.go
index 2e7fd599e2ad..ec53525c9a71 100644
--- a/rpc/json.go
+++ b/rpc/json.go
@@ -26,7 +26,7 @@ import (
"strings"
"sync"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
const (
diff --git a/rpc/server.go b/rpc/server.go
index 30c288349e86..4f026ed11a96 100644
--- a/rpc/server.go
+++ b/rpc/server.go
@@ -25,7 +25,7 @@ import (
"sync"
"sync/atomic"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
"gopkg.in/fatih/set.v0"
)
diff --git a/rpc/subscription_test.go b/rpc/subscription_test.go
index 0ba177e63b45..b22d095d50f2 100644
--- a/rpc/subscription_test.go
+++ b/rpc/subscription_test.go
@@ -227,7 +227,7 @@ func waitForMessages(t *testing.T, in *json.Decoder, successes chan<- jsonSucces
// for multiple different namespaces.
func TestSubscriptionMultipleNamespaces(t *testing.T) {
var (
- namespaces = []string{"eth", "shh", "bzz"}
+ namespaces = []string{"eth", "bzz"}
server = NewServer()
service = NotificationTestService{}
clientConn, serverConn = net.Pipe()
diff --git a/rpc/types.go b/rpc/types.go
index f2375604ed95..e91dbb5ea346 100644
--- a/rpc/types.go
+++ b/rpc/types.go
@@ -23,7 +23,7 @@ import (
"strings"
"sync"
- "github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
"gopkg.in/fatih/set.v0"
)
diff --git a/rpc/types_test.go b/rpc/types_test.go
index 30cef9b22e89..a438580e4a89 100644
--- a/rpc/types_test.go
+++ b/rpc/types_test.go
@@ -20,7 +20,7 @@ import (
"encoding/json"
"testing"
- "github.com/ethereum/go-ethereum/common/math"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
)
func TestBlockNumberJSONUnmarshal(t *testing.T) {
diff --git a/rpc/websocket.go b/rpc/websocket.go
index 4214fc86a074..deff1439ec92 100644
--- a/rpc/websocket.go
+++ b/rpc/websocket.go
@@ -27,7 +27,7 @@ import (
"strings"
"time"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
"golang.org/x/net/websocket"
"gopkg.in/fatih/set.v0"
)
diff --git a/scripts/.env b/scripts/.env
new file mode 100644
index 000000000000..707ac70cacb5
--- /dev/null
+++ b/scripts/.env
@@ -0,0 +1,2 @@
+ROOT_DIR=CHANGEME
+ARCHIVE_DIR=CHANGEME
diff --git a/scripts/README.md b/scripts/README.md
new file mode 100644
index 000000000000..7fed732f8448
--- /dev/null
+++ b/scripts/README.md
@@ -0,0 +1,13 @@
+## Required software:
+- Docker
+
+## Usage:
+1. Configure `.env`
+ 1. `ROOT_DIR`
+ 2. `ARCHIVE_DIR`
+2. Run: `sudo ./build-images.sh`
+2. Run: `sudo ./run.sh num_instance`
+
+## Examples: schedule runs using `at` (as root):
+1. `echo './run.sh 1' | at -m 7:00 pm`
+2. `echo './tx-sniper-cron.sh 1' | at -m 7:01 pm`
diff --git a/scripts/build-images.sh b/scripts/build-images.sh
new file mode 100755
index 000000000000..d651a10e6149
--- /dev/null
+++ b/scripts/build-images.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+# check if root
+if [ "$EUID" -ne 0 ]; then
+ echo "please run as root"
+ exit 1
+fi
+
+WORKING_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+# build tx-sniper container image
+cd ${WORKING_DIR}/..
+docker build -t "geth:tx-sniper" .
diff --git a/scripts/run-no-docker.sh b/scripts/run-no-docker.sh
new file mode 100755
index 000000000000..2752beddc0ce
--- /dev/null
+++ b/scripts/run-no-docker.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# This script assumes required docker images are already built.
+# check if root
+if [ "$EUID" -ne 0 ]; then
+ echo "please run as root"
+ exit 1
+fi
+if [ "$#" -ne 1 ]; then
+ echo "argument missing"
+ echo "usage: sudo ./run-no-docker.sh num-instance"
+ exit 1
+fi
+
+n=$(( $1 - 1 ))
+WORKING_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+TXSNIPER_NAME="geth-tx-sniper"
+
+# get env variables
+source .env
+
+cd ${WORKING_DIR}/..
+make geth
+cp ${WORKING_DIR}/../build/bin/geth /usr/bin/geth
+
+cd ${WORKING_DIR}
+DATADIR="${ROOT_DIR}/${TXSNIPER_NAME}"
+mkdir -p -m 755 ${DATADIR}
+
+# run tx-snipers
+for i in `seq 0 ${n}`;
+do
+ ./tx-sniper-loop.sh ${i} >>${DATADIR}/${TXSNIPER_NAME}-${i}-loop.log 2>&1 &
+ echo "${TXSNIPER_NAME}-${i} loop started"
+done
diff --git a/scripts/run.sh b/scripts/run.sh
new file mode 100755
index 000000000000..9da46a3eabf6
--- /dev/null
+++ b/scripts/run.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# This script assumes required docker images are already built.
+# check if root
+if [ "$EUID" -ne 0 ]; then
+ echo "please run as root"
+ exit 1
+fi
+if [ "$#" -ne 1 ]; then
+ echo "argument missing"
+ echo "usage: sudo ./run.sh num-instance"
+ exit 1
+fi
+
+n=$(( $1 - 1 ))
+WORKING_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+TXSNIPER_NAME="geth-tx-sniper"
+
+# get env variables
+source .env
+
+TXSNIPER_IMAGE="geth:tx-sniper"
+
+# run tx-snipers
+URL="research-scan.sprai.org"
+TXSNIPER_PORT=30403
+DATADIR="/root/.ethereum"
+echo "starting ${TXSNIPER_NAME} containers..."
+for i in `seq 0 ${n}`;
+do
+ IDENTITY="uiuc-${i}(${URL})"
+ TXSNIPER_DIR="${ROOT_DIR}/${TXSNIPER_NAME}/${i}"
+ [ -d "${TXSNIPER_DIR}" ] || mkdir -p -m 755 ${TXSNIPER_DIR}/${TXSNIPER_NAME}
+ PORT=$(( ${TXSNIPER_PORT}+${i} ))
+ CMD="geth \
+ --identity \"${IDENTITY}\" \
+ --datadir \"${DATADIR}\" \
+ --port ${PORT} \
+ --verbosity 5 \
+ --logtofile \
+ --maxnumfile 1048576 \
+ --nodiscover \
+ --nolisten"
+ docker run -dit --restart=always -h ${TXSNIPER_NAME}-${i} --name ${TXSNIPER_NAME}-${i} --net host -v ${TXSNIPER_DIR}:${DATADIR} -e CMD="${CMD}" --entrypoint '/bin/sh' ${TXSNIPER_IMAGE} -c "${CMD}"
+ echo "${TXSNIPER_NAME}-${i} started"
+done
diff --git a/scripts/tx-sniper-cron.sh b/scripts/tx-sniper-cron.sh
new file mode 100755
index 000000000000..0ce44540373b
--- /dev/null
+++ b/scripts/tx-sniper-cron.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# This script assumes:
+# - it's run from the directory it's in.
+# - duplicate cronjobs are handled separately.
+# check if root
+if [ "$EUID" -ne 0 ]; then
+ echo "please run as root"
+ exit 1
+fi
+if [ "$#" -ne 1 ]; then
+ echo "argument missing"
+ echo "usage: ./tx-sniper-cron.sh num-instance"
+ exit 1
+fi
+
+WORKING_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+TXSNIPER_NAME="geth-tx-sniper"
+MINUTE="0"
+HOUR="*"
+n=$(( $1 - 1 ))
+CRONJOBS="$(crontab -l 2>/dev/null)"
+for i in `seq 0 ${n}`;
+do
+ CRONJOBS="${CRONJOBS}\n0 * * * * cd ${WORKING_DIR} && ./tx-sniper-logrotate.sh ${i}"
+ CRONJOBS="${CRONJOBS}\n*/3 * * * * cd ${WORKING_DIR} && ./tx-sniper-peerlist.sh ${i}"
+done
+echo -e "${CRONJOBS}" | crontab -
+echo "${TXSNIPER_NAME} cronjobs added"
diff --git a/scripts/tx-sniper-logrotate.sh b/scripts/tx-sniper-logrotate.sh
new file mode 100755
index 000000000000..ef43955e4115
--- /dev/null
+++ b/scripts/tx-sniper-logrotate.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# this script should be added to root crontab for each instance as following:
+# 0 0 * * * cd /path/to/gitrepo/scripts && ./tx-sniper-logrotate.sh instance-number
+# check if root
+if [ "$EUID" -ne 0 ]; then
+ echo "please run as root"
+ exit 1
+fi
+if [ "$#" -ne 1 ]; then
+ echo "argument missing"
+ echo "usage: ./tx-sniper-logrotate.sh instance-number"
+ exit 1
+fi
+
+i=$1
+WORKING_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+# get env variables
+source .env
+
+TXSNIPER_NAME="geth-tx-sniper"
+DATADIR="${ROOT_DIR}/${TXSNIPER_NAME}/${i}"
+LOGDIR="${DATADIR}/${TXSNIPER_NAME}/logs"
+NEWLOGDIR="${ARCHIVE_DIR}/${TXSNIPER_NAME}/${i}"
+[ -d "${NEWLOGDIR}" ] || mkdir -p -m 755 ${NEWLOGDIR}
+if cd ${LOGDIR} ; then
+ [ -d old ] || mkdir -p -m 755 old
+ mv *.log old
+ docker exec ${TXSNIPER_NAME}-${i} geth attach --exec 'admin.logrotate()'
+ DATE=$(date -u +%Y%m%dT%H%M%S)
+ cd old
+ for FILENAME in *.log; do
+ mv ${FILENAME} ${FILENAME}-${DATE}Z
+ done
+ mv * ${NEWLOGDIR}
+else
+ echo "logdir ${LOGDIR} doesn't exist"
+fi
diff --git a/scripts/tx-sniper-loop.sh b/scripts/tx-sniper-loop.sh
new file mode 100755
index 000000000000..d785de25c771
--- /dev/null
+++ b/scripts/tx-sniper-loop.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# check if root
+if [ "$EUID" -ne 0 ]; then
+ echo "please run as root"
+ exit 1
+fi
+if [ "$#" -ne 1 ]; then
+ echo "argument missing"
+ echo "usage: sudo ./tx-sniper-loop.sh instance-number"
+ exit 1
+fi
+
+i=$1
+WORKING_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+cd ${WORKING_DIR}
+source .env
+TXSNIPER_NAME="geth-tx-sniper"
+URL="research-scan.sprai.org"
+TXSNIPER_PORT=30403
+PORT=$(( ${TXSNIPER_PORT}+${i} ))
+DATADIR="${ROOT_DIR}/${TXSNIPER_NAME}/${i}"
+mkdir -p -m 755 ${DATADIR}/${TXSNIPER_NAME}
+ERRFILE="${DATADIR}/${TXSNIPER_NAME}-error.log"
+IDENTITY="uiuc-${i}(${URL})"
+SLEEP=3
+echo "starting ${TXSNIPER_NAME}-${i}..."
+while true
+do
+ geth \
+ --identity "${IDENTITY}" \
+ --datadir "${DATADIR}" \
+ --port ${PORT} \
+ --verbosity 5 \
+ --logtofile \
+ --maxnumfile 1048576 \
+ --nodiscover \
+ --nolisten >>${ERRFILE} 2>&1
+ echo "${TXSNIPER_NAME}-${i} stopped. restarting in ${SLEEP} seconds..."
+ sleep ${SLEEP}
+ echo "restarting ${TXSNIPER_NAME}-${i}..."
+done
diff --git a/scripts/tx-sniper-peerlist.sh b/scripts/tx-sniper-peerlist.sh
new file mode 100755
index 000000000000..d96c4506b5a7
--- /dev/null
+++ b/scripts/tx-sniper-peerlist.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# this script should be added to root crontab for each instance as following:
+# */3 * * * * cd /path/to/gitrepo/scripts && ./tx-sniper-peerlist.sh instance-number
+# check if root
+if [ "$EUID" -ne 0 ]; then
+ echo "please run as root"
+ exit 1
+fi
+if [ "$#" -ne 1 ]; then
+ echo "argument missing"
+ echo "usage: ./tx-sniper-peerlist.sh instance-number"
+ exit 1
+fi
+
+i=$1
+WORKING_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+# get env variables
+source .env
+
+TXSNIPER_NAME="geth-tx-sniper"
+DATADIR="${ROOT_DIR}/${TXSNIPER_NAME}/${i}"
+LOGDIR="${DATADIR}/${TXSNIPER_NAME}/logs"
+NEWLOGDIR="${ARCHIVE_DIR}/${TXSNIPER_NAME}/${i}/peerlists"
+[ -d "${NEWLOGDIR}" ] || mkdir -p -m 755 ${NEWLOGDIR}
+if cd ${LOGDIR} ; then
+ FILENAME="peerlist.log-$(date -u +%Y%m%dT%H%M%S)Z"
+ docker exec ${TXSNIPER_NAME}-${i} geth attach --exec 'admin.peerList' > ${FILENAME}
+ mv ${FILENAME} ${NEWLOGDIR}
+else
+ echo "logdir ${LOGDIR} doesn't exist"
+fi
diff --git a/swarm/api/api.go b/swarm/api/api.go
index 79de29a1cfcf..c19fbeb0bdce 100644
--- a/swarm/api/api.go
+++ b/swarm/api/api.go
@@ -29,9 +29,9 @@ import (
"path/filepath"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
)
var hashMatcher = regexp.MustCompile("^[0-9A-Fa-f]{64}")
diff --git a/swarm/api/api_test.go b/swarm/api/api_test.go
index f9caed27f56a..65cbc3a2159d 100644
--- a/swarm/api/api_test.go
+++ b/swarm/api/api_test.go
@@ -24,9 +24,9 @@ import (
"os"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
)
func testApi(t *testing.T, f func(*Api)) {
diff --git a/swarm/api/client/client.go b/swarm/api/client/client.go
index 7952d3fb689e..a3b1d4eec669 100644
--- a/swarm/api/client/client.go
+++ b/swarm/api/client/client.go
@@ -33,7 +33,7 @@ import (
"strconv"
"strings"
- "github.com/ethereum/go-ethereum/swarm/api"
+ "github.com/teamnsrg/ethereum-p2p/swarm/api"
)
var (
diff --git a/swarm/api/client/client_test.go b/swarm/api/client/client_test.go
index c1d144e370e1..f4b3397c3023 100644
--- a/swarm/api/client/client_test.go
+++ b/swarm/api/client/client_test.go
@@ -25,8 +25,8 @@ import (
"sort"
"testing"
- "github.com/ethereum/go-ethereum/swarm/api"
- "github.com/ethereum/go-ethereum/swarm/testutil"
+ "github.com/teamnsrg/ethereum-p2p/swarm/api"
+ "github.com/teamnsrg/ethereum-p2p/swarm/testutil"
)
// TestClientUploadDownloadRaw test uploading and downloading raw data to swarm
diff --git a/swarm/api/config.go b/swarm/api/config.go
index d8d25b1c8227..50d107b0cb28 100644
--- a/swarm/api/config.go
+++ b/swarm/api/config.go
@@ -24,12 +24,12 @@ import (
"os"
"path/filepath"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/contracts/ens"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/swarm/network"
- "github.com/ethereum/go-ethereum/swarm/services/swap"
- "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/contracts/ens"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/swarm/network"
+ "github.com/teamnsrg/ethereum-p2p/swarm/services/swap"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
)
const (
diff --git a/swarm/api/config_test.go b/swarm/api/config_test.go
index 85d056270e29..4250d4799ef7 100644
--- a/swarm/api/config_test.go
+++ b/swarm/api/config_test.go
@@ -23,8 +23,8 @@ import (
"strings"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
)
var (
diff --git a/swarm/api/filesystem.go b/swarm/api/filesystem.go
index f5dc90e2e5b5..c4f68753861f 100644
--- a/swarm/api/filesystem.go
+++ b/swarm/api/filesystem.go
@@ -26,9 +26,9 @@ import (
"path/filepath"
"sync"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
)
const maxParallelFiles = 5
diff --git a/swarm/api/filesystem_test.go b/swarm/api/filesystem_test.go
index 8a15e735dcb0..c04afe60fe2c 100644
--- a/swarm/api/filesystem_test.go
+++ b/swarm/api/filesystem_test.go
@@ -24,8 +24,8 @@ import (
"sync"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
)
var testDownloadDir, _ = ioutil.TempDir(os.TempDir(), "bzz-test")
diff --git a/swarm/api/http/error.go b/swarm/api/http/error.go
index dbd97182fdc8..3fc2e694e650 100644
--- a/swarm/api/http/error.go
+++ b/swarm/api/http/error.go
@@ -28,8 +28,8 @@ import (
"strings"
"time"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/swarm/api"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/swarm/api"
)
//templateMap holds a mapping of an HTTP error code to a template
diff --git a/swarm/api/http/error_test.go b/swarm/api/http/error_test.go
index ed52bafbd201..a460235ca565 100644
--- a/swarm/api/http/error_test.go
+++ b/swarm/api/http/error_test.go
@@ -24,7 +24,7 @@ import (
"strings"
"testing"
- "github.com/ethereum/go-ethereum/swarm/testutil"
+ "github.com/teamnsrg/ethereum-p2p/swarm/testutil"
)
func TestError(t *testing.T) {
diff --git a/swarm/api/http/roundtripper.go b/swarm/api/http/roundtripper.go
index 328177a218b5..acdc32805af7 100644
--- a/swarm/api/http/roundtripper.go
+++ b/swarm/api/http/roundtripper.go
@@ -20,17 +20,17 @@ import (
"fmt"
"net/http"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
/*
http roundtripper to register for bzz url scheme
-see https://github.com/ethereum/go-ethereum/issues/2040
+see https://github.com/teamnsrg/ethereum-p2p/issues/2040
Usage:
import (
- "github.com/ethereum/go-ethereum/common/httpclient"
- "github.com/ethereum/go-ethereum/swarm/api/http"
+ "github.com/teamnsrg/ethereum-p2p/common/httpclient"
+ "github.com/teamnsrg/ethereum-p2p/swarm/api/http"
)
client := httpclient.New()
// for (private) swarm proxy running locally
diff --git a/swarm/api/http/server.go b/swarm/api/http/server.go
index 65f6afab723e..1eb49a3a35eb 100644
--- a/swarm/api/http/server.go
+++ b/swarm/api/http/server.go
@@ -35,11 +35,11 @@ import (
"strings"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/swarm/api"
- "github.com/ethereum/go-ethereum/swarm/storage"
"github.com/rs/cors"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/swarm/api"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
)
// ServerConfig is the basic configuration needed for the HTTP server and also
diff --git a/swarm/api/http/server_test.go b/swarm/api/http/server_test.go
index ffeaf6e0d867..4253de489f1c 100644
--- a/swarm/api/http/server_test.go
+++ b/swarm/api/http/server_test.go
@@ -26,11 +26,11 @@ import (
"sync"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/swarm/api"
- swarm "github.com/ethereum/go-ethereum/swarm/api/client"
- "github.com/ethereum/go-ethereum/swarm/storage"
- "github.com/ethereum/go-ethereum/swarm/testutil"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/swarm/api"
+ swarm "github.com/teamnsrg/ethereum-p2p/swarm/api/client"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
+ "github.com/teamnsrg/ethereum-p2p/swarm/testutil"
)
func TestBzzrGetPath(t *testing.T) {
diff --git a/swarm/api/http/templates.go b/swarm/api/http/templates.go
index 9ae434a7ed7a..d6902882030a 100644
--- a/swarm/api/http/templates.go
+++ b/swarm/api/http/templates.go
@@ -20,7 +20,7 @@ import (
"html/template"
"path"
- "github.com/ethereum/go-ethereum/swarm/api"
+ "github.com/teamnsrg/ethereum-p2p/swarm/api"
)
type htmlListData struct {
diff --git a/swarm/api/manifest.go b/swarm/api/manifest.go
index 32b5f80a7cb0..0c5594e76a31 100644
--- a/swarm/api/manifest.go
+++ b/swarm/api/manifest.go
@@ -27,9 +27,9 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
)
const (
diff --git a/swarm/api/manifest_test.go b/swarm/api/manifest_test.go
index f048627c511d..0bd0edcb71d2 100644
--- a/swarm/api/manifest_test.go
+++ b/swarm/api/manifest_test.go
@@ -24,7 +24,7 @@ import (
"strings"
"testing"
- "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
)
func manifest(paths ...string) (manifestReader storage.LazySectionReader) {
diff --git a/swarm/api/testapi.go b/swarm/api/testapi.go
index 6631196c1719..4a49a5aed1e2 100644
--- a/swarm/api/testapi.go
+++ b/swarm/api/testapi.go
@@ -17,7 +17,7 @@
package api
import (
- "github.com/ethereum/go-ethereum/swarm/network"
+ "github.com/teamnsrg/ethereum-p2p/swarm/network"
)
type Control struct {
diff --git a/swarm/dev/Makefile b/swarm/dev/Makefile
index 365964b7f56c..684fb05c4ca9 100644
--- a/swarm/dev/Makefile
+++ b/swarm/dev/Makefile
@@ -3,12 +3,12 @@
default: build
build:
- go build -o bin/swarm github.com/ethereum/go-ethereum/cmd/swarm
- go build -o bin/geth github.com/ethereum/go-ethereum/cmd/geth
- go build -o bin/bootnode github.com/ethereum/go-ethereum/cmd/bootnode
+ go build -o bin/swarm github.com/teamnsrg/ethereum-p2p/cmd/swarm
+ go build -o bin/geth github.com/teamnsrg/ethereum-p2p/cmd/geth
+ go build -o bin/bootnode github.com/teamnsrg/ethereum-p2p/cmd/bootnode
cluster: build
scripts/boot-cluster.sh
test:
- go test -v github.com/ethereum/go-ethereum/swarm/...
+ go test -v github.com/teamnsrg/ethereum-p2p/swarm/...
diff --git a/swarm/dev/bashrc b/swarm/dev/bashrc
index efb504fa36eb..c1667bd008b8 100644
--- a/swarm/dev/bashrc
+++ b/swarm/dev/bashrc
@@ -1,4 +1,4 @@
-export ROOT="${GOPATH}/src/github.com/ethereum/go-ethereum"
+export ROOT="${GOPATH}/src/github.com/teamnsrg/ethereum-p2p"
export PATH="${ROOT}/swarm/dev/bin:${PATH}"
cd "${ROOT}/swarm/dev"
diff --git a/swarm/dev/run.sh b/swarm/dev/run.sh
index 2ad600dedf3d..c316fbd4bb4b 100755
--- a/swarm/dev/run.sh
+++ b/swarm/dev/run.sh
@@ -80,7 +80,7 @@ run_image() {
--rm \
--hostname "${name}" \
--name "${name}" \
- --volume "${ROOT}:/go/src/github.com/ethereum/go-ethereum" \
+ --volume "${ROOT}:/go/src/github.com/teamnsrg/ethereum-p2p" \
--volume "/var/run/docker.sock:/var/run/docker.sock" \
${docker_args} \
"${name}" \
diff --git a/swarm/fuse/fuse_file.go b/swarm/fuse/fuse_file.go
index c94a0773f525..fa9f9336bfa4 100644
--- a/swarm/fuse/fuse_file.go
+++ b/swarm/fuse/fuse_file.go
@@ -26,8 +26,8 @@ import (
"bazil.org/fuse"
"bazil.org/fuse/fs"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
"golang.org/x/net/context"
)
diff --git a/swarm/fuse/swarmfs.go b/swarm/fuse/swarmfs.go
index 2493bdab19ba..585ca5c237f1 100644
--- a/swarm/fuse/swarmfs.go
+++ b/swarm/fuse/swarmfs.go
@@ -17,7 +17,7 @@
package fuse
import (
- "github.com/ethereum/go-ethereum/swarm/api"
+ "github.com/teamnsrg/ethereum-p2p/swarm/api"
"sync"
"time"
)
diff --git a/swarm/fuse/swarmfs_test.go b/swarm/fuse/swarmfs_test.go
index 93f1d4c2fdd7..fdfd2ef7ee01 100644
--- a/swarm/fuse/swarmfs_test.go
+++ b/swarm/fuse/swarmfs_test.go
@@ -27,8 +27,8 @@ import (
"path/filepath"
"testing"
- "github.com/ethereum/go-ethereum/swarm/api"
- "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/teamnsrg/ethereum-p2p/swarm/api"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
)
type fileInfo struct {
diff --git a/swarm/fuse/swarmfs_unix.go b/swarm/fuse/swarmfs_unix.go
index 75742845a24f..e367ba62679d 100644
--- a/swarm/fuse/swarmfs_unix.go
+++ b/swarm/fuse/swarmfs_unix.go
@@ -29,9 +29,9 @@ import (
"bazil.org/fuse"
"bazil.org/fuse/fs"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/swarm/api"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/swarm/api"
)
var (
diff --git a/swarm/fuse/swarmfs_util.go b/swarm/fuse/swarmfs_util.go
index d39966c0e3eb..04468294b012 100644
--- a/swarm/fuse/swarmfs_util.go
+++ b/swarm/fuse/swarmfs_util.go
@@ -24,7 +24,7 @@ import (
"os/exec"
"runtime"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
func externalUnmount(mountPoint string) error {
diff --git a/swarm/network/depo.go b/swarm/network/depo.go
index 17540d2f9fd7..8ad07306ab15 100644
--- a/swarm/network/depo.go
+++ b/swarm/network/depo.go
@@ -22,8 +22,8 @@ import (
"fmt"
"time"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
)
// Handler for storage/retrieval related protocol requests
diff --git a/swarm/network/forwarding.go b/swarm/network/forwarding.go
index 88a82a678c1e..5593bc297081 100644
--- a/swarm/network/forwarding.go
+++ b/swarm/network/forwarding.go
@@ -21,8 +21,8 @@ import (
"math/rand"
"time"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
)
const requesterCount = 3
diff --git a/swarm/network/hive.go b/swarm/network/hive.go
index d37b7e4006f2..11170c5c1c09 100644
--- a/swarm/network/hive.go
+++ b/swarm/network/hive.go
@@ -22,12 +22,12 @@ import (
"path/filepath"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/p2p/netutil"
- "github.com/ethereum/go-ethereum/swarm/network/kademlia"
- "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/p2p/netutil"
+ "github.com/teamnsrg/ethereum-p2p/swarm/network/kademlia"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
)
// Hive is the logistic manager of the swarm
diff --git a/swarm/network/kademlia/address.go b/swarm/network/kademlia/address.go
index 4c38a846f912..6cb1a55235ea 100644
--- a/swarm/network/kademlia/address.go
+++ b/swarm/network/kademlia/address.go
@@ -21,7 +21,7 @@ import (
"math/rand"
"strings"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
type Address common.Hash
diff --git a/swarm/network/kademlia/address_test.go b/swarm/network/kademlia/address_test.go
index c062c8eafb23..e1126e2fa1cf 100644
--- a/swarm/network/kademlia/address_test.go
+++ b/swarm/network/kademlia/address_test.go
@@ -21,7 +21,7 @@ import (
"reflect"
"testing"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
func (Address) Generate(rand *rand.Rand, size int) reflect.Value {
diff --git a/swarm/network/kademlia/kaddb.go b/swarm/network/kademlia/kaddb.go
index cb0869467e80..1ff91bf77bbf 100644
--- a/swarm/network/kademlia/kaddb.go
+++ b/swarm/network/kademlia/kaddb.go
@@ -24,7 +24,7 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
type NodeData interface {
diff --git a/swarm/network/kademlia/kademlia.go b/swarm/network/kademlia/kademlia.go
index bf976a3e1d94..24bd70292209 100644
--- a/swarm/network/kademlia/kademlia.go
+++ b/swarm/network/kademlia/kademlia.go
@@ -23,7 +23,7 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
const (
diff --git a/swarm/network/messages.go b/swarm/network/messages.go
index d920def9593e..51f1e7eeb458 100644
--- a/swarm/network/messages.go
+++ b/swarm/network/messages.go
@@ -21,11 +21,11 @@ import (
"net"
"time"
- "github.com/ethereum/go-ethereum/contracts/chequebook"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/swarm/network/kademlia"
- "github.com/ethereum/go-ethereum/swarm/services/swap"
- "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/teamnsrg/ethereum-p2p/contracts/chequebook"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/swarm/network/kademlia"
+ "github.com/teamnsrg/ethereum-p2p/swarm/services/swap"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
)
/*
diff --git a/swarm/network/protocol.go b/swarm/network/protocol.go
index a418c1dbbd46..fd74265757e2 100644
--- a/swarm/network/protocol.go
+++ b/swarm/network/protocol.go
@@ -37,12 +37,12 @@ import (
"strconv"
"time"
- "github.com/ethereum/go-ethereum/contracts/chequebook"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p"
- bzzswap "github.com/ethereum/go-ethereum/swarm/services/swap"
- "github.com/ethereum/go-ethereum/swarm/services/swap/swap"
- "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/teamnsrg/ethereum-p2p/contracts/chequebook"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ bzzswap "github.com/teamnsrg/ethereum-p2p/swarm/services/swap"
+ "github.com/teamnsrg/ethereum-p2p/swarm/services/swap/swap"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
)
const (
diff --git a/swarm/network/syncdb.go b/swarm/network/syncdb.go
index 88b4b68dd0f5..f850a8430fc8 100644
--- a/swarm/network/syncdb.go
+++ b/swarm/network/syncdb.go
@@ -20,10 +20,10 @@ import (
"encoding/binary"
"fmt"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/swarm/storage"
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/iterator"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
)
const counterKeyPrefix = 0x01
diff --git a/swarm/network/syncdb_test.go b/swarm/network/syncdb_test.go
index be21d156f9fb..7cb30490b5c8 100644
--- a/swarm/network/syncdb_test.go
+++ b/swarm/network/syncdb_test.go
@@ -25,9 +25,9 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
)
func init() {
diff --git a/swarm/network/syncer.go b/swarm/network/syncer.go
index d76af022c12f..3d9bcda8fb2f 100644
--- a/swarm/network/syncer.go
+++ b/swarm/network/syncer.go
@@ -22,8 +22,8 @@ import (
"fmt"
"path/filepath"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
)
// syncer parameters (global, not peer specific) default values
diff --git a/swarm/services/swap/swap.go b/swarm/services/swap/swap.go
index 093892e8d9e0..e3c9f1f0e944 100644
--- a/swarm/services/swap/swap.go
+++ b/swarm/services/swap/swap.go
@@ -26,14 +26,14 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/contracts/chequebook"
- "github.com/ethereum/go-ethereum/contracts/chequebook/contract"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/swarm/services/swap/swap"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi/bind"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/contracts/chequebook"
+ "github.com/teamnsrg/ethereum-p2p/contracts/chequebook/contract"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/swarm/services/swap/swap"
)
// SwAP Swarm Accounting Protocol with
diff --git a/swarm/services/swap/swap/swap.go b/swarm/services/swap/swap/swap.go
index a78f1f0e2ad5..f8ad3da08b8d 100644
--- a/swarm/services/swap/swap/swap.go
+++ b/swarm/services/swap/swap/swap.go
@@ -22,7 +22,7 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
// SwAP Swarm Accounting Protocol with
diff --git a/swarm/services/swap/swap/swap_test.go b/swarm/services/swap/swap/swap_test.go
index 222e0770f399..b2e089b5418b 100644
--- a/swarm/services/swap/swap/swap_test.go
+++ b/swarm/services/swap/swap/swap_test.go
@@ -21,7 +21,7 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
type testInPayment struct {
diff --git a/swarm/storage/chunker_test.go b/swarm/storage/chunker_test.go
index b41d7dd333e4..ee3174fac0cf 100644
--- a/swarm/storage/chunker_test.go
+++ b/swarm/storage/chunker_test.go
@@ -27,7 +27,7 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/crypto/sha3"
+ "github.com/teamnsrg/ethereum-p2p/crypto/sha3"
)
/*
diff --git a/swarm/storage/common_test.go b/swarm/storage/common_test.go
index cd4c2ef139fa..3180c0a95dc7 100644
--- a/swarm/storage/common_test.go
+++ b/swarm/storage/common_test.go
@@ -24,7 +24,7 @@ import (
"sync"
"testing"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
type brokenLimitedReader struct {
diff --git a/swarm/storage/database.go b/swarm/storage/database.go
index 2532490cc9cb..1b8c347dbee2 100644
--- a/swarm/storage/database.go
+++ b/swarm/storage/database.go
@@ -22,10 +22,10 @@ package storage
import (
"fmt"
- "github.com/ethereum/go-ethereum/compression/rle"
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/iterator"
"github.com/syndtr/goleveldb/leveldb/opt"
+ "github.com/teamnsrg/ethereum-p2p/compression/rle"
)
const openFileLimit = 128
diff --git a/swarm/storage/dbstore.go b/swarm/storage/dbstore.go
index 46a5c16ccc88..77b04d7e106c 100644
--- a/swarm/storage/dbstore.go
+++ b/swarm/storage/dbstore.go
@@ -32,10 +32,10 @@ import (
"io/ioutil"
"sync"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/rlp"
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/iterator"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
const (
diff --git a/swarm/storage/dbstore_test.go b/swarm/storage/dbstore_test.go
index dd165b576869..6e9d44e84d97 100644
--- a/swarm/storage/dbstore_test.go
+++ b/swarm/storage/dbstore_test.go
@@ -21,7 +21,7 @@ import (
"io/ioutil"
"testing"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
func initDbStore(t *testing.T) *DbStore {
diff --git a/swarm/storage/dpa.go b/swarm/storage/dpa.go
index 44a2669f125e..ae0ae12965ab 100644
--- a/swarm/storage/dpa.go
+++ b/swarm/storage/dpa.go
@@ -23,7 +23,7 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
/*
diff --git a/swarm/storage/memstore.go b/swarm/storage/memstore.go
index 3cb25ac62590..51b98ebd74c7 100644
--- a/swarm/storage/memstore.go
+++ b/swarm/storage/memstore.go
@@ -22,7 +22,7 @@ import (
"fmt"
"sync"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
const (
diff --git a/swarm/storage/netstore.go b/swarm/storage/netstore.go
index 7b0612edc531..1c60413e7fd3 100644
--- a/swarm/storage/netstore.go
+++ b/swarm/storage/netstore.go
@@ -21,7 +21,7 @@ import (
"path/filepath"
"time"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
/*
diff --git a/swarm/storage/types.go b/swarm/storage/types.go
index d35f1f929404..d1cadf91bde7 100644
--- a/swarm/storage/types.go
+++ b/swarm/storage/types.go
@@ -24,9 +24,9 @@ import (
"io"
"sync"
- "github.com/ethereum/go-ethereum/bmt"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto/sha3"
+ "github.com/teamnsrg/ethereum-p2p/bmt"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto/sha3"
)
type Hasher func() hash.Hash
diff --git a/swarm/swarm.go b/swarm/swarm.go
index 9db15325aee7..25f1ede13312 100644
--- a/swarm/swarm.go
+++ b/swarm/swarm.go
@@ -23,22 +23,22 @@ import (
"fmt"
"net"
- "github.com/ethereum/go-ethereum/accounts/abi/bind"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/contracts/chequebook"
- "github.com/ethereum/go-ethereum/contracts/ens"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethclient"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/node"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/rpc"
- "github.com/ethereum/go-ethereum/swarm/api"
- httpapi "github.com/ethereum/go-ethereum/swarm/api/http"
- "github.com/ethereum/go-ethereum/swarm/fuse"
- "github.com/ethereum/go-ethereum/swarm/network"
- "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/teamnsrg/ethereum-p2p/accounts/abi/bind"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/contracts/chequebook"
+ "github.com/teamnsrg/ethereum-p2p/contracts/ens"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/ethclient"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/node"
+ "github.com/teamnsrg/ethereum-p2p/p2p"
+ "github.com/teamnsrg/ethereum-p2p/p2p/discover"
+ "github.com/teamnsrg/ethereum-p2p/rpc"
+ "github.com/teamnsrg/ethereum-p2p/swarm/api"
+ httpapi "github.com/teamnsrg/ethereum-p2p/swarm/api/http"
+ "github.com/teamnsrg/ethereum-p2p/swarm/fuse"
+ "github.com/teamnsrg/ethereum-p2p/swarm/network"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
)
// the swarm stack
diff --git a/swarm/testutil/http.go b/swarm/testutil/http.go
index f2922fab003a..868733476e56 100644
--- a/swarm/testutil/http.go
+++ b/swarm/testutil/http.go
@@ -22,9 +22,9 @@ import (
"os"
"testing"
- "github.com/ethereum/go-ethereum/swarm/api"
- httpapi "github.com/ethereum/go-ethereum/swarm/api/http"
- "github.com/ethereum/go-ethereum/swarm/storage"
+ "github.com/teamnsrg/ethereum-p2p/swarm/api"
+ httpapi "github.com/teamnsrg/ethereum-p2p/swarm/api/http"
+ "github.com/teamnsrg/ethereum-p2p/swarm/storage"
)
func NewTestSwarmServer(t *testing.T) *TestSwarmServer {
diff --git a/tcpinfo/LICENSE b/tcpinfo/LICENSE
new file mode 100755
index 000000000000..5a4edfbebc0a
--- /dev/null
+++ b/tcpinfo/LICENSE
@@ -0,0 +1,23 @@
+Copyright (c) 2016, Mikio Hara
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/tcpinfo/defs_darwin.go b/tcpinfo/defs_darwin.go
new file mode 100755
index 000000000000..043822f51a82
--- /dev/null
+++ b/tcpinfo/defs_darwin.go
@@ -0,0 +1,19 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+package tcpinfo
+
+/*
+#include
+*/
+import "C"
+
+const (
+ TCP_CONNECTION_INFO = C.TCP_CONNECTION_INFO
+ SizeofTCPConnectionInfo = C.sizeof_struct_tcp_connection_info
+)
+
+type TCPConnectionInfo C.struct_tcp_connection_info
diff --git a/tcpinfo/defs_freebsd.go b/tcpinfo/defs_freebsd.go
new file mode 100755
index 000000000000..62241f08bb95
--- /dev/null
+++ b/tcpinfo/defs_freebsd.go
@@ -0,0 +1,26 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+package tcpinfo
+
+/*
+#include
+*/
+import "C"
+
+const (
+ sysTCP_INFO = C.TCP_INFO
+
+ sysTCPI_OPT_TIMESTAMPS = C.TCPI_OPT_TIMESTAMPS
+ sysTCPI_OPT_SACK = C.TCPI_OPT_SACK
+ sysTCPI_OPT_WSCALE = C.TCPI_OPT_WSCALE
+ sysTCPI_OPT_ECN = C.TCPI_OPT_ECN
+ sysTCPI_OPT_TOE = C.TCPI_OPT_TOE
+
+ sizeofTCPInfo = C.sizeof_struct_tcp_info
+)
+
+type tcpInfo C.struct_tcp_info
diff --git a/tcpinfo/defs_linux.go b/tcpinfo/defs_linux.go
new file mode 100755
index 000000000000..674caf870b5c
--- /dev/null
+++ b/tcpinfo/defs_linux.go
@@ -0,0 +1,19 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+package tcpinfo
+
+/*
+#include
+*/
+import "C"
+
+const (
+ TCP_INFO = C.TCP_INFO
+ SizeofTCPInfo = C.sizeof_struct_tcp_info
+)
+
+type TCPInfo C.struct_tcp_info
diff --git a/tcpinfo/defs_netbsd.go b/tcpinfo/defs_netbsd.go
new file mode 100755
index 000000000000..62241f08bb95
--- /dev/null
+++ b/tcpinfo/defs_netbsd.go
@@ -0,0 +1,26 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+package tcpinfo
+
+/*
+#include
+*/
+import "C"
+
+const (
+ sysTCP_INFO = C.TCP_INFO
+
+ sysTCPI_OPT_TIMESTAMPS = C.TCPI_OPT_TIMESTAMPS
+ sysTCPI_OPT_SACK = C.TCPI_OPT_SACK
+ sysTCPI_OPT_WSCALE = C.TCPI_OPT_WSCALE
+ sysTCPI_OPT_ECN = C.TCPI_OPT_ECN
+ sysTCPI_OPT_TOE = C.TCPI_OPT_TOE
+
+ sizeofTCPInfo = C.sizeof_struct_tcp_info
+)
+
+type tcpInfo C.struct_tcp_info
diff --git a/tcpinfo/doc.go b/tcpinfo/doc.go
new file mode 100755
index 000000000000..16c15b2264d2
--- /dev/null
+++ b/tcpinfo/doc.go
@@ -0,0 +1,46 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package tcpinfo implements encoding and decoding of TCP-level
+// socket options regarding connection information.
+//
+// The Transmission Control Protocol (TCP) is defined in RFC 793.
+// TCP Selective Acknowledgment Options is defined in RFC 2018.
+// Management Information Base for the Transmission Control Protocol
+// (TCP) is defined in RFC 4022.
+// TCP Congestion Control is defined in RFC 5681.
+// Computing TCP's Retransmission Timer is described in RFC 6298.
+// TCP Options and Maximum Segment Size (MSS) is defined in RFC 6691.
+// Shared Use of Experimental TCP Options is defined in RFC 6994.
+// TCP Extensions for High Performance is defined in RFC 7323.
+//
+// Example:
+//
+// import (
+// "github.com/mikioh/tcp"
+// "github.com/mikioh/tcpinfo"
+// )
+//
+// c, err := net.Dial("tcp", "golang.org:80")
+// if err != nil {
+// // error handling
+// }
+// defer c.Close()
+//
+// tc, err := tcp.NewConn(c)
+// if err != nil {
+// // error handling
+// }
+// var o tcpinfo.Info
+// var b [256]byte
+// i, err := tc.Option(o.Level(), o.Name(), b[:])
+// if err != nil {
+// // error handling
+// }
+// txt, err := json.Marshal(i)
+// if err != nil {
+// // error handling
+// }
+// fmt.Println(txt)
+package tcpinfo
diff --git a/tcpinfo/zsys_darwin.go b/tcpinfo/zsys_darwin.go
new file mode 100755
index 000000000000..539190ecb71a
--- /dev/null
+++ b/tcpinfo/zsys_darwin.go
@@ -0,0 +1,36 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs tcpinfo/defs_darwin.go
+
+package tcpinfo
+
+const (
+ TCP_CONNECTION_INFO = 0x106
+ SizeofTCPConnectionInfo = 0x70
+)
+
+type TCPConnectionInfo struct {
+ State uint8
+ Snd_wscale uint8
+ Rcv_wscale uint8
+ X__pad1 uint8
+ Options uint32
+ Flags uint32
+ Rto uint32
+ Maxseg uint32
+ Snd_ssthresh uint32
+ Snd_cwnd uint32
+ Snd_wnd uint32
+ Snd_sbbytes uint32
+ Rcv_wnd uint32
+ Rttcur uint32
+ Srtt uint32
+ Rttvar uint32
+ Pad_cgo_0 [4]byte
+ Txpackets uint64
+ Txbytes uint64
+ Txretransmitbytes uint64
+ Rxpackets uint64
+ Rxbytes uint64
+ Rxoutoforderbytes uint64
+ Txretransmitpackets uint64
+}
diff --git a/tcpinfo/zsys_freebsd.go b/tcpinfo/zsys_freebsd.go
new file mode 100755
index 000000000000..b92d53eeffd9
--- /dev/null
+++ b/tcpinfo/zsys_freebsd.go
@@ -0,0 +1,58 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_freebsd.go
+
+package tcpinfo
+
+const (
+ sysTCP_INFO = 0x20
+
+ sysTCPI_OPT_TIMESTAMPS = 0x1
+ sysTCPI_OPT_SACK = 0x2
+ sysTCPI_OPT_WSCALE = 0x4
+ sysTCPI_OPT_ECN = 0x8
+ sysTCPI_OPT_TOE = 0x10
+
+ sizeofTCPInfo = 0xec
+)
+
+type tcpInfo struct {
+ State uint8
+ X__tcpi_ca_state uint8
+ X__tcpi_retransmits uint8
+ X__tcpi_probes uint8
+ X__tcpi_backoff uint8
+ Options uint8
+ Pad_cgo_0 [2]byte
+ Rto uint32
+ X__tcpi_ato uint32
+ Snd_mss uint32
+ Rcv_mss uint32
+ X__tcpi_unacked uint32
+ X__tcpi_sacked uint32
+ X__tcpi_lost uint32
+ X__tcpi_retrans uint32
+ X__tcpi_fackets uint32
+ X__tcpi_last_data_sent uint32
+ X__tcpi_last_ack_sent uint32
+ Last_data_recv uint32
+ X__tcpi_last_ack_recv uint32
+ X__tcpi_pmtu uint32
+ X__tcpi_rcv_ssthresh uint32
+ Rtt uint32
+ Rttvar uint32
+ Snd_ssthresh uint32
+ Snd_cwnd uint32
+ X__tcpi_advmss uint32
+ X__tcpi_reordering uint32
+ X__tcpi_rcv_rtt uint32
+ Rcv_space uint32
+ Snd_wnd uint32
+ Snd_bwnd uint32
+ Snd_nxt uint32
+ Rcv_nxt uint32
+ Toe_tid uint32
+ Snd_rexmitpack uint32
+ Rcv_ooopack uint32
+ Snd_zerowin uint32
+ X__tcpi_pad [26]uint32
+}
diff --git a/tcpinfo/zsys_linux.go b/tcpinfo/zsys_linux.go
new file mode 100755
index 000000000000..4ea05bd55974
--- /dev/null
+++ b/tcpinfo/zsys_linux.go
@@ -0,0 +1,49 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs tcpinfo/defs_linux.go
+
+package tcpinfo
+
+const (
+ TCP_INFO = 0xb
+ SizeofTCPInfo = 0x90
+)
+
+type TCPInfo struct {
+ State uint8
+ Ca_state uint8
+ Retransmits uint8
+ Probes uint8
+ Backoff uint8
+ Options uint8
+ Pad_cgo_0 [2]byte
+ Rto uint32
+ Ato uint32
+ Snd_mss uint32
+ Rcv_mss uint32
+ Unacked uint32
+ Sacked uint32
+ Lost uint32
+ Retrans uint32
+ Fackets uint32
+ Last_data_sent uint32
+ Last_ack_sent uint32
+ Last_data_recv uint32
+ Last_ack_recv uint32
+ Pmtu uint32
+ Rcv_ssthresh uint32
+ Rtt uint32
+ Rttvar uint32
+ Snd_ssthresh uint32
+ Snd_cwnd uint32
+ Advmss uint32
+ Reordering uint32
+ Rcv_rtt uint32
+ Rcv_space uint32
+ Total_retrans uint32
+ Pacing_rate uint64
+ Max_pacing_rate uint64
+ Bytes_acked uint64
+ Bytes_received uint64
+ Segs_out uint32
+ Segs_in uint32
+}
diff --git a/tcpinfo/zsys_netbsd.go b/tcpinfo/zsys_netbsd.go
new file mode 100755
index 000000000000..126355e04434
--- /dev/null
+++ b/tcpinfo/zsys_netbsd.go
@@ -0,0 +1,58 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_netbsd.go
+
+package tcpinfo
+
+const (
+ sysTCP_INFO = 0x9
+
+ sysTCPI_OPT_TIMESTAMPS = 0x1
+ sysTCPI_OPT_SACK = 0x2
+ sysTCPI_OPT_WSCALE = 0x4
+ sysTCPI_OPT_ECN = 0x8
+ sysTCPI_OPT_TOE = 0x10
+
+ sizeofTCPInfo = 0xec
+)
+
+type tcpInfo struct {
+ State uint8
+ X__tcpi_ca_state uint8
+ X__tcpi_retransmits uint8
+ X__tcpi_probes uint8
+ X__tcpi_backoff uint8
+ Options uint8
+ Pad_cgo_0 [2]byte
+ Rto uint32
+ X__tcpi_ato uint32
+ Snd_mss uint32
+ Rcv_mss uint32
+ X__tcpi_unacked uint32
+ X__tcpi_sacked uint32
+ X__tcpi_lost uint32
+ X__tcpi_retrans uint32
+ X__tcpi_fackets uint32
+ X__tcpi_last_data_sent uint32
+ X__tcpi_last_ack_sent uint32
+ Last_data_recv uint32
+ X__tcpi_last_ack_recv uint32
+ X__tcpi_pmtu uint32
+ X__tcpi_rcv_ssthresh uint32
+ Rtt uint32
+ Rttvar uint32
+ Snd_ssthresh uint32
+ Snd_cwnd uint32
+ X__tcpi_advmss uint32
+ X__tcpi_reordering uint32
+ X__tcpi_rcv_rtt uint32
+ Rcv_space uint32
+ Snd_wnd uint32
+ Snd_bwnd uint32
+ Snd_nxt uint32
+ Rcv_nxt uint32
+ Toe_tid uint32
+ Snd_rexmitpack uint32
+ Rcv_ooopack uint32
+ Snd_zerowin uint32
+ X__tcpi_pad [26]uint32
+}
diff --git a/tests/block_test_util.go b/tests/block_test_util.go
index a789e6d8873d..0652898f758d 100644
--- a/tests/block_test_util.go
+++ b/tests/block_test_util.go
@@ -24,17 +24,17 @@ import (
"fmt"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/consensus/ethash"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
// A BlockTest checks handling of entire blocks.
diff --git a/tests/difficulty_test.go b/tests/difficulty_test.go
index a449b1cfa68f..82563446eea2 100644
--- a/tests/difficulty_test.go
+++ b/tests/difficulty_test.go
@@ -22,8 +22,8 @@ import (
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
var (
diff --git a/tests/difficulty_test_util.go b/tests/difficulty_test_util.go
index 75414779334e..c8eaf9b66912 100644
--- a/tests/difficulty_test_util.go
+++ b/tests/difficulty_test_util.go
@@ -21,11 +21,11 @@ import (
"fmt"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/consensus/ethash"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
//go:generate gencodec -type DifficultyTest -field-override difficultyTestMarshaling -out gen_difficultytest.go
diff --git a/tests/gen_btheader.go b/tests/gen_btheader.go
index 5d65e0dbce79..4dbc6bde4aaa 100644
--- a/tests/gen_btheader.go
+++ b/tests/gen_btheader.go
@@ -6,10 +6,10 @@ import (
"encoding/json"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core/types"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
)
var _ = (*btHeaderMarshaling)(nil)
diff --git a/tests/gen_difficultytest.go b/tests/gen_difficultytest.go
index 88f36ce99957..698d11653d13 100644
--- a/tests/gen_difficultytest.go
+++ b/tests/gen_difficultytest.go
@@ -6,8 +6,8 @@ import (
"encoding/json"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
)
var _ = (*difficultyTestMarshaling)(nil)
diff --git a/tests/gen_stenv.go b/tests/gen_stenv.go
index c780524bc30c..0e8f361deafd 100644
--- a/tests/gen_stenv.go
+++ b/tests/gen_stenv.go
@@ -7,8 +7,8 @@ import (
"errors"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
)
var _ = (*stEnvMarshaling)(nil)
diff --git a/tests/gen_sttransaction.go b/tests/gen_sttransaction.go
index 5a489d00b839..ac0af984aacb 100644
--- a/tests/gen_sttransaction.go
+++ b/tests/gen_sttransaction.go
@@ -6,8 +6,8 @@ import (
"encoding/json"
"math/big"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
)
var _ = (*stTransactionMarshaling)(nil)
diff --git a/tests/gen_tttransaction.go b/tests/gen_tttransaction.go
index b6759be9125a..5418e62f1b70 100644
--- a/tests/gen_tttransaction.go
+++ b/tests/gen_tttransaction.go
@@ -7,9 +7,9 @@ import (
"errors"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
)
var _ = (*ttTransactionMarshaling)(nil)
diff --git a/tests/gen_vmexec.go b/tests/gen_vmexec.go
index dd2d3d94e74c..2bd3f56d3ef0 100644
--- a/tests/gen_vmexec.go
+++ b/tests/gen_vmexec.go
@@ -7,9 +7,9 @@ import (
"errors"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
)
var _ = (*vmExecMarshaling)(nil)
diff --git a/tests/init.go b/tests/init.go
index 9e884efe3961..766613547cf0 100644
--- a/tests/init.go
+++ b/tests/init.go
@@ -20,7 +20,7 @@ import (
"fmt"
"math/big"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
// This table defines supported forks and their chain config.
diff --git a/tests/init_test.go b/tests/init_test.go
index ebb0d32c34a4..e193e601d004 100644
--- a/tests/init_test.go
+++ b/tests/init_test.go
@@ -29,7 +29,7 @@ import (
"strings"
"testing"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
var (
diff --git a/tests/rlp_test_util.go b/tests/rlp_test_util.go
index 58ef8a6428c0..61a79f8f048d 100644
--- a/tests/rlp_test_util.go
+++ b/tests/rlp_test_util.go
@@ -24,7 +24,7 @@ import (
"math/big"
"strings"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
// RLPTest is the JSON structure of a single RLP test.
diff --git a/tests/state_test.go b/tests/state_test.go
index 5a67b290db70..0dbcacb808d9 100644
--- a/tests/state_test.go
+++ b/tests/state_test.go
@@ -22,7 +22,7 @@ import (
"reflect"
"testing"
- "github.com/ethereum/go-ethereum/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
)
func TestState(t *testing.T) {
diff --git a/tests/state_test_util.go b/tests/state_test_util.go
index 352f840d9fd3..a162cd062e19 100644
--- a/tests/state_test_util.go
+++ b/tests/state_test_util.go
@@ -23,18 +23,18 @@ import (
"math/big"
"strings"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
- "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"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/crypto/sha3"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
// StateTest checks transaction processing without block context.
diff --git a/tests/transaction_test.go b/tests/transaction_test.go
index c743996c2a9f..3be752e03490 100644
--- a/tests/transaction_test.go
+++ b/tests/transaction_test.go
@@ -20,7 +20,7 @@ import (
"math/big"
"testing"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
func TestTransaction(t *testing.T) {
diff --git a/tests/transaction_test_util.go b/tests/transaction_test_util.go
index 472b3d6f2420..4b9fd9c1d714 100644
--- a/tests/transaction_test_util.go
+++ b/tests/transaction_test_util.go
@@ -22,12 +22,12 @@ import (
"fmt"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/core/types"
+ "github.com/teamnsrg/ethereum-p2p/params"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
// TransactionTest checks RLP decoding and sender derivation of transactions.
diff --git a/tests/vm_test.go b/tests/vm_test.go
index c9f5e225e987..4ed4ec495d89 100644
--- a/tests/vm_test.go
+++ b/tests/vm_test.go
@@ -19,7 +19,7 @@ package tests
import (
"testing"
- "github.com/ethereum/go-ethereum/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
)
func TestVM(t *testing.T) {
diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go
index 0aa37955ce35..e3831189df2e 100644
--- a/tests/vm_test_util.go
+++ b/tests/vm_test_util.go
@@ -22,15 +22,15 @@ import (
"fmt"
"math/big"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/params"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/common/hexutil"
+ "github.com/teamnsrg/ethereum-p2p/common/math"
+ "github.com/teamnsrg/ethereum-p2p/core"
+ "github.com/teamnsrg/ethereum-p2p/core/state"
+ "github.com/teamnsrg/ethereum-p2p/core/vm"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/params"
)
// VMTest checks EVM execution without block or transaction context.
diff --git a/trie/errors.go b/trie/errors.go
index 567b80078c06..dfd0d8fb94c5 100644
--- a/trie/errors.go
+++ b/trie/errors.go
@@ -19,7 +19,7 @@ package trie
import (
"fmt"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
// MissingNodeError is returned by the trie functions (TryGet, TryUpdate, TryDelete)
diff --git a/trie/hasher.go b/trie/hasher.go
index 4719aabf62c1..7437aa78ecec 100644
--- a/trie/hasher.go
+++ b/trie/hasher.go
@@ -21,9 +21,9 @@ import (
"hash"
"sync"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto/sha3"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto/sha3"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
type hasher struct {
diff --git a/trie/iterator.go b/trie/iterator.go
index 76146c0d64f8..743e2ef56ee8 100644
--- a/trie/iterator.go
+++ b/trie/iterator.go
@@ -21,7 +21,7 @@ import (
"container/heap"
"errors"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
)
// Iterator is a key-value trie iterator that traverses a Trie.
diff --git a/trie/iterator_test.go b/trie/iterator_test.go
index 4808d8b0c662..2e31d7010408 100644
--- a/trie/iterator_test.go
+++ b/trie/iterator_test.go
@@ -22,8 +22,8 @@ import (
"math/rand"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
)
func TestIterator(t *testing.T) {
diff --git a/trie/node.go b/trie/node.go
index a7697fc0c656..7615b1a3a186 100644
--- a/trie/node.go
+++ b/trie/node.go
@@ -21,8 +21,8 @@ import (
"io"
"strings"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
var indices = []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "[17]"}
diff --git a/trie/proof.go b/trie/proof.go
index 5e886a2598b8..4e62678d856d 100644
--- a/trie/proof.go
+++ b/trie/proof.go
@@ -20,10 +20,10 @@ import (
"bytes"
"fmt"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/log"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
// Prove constructs a merkle proof for key. The result contains all
diff --git a/trie/proof_test.go b/trie/proof_test.go
index fff313d7fdfb..eb0b8f6940b9 100644
--- a/trie/proof_test.go
+++ b/trie/proof_test.go
@@ -23,9 +23,9 @@ import (
"testing"
"time"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
)
func init() {
diff --git a/trie/secure_trie.go b/trie/secure_trie.go
index 20c303f31c3d..4b9cf01119e0 100644
--- a/trie/secure_trie.go
+++ b/trie/secure_trie.go
@@ -19,8 +19,8 @@ package trie
import (
"fmt"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/log"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
var secureKeyPrefix = []byte("secure-key-")
diff --git a/trie/secure_trie_test.go b/trie/secure_trie_test.go
index d74102e2a295..ce89c203fe10 100644
--- a/trie/secure_trie_test.go
+++ b/trie/secure_trie_test.go
@@ -22,9 +22,9 @@ import (
"sync"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
)
func newEmptySecure() *SecureTrie {
diff --git a/trie/sync.go b/trie/sync.go
index fea10051f442..7d30da264739 100644
--- a/trie/sync.go
+++ b/trie/sync.go
@@ -20,7 +20,7 @@ import (
"errors"
"fmt"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/teamnsrg/ethereum-p2p/common"
"gopkg.in/karalabe/cookiejar.v2/collections/prque"
)
diff --git a/trie/sync_test.go b/trie/sync_test.go
index ec16a25bd9cc..c231796d0cd0 100644
--- a/trie/sync_test.go
+++ b/trie/sync_test.go
@@ -20,8 +20,8 @@ import (
"bytes"
"testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
)
// makeTestTrie create a sample test trie to test node-wise reconstruction.
diff --git a/trie/trie.go b/trie/trie.go
index 7f69a3d1de1c..80993c3e11e1 100644
--- a/trie/trie.go
+++ b/trie/trie.go
@@ -21,10 +21,10 @@ import (
"bytes"
"fmt"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto/sha3"
- "github.com/ethereum/go-ethereum/log"
"github.com/rcrowley/go-metrics"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto/sha3"
+ "github.com/teamnsrg/ethereum-p2p/log"
)
var (
diff --git a/trie/trie_test.go b/trie/trie_test.go
index 1e28c3bc4874..ca5603d4750c 100644
--- a/trie/trie_test.go
+++ b/trie/trie_test.go
@@ -30,10 +30,10 @@ import (
"testing/quick"
"github.com/davecgh/go-spew/spew"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/rlp"
+ "github.com/teamnsrg/ethereum-p2p/common"
+ "github.com/teamnsrg/ethereum-p2p/crypto"
+ "github.com/teamnsrg/ethereum-p2p/ethdb"
+ "github.com/teamnsrg/ethereum-p2p/rlp"
)
func init() {
diff --git a/vendor/github.com/dgrijalva/jwt-go/token.go b/vendor/github.com/dgrijalva/jwt-go/token.go
index d637e0867c65..99868d29b9fd 100644
--- a/vendor/github.com/dgrijalva/jwt-go/token.go
+++ b/vendor/github.com/dgrijalva/jwt-go/token.go
@@ -65,7 +65,7 @@ func (t *Token) SignedString(key interface{}) (string, error) {
func (t *Token) SigningString() (string, error) {
var err error
parts := make([]string, 2)
- for i, _ := range parts {
+ for i := range parts {
var jsonValue []byte
if i == 0 {
if jsonValue, err = json.Marshal(t.Header); err != nil {
diff --git a/vendor/github.com/gizak/termui/events.go b/vendor/github.com/gizak/termui/events.go
index 16d9bd9cc34a..83f5b03c3b87 100644
--- a/vendor/github.com/gizak/termui/events.go
+++ b/vendor/github.com/gizak/termui/events.go
@@ -224,7 +224,7 @@ func findMatch(mux map[string]func(Event), path string) string {
// Remove all existing defined Handlers from the map
func (es *EvtStream) ResetHandlers() {
- for Path, _ := range es.Handlers {
+ for Path := range es.Handlers {
delete(es.Handlers, Path)
}
return
diff --git a/vendor/github.com/gizak/termui/theme.go b/vendor/github.com/gizak/termui/theme.go
index 21fb3bfb751a..0d83c8e229aa 100644
--- a/vendor/github.com/gizak/termui/theme.go
+++ b/vendor/github.com/gizak/termui/theme.go
@@ -111,7 +111,7 @@ func lookUpAttr(clrmap map[string]Attribute, name string) Attribute {
ns := strings.Split(name, ".")
for i := range ns {
- nn := strings.Join(ns[i:len(ns)], ".")
+ nn := strings.Join(ns[i:], ".")
a, ok = ColorMap[nn]
if ok {
break
diff --git a/vendor/github.com/mattn/go-colorable/colorable_windows.go b/vendor/github.com/mattn/go-colorable/colorable_windows.go
index 628ad904e591..d22efebf9ce3 100644
--- a/vendor/github.com/mattn/go-colorable/colorable_windows.go
+++ b/vendor/github.com/mattn/go-colorable/colorable_windows.go
@@ -700,22 +700,22 @@ func (c consoleColor) backgroundAttr() (attr word) {
}
var color16 = []consoleColor{
- consoleColor{0x000000, false, false, false, false},
- consoleColor{0x000080, false, false, true, false},
- consoleColor{0x008000, false, true, false, false},
- consoleColor{0x008080, false, true, true, false},
- consoleColor{0x800000, true, false, false, false},
- consoleColor{0x800080, true, false, true, false},
- consoleColor{0x808000, true, true, false, false},
- consoleColor{0xc0c0c0, true, true, true, false},
- consoleColor{0x808080, false, false, false, true},
- consoleColor{0x0000ff, false, false, true, true},
- consoleColor{0x00ff00, false, true, false, true},
- consoleColor{0x00ffff, false, true, true, true},
- consoleColor{0xff0000, true, false, false, true},
- consoleColor{0xff00ff, true, false, true, true},
- consoleColor{0xffff00, true, true, false, true},
- consoleColor{0xffffff, true, true, true, true},
+ {0x000000, false, false, false, false},
+ {0x000080, false, false, true, false},
+ {0x008000, false, true, false, false},
+ {0x008080, false, true, true, false},
+ {0x800000, true, false, false, false},
+ {0x800080, true, false, true, false},
+ {0x808000, true, true, false, false},
+ {0xc0c0c0, true, true, true, false},
+ {0x808080, false, false, false, true},
+ {0x0000ff, false, false, true, true},
+ {0x00ff00, false, true, false, true},
+ {0x00ffff, false, true, true, true},
+ {0xff0000, true, false, false, true},
+ {0xff00ff, true, false, true, true},
+ {0xffff00, true, true, false, true},
+ {0xffffff, true, true, true, true},
}
type hsv struct {
diff --git a/vendor/github.com/mikioh/tcp/LICENSE b/vendor/github.com/mikioh/tcp/LICENSE
new file mode 100644
index 000000000000..0b0f8cdc74b8
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/LICENSE
@@ -0,0 +1,23 @@
+Copyright (c) 2014, Mikio Hara
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/mikioh/tcp/README.md b/vendor/github.com/mikioh/tcp/README.md
new file mode 100644
index 000000000000..5233aed761a7
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/README.md
@@ -0,0 +1,6 @@
+Package tcp provides TCP-level socket options that allow manipulation of TCP connection facilities.
+
+[![GoDoc](https://godoc.org/github.com/mikioh/tcp?status.png)](https://godoc.org/github.com/mikioh/tcp)
+[![Build Status](https://travis-ci.org/mikioh/tcp.svg?branch=master)](https://travis-ci.org/mikioh/tcp)
+[![Build status](https://ci.appveyor.com/api/projects/status/q8ejg9mvstq23j3r?svg=true)](https://ci.appveyor.com/project/mikioh/tcp)
+[![Go Report Card](https://goreportcard.com/badge/github.com/mikioh/tcp)](https://goreportcard.com/report/github.com/mikioh/tcp)
diff --git a/vendor/github.com/mikioh/tcp/appveyor.yml b/vendor/github.com/mikioh/tcp/appveyor.yml
new file mode 100644
index 000000000000..7347da459b03
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/appveyor.yml
@@ -0,0 +1,19 @@
+version: "{build}"
+
+branches:
+ only:
+ - master
+
+environment:
+ GOPATH: c:\gopath
+
+install:
+ - set PATH=%GOPATH%\bin;c:\go\bin;%PATH%
+ - mkdir c:\gopath
+ - go get github.com/mikioh/tcp
+ - go get github.com/mikioh/tcpopt
+ - go get github.com/mikioh/tcpinfo
+ - go get golang.org/x/net/nettest
+
+build_script:
+ - go test -v -race
diff --git a/vendor/github.com/mikioh/tcp/conn.go b/vendor/github.com/mikioh/tcp/conn.go
new file mode 100644
index 000000000000..358dc20f0cf3
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/conn.go
@@ -0,0 +1,82 @@
+// Copyright 2014 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+import (
+ "net"
+ "syscall"
+
+ "github.com/mikioh/tcpopt"
+)
+
+var _ net.Conn = &Conn{}
+
+// SetOption sets a socket option.
+func (c *Conn) SetOption(o tcpopt.Option) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ b, err := o.Marshal()
+ if err != nil {
+ return &net.OpError{Op: "raw-control", Net: c.LocalAddr().Network(), Source: nil, Addr: c.LocalAddr(), Err: err}
+ }
+ if err := c.setOption(o.Level(), o.Name(), b); err != nil {
+ return &net.OpError{Op: "raw-control", Net: c.LocalAddr().Network(), Source: nil, Addr: c.LocalAddr(), Err: err}
+ }
+ return nil
+}
+
+// Option returns a socket option.
+func (c *Conn) Option(level, name int, b []byte) (tcpopt.Option, error) {
+ if !c.ok() || len(b) == 0 {
+ return nil, syscall.EINVAL
+ }
+ n, err := c.option(level, name, b)
+ if err != nil {
+ return nil, &net.OpError{Op: "raw-control", Net: c.LocalAddr().Network(), Source: nil, Addr: c.LocalAddr(), Err: err}
+ }
+ o, err := tcpopt.Parse(level, name, b[:n])
+ if err != nil {
+ return nil, &net.OpError{Op: "raw-control", Net: c.LocalAddr().Network(), Source: nil, Addr: c.LocalAddr(), Err: err}
+ }
+ return o, nil
+}
+
+// Buffered returns the number of bytes that can be read from the
+// underlying socket read buffer.
+// It returns -1 when the platform doesn't support this feature.
+func (c *Conn) Buffered() int {
+ if !c.ok() {
+ return -1
+ }
+ return c.buffered()
+}
+
+// Available returns how many bytes are unused in the underlying
+// socket write buffer.
+// It returns -1 when the platform doesn't support this feature.
+func (c *Conn) Available() int {
+ if !c.ok() {
+ return -1
+ }
+ return c.available()
+}
+
+// OriginalDst returns an original destination address, which is an
+// address not modified by intermediate entities such as network
+// address and port translators inside the kernel, on the connection.
+//
+// Only Linux and BSD variants using PF support this feature.
+func (c *Conn) OriginalDst() (net.Addr, error) {
+ if !c.ok() {
+ return nil, syscall.EINVAL
+ }
+ la := c.LocalAddr().(*net.TCPAddr)
+ od, err := c.originalDst(la, c.RemoteAddr().(*net.TCPAddr))
+ if err != nil {
+ return nil, &net.OpError{Op: "raw-control", Net: c.LocalAddr().Network(), Source: nil, Addr: la, Err: err}
+ }
+ return od, nil
+}
diff --git a/vendor/github.com/mikioh/tcp/conn_bsd.go b/vendor/github.com/mikioh/tcp/conn_bsd.go
new file mode 100644
index 000000000000..9f589d4fdb6d
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/conn_bsd.go
@@ -0,0 +1,59 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd openbsd
+
+package tcp
+
+import (
+ "net"
+ "os"
+ "syscall"
+ "unsafe"
+)
+
+func (*Conn) originalDst(la, ra *net.TCPAddr) (net.Addr, error) {
+ f, err := os.Open("/dev/pf")
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ fd := f.Fd()
+ b := make([]byte, sizeofPfiocNatlook)
+ nl := (*pfiocNatlook)(unsafe.Pointer(&b[0]))
+ if ra.IP.To4() != nil {
+ copy(nl.Saddr[:net.IPv4len], ra.IP.To4())
+ copy(nl.Daddr[:net.IPv4len], la.IP.To4())
+ nl.Af = sysAF_INET
+ }
+ if ra.IP.To16() != nil && ra.IP.To4() == nil {
+ copy(nl.Saddr[:], ra.IP)
+ copy(nl.Daddr[:], la.IP)
+ nl.Af = sysAF_INET6
+ }
+ nl.setPort(ra.Port, la.Port)
+ nl.Proto = ianaProtocolTCP
+ ioc := uintptr(sysDIOCNATLOOK)
+ for _, dir := range []byte{sysPF_OUT, sysPF_IN} {
+ nl.Direction = dir
+ err = ioctl(fd, int(ioc), b)
+ if err == nil || err != syscall.ENOENT {
+ break
+ }
+ }
+ if err != nil {
+ return nil, os.NewSyscallError("ioctl", err)
+ }
+ od := new(net.TCPAddr)
+ od.Port = nl.rdPort()
+ switch nl.Af {
+ case sysAF_INET:
+ od.IP = make(net.IP, net.IPv4len)
+ copy(od.IP, nl.Rdaddr[:net.IPv4len])
+ case sysAF_INET6:
+ od.IP = make(net.IP, net.IPv6len)
+ copy(od.IP, nl.Rdaddr[:])
+ }
+ return od, nil
+}
diff --git a/vendor/github.com/mikioh/tcp/conn_linux.go b/vendor/github.com/mikioh/tcp/conn_linux.go
new file mode 100644
index 000000000000..aec5e2f1a673
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/conn_linux.go
@@ -0,0 +1,44 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+import (
+ "encoding/binary"
+ "net"
+ "unsafe"
+)
+
+func (c *Conn) originalDst(la, _ *net.TCPAddr) (net.Addr, error) {
+ var level, name int
+ var b []byte
+ if la.IP.To4() != nil {
+ level = ianaProtocolIP
+ name = sysSO_ORIGINAL_DST
+ b = make([]byte, sizeofSockaddrInet)
+ }
+ if la.IP.To16() != nil && la.IP.To4() == nil {
+ level = ianaProtocolIPv6
+ name = sysIP6T_SO_ORIGINAL_DST
+ b = make([]byte, sizeofSockaddrInet6)
+ }
+ if _, err := c.option(level, name, b); err != nil {
+ return nil, err
+ }
+ od := new(net.TCPAddr)
+ switch len(b) {
+ case sizeofSockaddrInet:
+ sa := (*sockaddrInet)(unsafe.Pointer(&b[0]))
+ od.IP = make(net.IP, net.IPv4len)
+ copy(od.IP, sa.Addr[:])
+ od.Port = int(binary.BigEndian.Uint16((*[2]byte)(unsafe.Pointer(&sa.Port))[:]))
+ case sizeofSockaddrInet6:
+ sa := (*sockaddrInet6)(unsafe.Pointer(&b[0]))
+ od.IP = make(net.IP, net.IPv6len)
+ copy(od.IP, sa.Addr[:])
+ od.Port = int(binary.BigEndian.Uint16((*[2]byte)(unsafe.Pointer(&sa.Port))[:]))
+ od.Zone = zoneCache.name(int(sa.Scope_id))
+ }
+ return od, nil
+}
diff --git a/vendor/github.com/mikioh/tcp/conn_stub.go b/vendor/github.com/mikioh/tcp/conn_stub.go
new file mode 100644
index 000000000000..66ff9e2a02d3
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/conn_stub.go
@@ -0,0 +1,16 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !darwin,!dragonfly,!freebsd,!linux,!openbsd
+
+package tcp
+
+import (
+ "errors"
+ "net"
+)
+
+func (c *Conn) originalDst(la, ra *net.TCPAddr) (net.Addr, error) {
+ return nil, errors.New("not implemented")
+}
diff --git a/vendor/github.com/mikioh/tcp/doc.go b/vendor/github.com/mikioh/tcp/doc.go
new file mode 100644
index 000000000000..6a35259eee03
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/doc.go
@@ -0,0 +1,9 @@
+// Copyright 2014 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package tcp implements TCP-level socket options.
+//
+// The package provides TCP-level socket options that allow
+// manipulation of TCP connection facilities.
+package tcp
diff --git a/vendor/github.com/mikioh/tcp/ipv6zone.go b/vendor/github.com/mikioh/tcp/ipv6zone.go
new file mode 100644
index 000000000000..dfa2ce6c3ff7
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/ipv6zone.go
@@ -0,0 +1,73 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+import (
+ "fmt"
+ "net"
+ "strconv"
+ "sync"
+ "time"
+)
+
+type ipv6ZoneCache struct {
+ sync.RWMutex
+ lastFetched time.Time
+ toIndex map[string]int
+ toName map[int]string
+}
+
+var zoneCache = ipv6ZoneCache{
+ toIndex: make(map[string]int),
+ toName: make(map[int]string),
+}
+
+func (zc *ipv6ZoneCache) index(name string) int {
+ if name == "" {
+ return 0
+ }
+ zc.update()
+ zc.RLock()
+ defer zc.RUnlock()
+ index, ok := zc.toIndex[name]
+ if !ok {
+ index, _ = strconv.Atoi(name)
+ }
+ return index
+}
+
+func (zc *ipv6ZoneCache) name(index int) string {
+ if index == 0 {
+ return ""
+ }
+ zc.update()
+ zc.RLock()
+ defer zc.RUnlock()
+ name, ok := zc.toName[index]
+ if !ok {
+ name = fmt.Sprintf("%d", index)
+ }
+ return name
+}
+
+func (zc *ipv6ZoneCache) update() {
+ zc.Lock()
+ defer zc.Unlock()
+ now := time.Now()
+ if zc.lastFetched.After(now.Add(-60 * time.Second)) {
+ return
+ }
+ zc.lastFetched = now
+ ift, err := net.Interfaces()
+ if err != nil {
+ return
+ }
+ zc.toIndex = make(map[string]int, len(ift))
+ zc.toName = make(map[int]string, len(ift))
+ for _, ifi := range ift {
+ zc.toIndex[ifi.Name] = ifi.Index
+ zc.toName[ifi.Index] = ifi.Name
+ }
+}
diff --git a/vendor/github.com/mikioh/tcp/rawconn.go b/vendor/github.com/mikioh/tcp/rawconn.go
new file mode 100644
index 000000000000..1c7374093bc9
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/rawconn.go
@@ -0,0 +1,114 @@
+// Copyright 2017 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.9
+
+package tcp
+
+import (
+ "errors"
+ "net"
+ "os"
+ "runtime"
+ "syscall"
+
+ "github.com/mikioh/tcpopt"
+)
+
+// A Conn represents an end point that uses TCP connection.
+// It allows to set non-portable, platform-dependent TCP-level socket
+// options.
+type Conn struct {
+ net.Conn
+ c syscall.RawConn
+}
+
+func (c *Conn) ok() bool { return c != nil && c.Conn != nil && c.c != nil }
+
+func (c *Conn) setOption(level, name int, b []byte) error {
+ var operr error
+ fn := func(s uintptr) {
+ operr = setsockopt(s, level, name, b)
+ }
+ if err := c.c.Control(fn); err != nil {
+ return err
+ }
+ return os.NewSyscallError("setsockopt", operr)
+}
+
+func (c *Conn) option(level, name int, b []byte) (int, error) {
+ var operr error
+ var n int
+ fn := func(s uintptr) {
+ n, operr = getsockopt(s, level, name, b)
+ }
+ if err := c.c.Control(fn); err != nil {
+ return 0, err
+ }
+ return n, os.NewSyscallError("getsockopt", operr)
+}
+
+func (c *Conn) buffered() int {
+ var operr error
+ var n int
+ fn := func(s uintptr) {
+ var b [4]byte
+ operr = ioctl(s, options[soBuffered].name, b[:])
+ if operr != nil {
+ return
+ }
+ n = int(nativeEndian.Uint32(b[:]))
+ }
+ err := c.c.Control(fn)
+ if err != nil || operr != nil {
+ return -1
+ }
+ return n
+}
+
+func (c *Conn) available() int {
+ var operr error
+ var n int
+ fn := func(s uintptr) {
+ var b [4]byte
+ if runtime.GOOS == "darwin" {
+ _, operr = getsockopt(s, options[soAvailable].level, options[soAvailable].name, b[:])
+ } else {
+ operr = ioctl(s, options[soAvailable].name, b[:])
+ }
+ if operr != nil {
+ return
+ }
+ n = int(nativeEndian.Uint32(b[:]))
+ if runtime.GOOS == "darwin" || runtime.GOOS == "linux" {
+ var o tcpopt.SendBuffer
+ _, operr = getsockopt(s, o.Level(), o.Name(), b[:])
+ if operr != nil {
+ return
+ }
+ n = int(nativeEndian.Uint32(b[:])) - n
+ }
+ }
+ err := c.c.Control(fn)
+ if err != nil || operr != nil {
+ return -1
+ }
+ return n
+}
+
+// NewConn returns a new end point.
+func NewConn(c net.Conn) (*Conn, error) {
+ cc := &Conn{Conn: c}
+ switch c := c.(type) {
+ case *net.TCPConn:
+ var err error
+ cc.c, err = c.SyscallConn()
+ if err != nil {
+ return nil, err
+ }
+ return cc, nil
+ default:
+ return nil, errors.New("unknown connection type")
+ }
+}
diff --git a/vendor/github.com/mikioh/tcp/reflect.go b/vendor/github.com/mikioh/tcp/reflect.go
new file mode 100644
index 000000000000..8152e621cadf
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/reflect.go
@@ -0,0 +1,109 @@
+// Copyright 2014 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.9
+
+package tcp
+
+import (
+ "errors"
+ "net"
+ "os"
+ "reflect"
+ "runtime"
+ "sync/atomic"
+ "syscall"
+
+ "github.com/mikioh/tcpopt"
+)
+
+// A Conn represents an end point that uses TCP connection.
+// It allows to set non-portable, platform-dependent TCP-level socket
+// options.
+type Conn struct {
+ net.Conn
+ s uintptr // socket descriptor for configuring options
+}
+
+func (c *Conn) ok() bool { return c != nil && c.Conn != nil }
+
+func (c *Conn) setOption(level, name int, b []byte) error {
+ return os.NewSyscallError("setsockopt", setsockopt(c.s, level, name, b))
+}
+
+func (c *Conn) option(level, name int, b []byte) (int, error) {
+ n, err := getsockopt(c.s, level, name, b)
+ return n, os.NewSyscallError("getsockopt", err)
+}
+
+func (c *Conn) buffered() int {
+ var b [4]byte
+ if err := ioctl(c.s, options[soBuffered].name, b[:]); err != nil {
+ return -1
+ }
+ return int(nativeEndian.Uint32(b[:]))
+}
+
+func (c *Conn) available() int {
+ var err error
+ var b [4]byte
+ if runtime.GOOS == "darwin" {
+ _, err = getsockopt(c.s, options[soAvailable].level, options[soAvailable].name, b[:])
+ } else {
+ err = ioctl(c.s, options[soAvailable].name, b[:])
+ }
+ if err != nil {
+ return -1
+ }
+ n := int(nativeEndian.Uint32(b[:]))
+ if runtime.GOOS == "darwin" || runtime.GOOS == "linux" {
+ var o tcpopt.SendBuffer
+ _, err = getsockopt(c.s, o.Level(), o.Name(), b[:])
+ if err != nil {
+ return -1
+ }
+ n = int(nativeEndian.Uint32(b[:])) - n
+ }
+ return n
+}
+
+// Close closes the connection.
+func (c *Conn) Close() error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ atomic.StoreUintptr(&c.s, ^uintptr(0))
+ return c.Conn.Close()
+}
+
+// NewConn returns a new end point.
+func NewConn(c net.Conn) (*Conn, error) {
+ s, err := socketOf(c)
+ if err != nil {
+ return nil, err
+ }
+ cc := &Conn{Conn: c}
+ atomic.StoreUintptr(&cc.s, s)
+ return cc, nil
+}
+
+func socketOf(c net.Conn) (uintptr, error) {
+ switch c.(type) {
+ case *net.TCPConn, *net.UDPConn, *net.IPConn:
+ v := reflect.ValueOf(c)
+ switch e := v.Elem(); e.Kind() {
+ case reflect.Struct:
+ fd := e.FieldByName("conn").FieldByName("fd")
+ switch e := fd.Elem(); e.Kind() {
+ case reflect.Struct:
+ sysfd := e.FieldByName("sysfd")
+ if runtime.GOOS == "windows" {
+ return uintptr(sysfd.Uint()), nil
+ }
+ return uintptr(sysfd.Int()), nil
+ }
+ }
+ }
+ return 0, errors.New("invalid type")
+}
diff --git a/vendor/github.com/mikioh/tcp/sys.go b/vendor/github.com/mikioh/tcp/sys.go
new file mode 100644
index 000000000000..57fc284ba045
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys.go
@@ -0,0 +1,39 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+import (
+ "encoding/binary"
+ "unsafe"
+)
+
+var nativeEndian binary.ByteOrder
+
+func init() {
+ i := uint32(1)
+ b := (*[4]byte)(unsafe.Pointer(&i))
+ if b[0] == 1 {
+ nativeEndian = binary.LittleEndian
+ } else {
+ nativeEndian = binary.BigEndian
+ }
+}
+
+const (
+ ianaProtocolIP = 0x0
+ ianaProtocolTCP = 0x6
+ ianaProtocolIPv6 = 0x29
+)
+
+const (
+ soBuffered = iota
+ soAvailable
+ soMax
+)
+
+type option struct {
+ level int // option level
+ name int // option name, must be equal or greater than 1
+}
diff --git a/vendor/github.com/mikioh/tcp/sys_darwin.go b/vendor/github.com/mikioh/tcp/sys_darwin.go
new file mode 100644
index 000000000000..b1a03f4b43bc
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_darwin.go
@@ -0,0 +1,24 @@
+// Copyright 2014 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+import (
+ "encoding/binary"
+ "unsafe"
+)
+
+var options = [soMax]option{
+ soBuffered: {0, sysFIONREAD},
+ soAvailable: {sysSOL_SOCKET, sysSO_NWRITE},
+}
+
+func (nl *pfiocNatlook) rdPort() int {
+ return int(binary.BigEndian.Uint16(nl.Rdxport[:2]))
+}
+
+func (nl *pfiocNatlook) setPort(remote, local int) {
+ binary.BigEndian.PutUint16((*[2]byte)(unsafe.Pointer(&nl.Sxport))[:2], uint16(remote))
+ binary.BigEndian.PutUint16((*[2]byte)(unsafe.Pointer(&nl.Dxport))[:2], uint16(local))
+}
diff --git a/vendor/github.com/mikioh/tcp/sys_dragonfly.go b/vendor/github.com/mikioh/tcp/sys_dragonfly.go
new file mode 100644
index 000000000000..c00a7a60a216
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_dragonfly.go
@@ -0,0 +1,23 @@
+// Copyright 2014 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+import (
+ "encoding/binary"
+ "unsafe"
+)
+
+var options = [soMax]option{
+ soBuffered: {0, sysFIONREAD},
+}
+
+func (nl *pfiocNatlook) rdPort() int {
+ return int(binary.BigEndian.Uint16((*[2]byte)(unsafe.Pointer(&nl.Rdport))[:]))
+}
+
+func (nl *pfiocNatlook) setPort(remote, local int) {
+ binary.BigEndian.PutUint16((*[2]byte)(unsafe.Pointer(&nl.Sport))[:], uint16(remote))
+ binary.BigEndian.PutUint16((*[2]byte)(unsafe.Pointer(&nl.Dport))[:], uint16(local))
+}
diff --git a/vendor/github.com/mikioh/tcp/sys_freebsd.go b/vendor/github.com/mikioh/tcp/sys_freebsd.go
new file mode 100644
index 000000000000..1e60da107574
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_freebsd.go
@@ -0,0 +1,24 @@
+// Copyright 2014 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+import (
+ "encoding/binary"
+ "unsafe"
+)
+
+var options = [soMax]option{
+ soBuffered: {0, sysFIONREAD},
+ soAvailable: {0, sysFIONSPACE},
+}
+
+func (nl *pfiocNatlook) rdPort() int {
+ return int(binary.BigEndian.Uint16((*[2]byte)(unsafe.Pointer(&nl.Rdport))[:]))
+}
+
+func (nl *pfiocNatlook) setPort(remote, local int) {
+ binary.BigEndian.PutUint16((*[2]byte)(unsafe.Pointer(&nl.Sport))[:], uint16(remote))
+ binary.BigEndian.PutUint16((*[2]byte)(unsafe.Pointer(&nl.Dport))[:], uint16(local))
+}
diff --git a/vendor/github.com/mikioh/tcp/sys_linux.go b/vendor/github.com/mikioh/tcp/sys_linux.go
new file mode 100644
index 000000000000..602eb0bd9c58
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_linux.go
@@ -0,0 +1,10 @@
+// Copyright 2014 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+var options = [soMax]option{
+ soBuffered: {0, sysSIOCINQ},
+ soAvailable: {0, sysSIOCOUTQ},
+}
diff --git a/vendor/github.com/mikioh/tcp/sys_linux_386.go b/vendor/github.com/mikioh/tcp/sys_linux_386.go
new file mode 100644
index 000000000000..3f7271432753
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_linux_386.go
@@ -0,0 +1,44 @@
+// Copyright 2014 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+const (
+ sysSIOCINQ = 0x541b
+ sysSIOCOUTQ = 0x5411
+)
+
+func ioctl(s uintptr, ioc int, b []byte) error {
+ if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, s, uintptr(ioc), uintptr(unsafe.Pointer(&b[0]))); errno != 0 {
+ return error(errno)
+ }
+ return nil
+}
+
+const (
+ sysSETSOCKOPT = 0xe
+ sysGETSOCKOPT = 0xf
+)
+
+func socketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno)
+
+func setsockopt(s uintptr, level, name int, b []byte) error {
+ if _, errno := socketcall(sysSETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0); errno != 0 {
+ return error(errno)
+ }
+ return nil
+}
+
+func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
+ l := uint32(len(b))
+ if _, errno := socketcall(sysGETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&l)), 0); errno != 0 {
+ return int(l), error(errno)
+ }
+ return int(l), nil
+}
diff --git a/vendor/github.com/mikioh/tcp/sys_linux_386.s b/vendor/github.com/mikioh/tcp/sys_linux_386.s
new file mode 100644
index 000000000000..34c5db197143
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_linux_386.s
@@ -0,0 +1,8 @@
+// Copyright 2014 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·socketcall(SB),NOSPLIT,$0-36
+ JMP syscall·socketcall(SB)
diff --git a/vendor/github.com/mikioh/tcp/sys_linux_amd64.go b/vendor/github.com/mikioh/tcp/sys_linux_amd64.go
new file mode 100644
index 000000000000..b2c1561adcc3
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_linux_amd64.go
@@ -0,0 +1,10 @@
+// Copyright 2017 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+const (
+ sysSIOCINQ = 0x541b
+ sysSIOCOUTQ = 0x5411
+)
diff --git a/vendor/github.com/mikioh/tcp/sys_linux_arm.go b/vendor/github.com/mikioh/tcp/sys_linux_arm.go
new file mode 100644
index 000000000000..b2c1561adcc3
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_linux_arm.go
@@ -0,0 +1,10 @@
+// Copyright 2017 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+const (
+ sysSIOCINQ = 0x541b
+ sysSIOCOUTQ = 0x5411
+)
diff --git a/vendor/github.com/mikioh/tcp/sys_linux_arm64.go b/vendor/github.com/mikioh/tcp/sys_linux_arm64.go
new file mode 100644
index 000000000000..b2c1561adcc3
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_linux_arm64.go
@@ -0,0 +1,10 @@
+// Copyright 2017 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+const (
+ sysSIOCINQ = 0x541b
+ sysSIOCOUTQ = 0x5411
+)
diff --git a/vendor/github.com/mikioh/tcp/sys_linux_mips.go b/vendor/github.com/mikioh/tcp/sys_linux_mips.go
new file mode 100644
index 000000000000..2b871d2d5d86
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_linux_mips.go
@@ -0,0 +1,10 @@
+// Copyright 2017 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+const (
+ sysSIOCINQ = 0x467f
+ sysSIOCOUTQ = 0x7472
+)
diff --git a/vendor/github.com/mikioh/tcp/sys_linux_mips64.go b/vendor/github.com/mikioh/tcp/sys_linux_mips64.go
new file mode 100644
index 000000000000..2b871d2d5d86
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_linux_mips64.go
@@ -0,0 +1,10 @@
+// Copyright 2017 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+const (
+ sysSIOCINQ = 0x467f
+ sysSIOCOUTQ = 0x7472
+)
diff --git a/vendor/github.com/mikioh/tcp/sys_linux_mips64le.go b/vendor/github.com/mikioh/tcp/sys_linux_mips64le.go
new file mode 100644
index 000000000000..2b871d2d5d86
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_linux_mips64le.go
@@ -0,0 +1,10 @@
+// Copyright 2017 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+const (
+ sysSIOCINQ = 0x467f
+ sysSIOCOUTQ = 0x7472
+)
diff --git a/vendor/github.com/mikioh/tcp/sys_linux_mipsle.go b/vendor/github.com/mikioh/tcp/sys_linux_mipsle.go
new file mode 100644
index 000000000000..2b871d2d5d86
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_linux_mipsle.go
@@ -0,0 +1,10 @@
+// Copyright 2017 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+const (
+ sysSIOCINQ = 0x467f
+ sysSIOCOUTQ = 0x7472
+)
diff --git a/vendor/github.com/mikioh/tcp/sys_linux_ppc64.go b/vendor/github.com/mikioh/tcp/sys_linux_ppc64.go
new file mode 100644
index 000000000000..2d82b135e185
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_linux_ppc64.go
@@ -0,0 +1,10 @@
+// Copyright 2017 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+const (
+ sysSIOCINQ = 0x4004667f
+ sysSIOCOUTQ = 0x40047473
+)
diff --git a/vendor/github.com/mikioh/tcp/sys_linux_ppc64le.go b/vendor/github.com/mikioh/tcp/sys_linux_ppc64le.go
new file mode 100644
index 000000000000..2d82b135e185
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_linux_ppc64le.go
@@ -0,0 +1,10 @@
+// Copyright 2017 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+const (
+ sysSIOCINQ = 0x4004667f
+ sysSIOCOUTQ = 0x40047473
+)
diff --git a/vendor/github.com/mikioh/tcp/sys_linux_s390x.go b/vendor/github.com/mikioh/tcp/sys_linux_s390x.go
new file mode 100644
index 000000000000..d52bf7d80bb8
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_linux_s390x.go
@@ -0,0 +1,44 @@
+// Copyright 2017 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+const (
+ sysSIOCINQ = 0x541b
+ sysSIOCOUTQ = 0x5411
+)
+
+func ioctl(s uintptr, ioc int, b []byte) error {
+ if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, s, uintptr(ioc), uintptr(unsafe.Pointer(&b[0]))); errno != 0 {
+ return error(errno)
+ }
+ return nil
+}
+
+const (
+ sysSETSOCKOPT = 0xe
+ sysGETSOCKOPT = 0xf
+)
+
+func socketcall(call, a0, a1, a2, a3, a4, a5 uintptr) (uintptr, syscall.Errno)
+
+func setsockopt(s uintptr, level, name int, b []byte) error {
+ if _, errno := socketcall(sysSETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0); errno != 0 {
+ return error(errno)
+ }
+ return nil
+}
+
+func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
+ l := uint32(len(b))
+ if _, errno := socketcall(sysGETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&l)), 0); errno != 0 {
+ return int(l), error(errno)
+ }
+ return int(l), nil
+}
diff --git a/vendor/github.com/mikioh/tcp/sys_linux_s390x.s b/vendor/github.com/mikioh/tcp/sys_linux_s390x.s
new file mode 100644
index 000000000000..eecc9b109591
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_linux_s390x.s
@@ -0,0 +1,8 @@
+// Copyright 2017 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·socketcall(SB),NOSPLIT,$0-72
+ JMP syscall·socketcall(SB)
diff --git a/vendor/github.com/mikioh/tcp/sys_netbsd.go b/vendor/github.com/mikioh/tcp/sys_netbsd.go
new file mode 100644
index 000000000000..63cc3d3ff68a
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_netbsd.go
@@ -0,0 +1,10 @@
+// Copyright 2014 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+var options = [soMax]option{
+ soBuffered: {0, sysFIONREAD},
+ soAvailable: {0, sysFIONSPACE},
+}
diff --git a/vendor/github.com/mikioh/tcp/sys_openbsd.go b/vendor/github.com/mikioh/tcp/sys_openbsd.go
new file mode 100644
index 000000000000..c00a7a60a216
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_openbsd.go
@@ -0,0 +1,23 @@
+// Copyright 2014 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+import (
+ "encoding/binary"
+ "unsafe"
+)
+
+var options = [soMax]option{
+ soBuffered: {0, sysFIONREAD},
+}
+
+func (nl *pfiocNatlook) rdPort() int {
+ return int(binary.BigEndian.Uint16((*[2]byte)(unsafe.Pointer(&nl.Rdport))[:]))
+}
+
+func (nl *pfiocNatlook) setPort(remote, local int) {
+ binary.BigEndian.PutUint16((*[2]byte)(unsafe.Pointer(&nl.Sport))[:], uint16(remote))
+ binary.BigEndian.PutUint16((*[2]byte)(unsafe.Pointer(&nl.Dport))[:], uint16(local))
+}
diff --git a/vendor/github.com/mikioh/tcp/sys_solaris.go b/vendor/github.com/mikioh/tcp/sys_solaris.go
new file mode 100644
index 000000000000..a904de086a0b
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_solaris.go
@@ -0,0 +1,49 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+var options [soMax]option
+
+func rtioctl(s uintptr, ioc uintptr, arg uintptr) syscall.Errno
+
+func ioctl(s uintptr, ioc int, b []byte) error {
+ if errno := rtioctl(s, uintptr(ioc), uintptr(unsafe.Pointer(&b[0]))); errno != 0 {
+ return error(errno)
+ }
+ return nil
+}
+
+//go:cgo_import_dynamic libcGetsockopt __xnet_getsockopt "libsocket.so"
+//go:cgo_import_dynamic libcSetsockopt setsockopt "libsocket.so"
+
+//go:linkname libcGetsockopt libcGetsockopt
+//go:linkname libcSetsockopt libcSetsockopt
+
+var (
+ libcGetsockopt uintptr
+ libcSetsockopt uintptr
+)
+
+func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (uintptr, uintptr, syscall.Errno)
+
+func setsockopt(s uintptr, level, name int, b []byte) error {
+ if _, _, errno := sysvicall6(uintptr(unsafe.Pointer(&libcSetsockopt)), 5, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0); errno != 0 {
+ return error(errno)
+ }
+ return nil
+}
+
+func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
+ l := uint32(len(b))
+ if _, _, errno := sysvicall6(uintptr(unsafe.Pointer(&libcGetsockopt)), 5, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&l)), 0); errno != 0 {
+ return int(l), error(errno)
+ }
+ return int(l), nil
+}
diff --git a/vendor/github.com/mikioh/tcp/sys_solaris_amd64.s b/vendor/github.com/mikioh/tcp/sys_solaris_amd64.s
new file mode 100644
index 000000000000..ffa0451e9e9a
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_solaris_amd64.s
@@ -0,0 +1,11 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·rtioctl(SB),NOSPLIT,$0
+ JMP runtime·syscall_ioctl(SB)
+
+TEXT ·sysvicall6(SB),NOSPLIT,$0-88
+ JMP syscall·sysvicall6(SB)
diff --git a/vendor/github.com/mikioh/tcp/sys_stub.go b/vendor/github.com/mikioh/tcp/sys_stub.go
new file mode 100644
index 000000000000..8a5c929f9843
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_stub.go
@@ -0,0 +1,23 @@
+// Copyright 2014 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+
+package tcp
+
+import "errors"
+
+var options [soMax]option
+
+func ioctl(s uintptr, ioc int, b []byte) error {
+ return errors.New("not implemented")
+}
+
+func setsockopt(s uintptr, level, name int, b []byte) error {
+ return errors.New("not implemented")
+}
+
+func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
+ return 0, errors.New("not implemented")
+}
diff --git a/vendor/github.com/mikioh/tcp/sys_unix.go b/vendor/github.com/mikioh/tcp/sys_unix.go
new file mode 100644
index 000000000000..dcd80d87893b
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_unix.go
@@ -0,0 +1,34 @@
+// Copyright 2014 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux,!s390x,!386 netbsd openbsd
+
+package tcp
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+func ioctl(s uintptr, ioc int, b []byte) error {
+ if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, s, uintptr(ioc), uintptr(unsafe.Pointer(&b[0]))); errno != 0 {
+ return error(errno)
+ }
+ return nil
+}
+
+func setsockopt(s uintptr, level, name int, b []byte) error {
+ if _, _, errno := syscall.Syscall6(syscall.SYS_SETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), 0); errno != 0 {
+ return error(errno)
+ }
+ return nil
+}
+
+func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
+ l := uint32(len(b))
+ if _, _, errno := syscall.Syscall6(syscall.SYS_GETSOCKOPT, s, uintptr(level), uintptr(name), uintptr(unsafe.Pointer(&b[0])), uintptr(unsafe.Pointer(&l)), 0); errno != 0 {
+ return int(l), error(errno)
+ }
+ return int(l), nil
+}
diff --git a/vendor/github.com/mikioh/tcp/sys_windows.go b/vendor/github.com/mikioh/tcp/sys_windows.go
new file mode 100644
index 000000000000..45a9d895d1ad
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/sys_windows.go
@@ -0,0 +1,73 @@
+// Copyright 2014 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcp
+
+import (
+ "errors"
+ "os"
+ "sync"
+ "syscall"
+ "time"
+ "unsafe"
+
+ "github.com/mikioh/tcpopt"
+)
+
+var options [soMax]option
+
+func ioctl(s uintptr, ioc int, b []byte) error {
+ return errors.New("not implemented")
+}
+
+var keepAlive = struct {
+ sync.RWMutex
+ syscall.TCPKeepalive
+}{
+ TCPKeepalive: syscall.TCPKeepalive{
+ OnOff: 1,
+ Time: uint32(2 * time.Hour / time.Millisecond),
+ Interval: uint32(time.Second / time.Millisecond),
+ },
+}
+
+func setsockopt(s uintptr, level, name int, b []byte) error {
+ var kai tcpopt.KeepAliveIdleInterval
+ var kap tcpopt.KeepAliveProbeInterval
+ if level == kai.Level() && name == kai.Name() {
+ keepAlive.Lock()
+ defer keepAlive.Unlock()
+ prev := keepAlive.Time
+ keepAlive.Time = nativeEndian.Uint32(b)
+ rv := uint32(0)
+ siz := uint32(unsafe.Sizeof(keepAlive))
+ if err := syscall.WSAIoctl(syscall.Handle(s), syscall.SIO_KEEPALIVE_VALS, (*byte)(unsafe.Pointer(&keepAlive)), siz, nil, 0, &rv, nil, 0); err != nil {
+ keepAlive.Time = prev
+ return os.NewSyscallError("wsaioctl", err)
+ }
+ return nil
+ }
+ if level == kap.Level() && name == kap.Name() {
+ keepAlive.Lock()
+ defer keepAlive.Unlock()
+ prev := keepAlive.Interval
+ keepAlive.Interval = nativeEndian.Uint32(b)
+ rv := uint32(0)
+ siz := uint32(unsafe.Sizeof(keepAlive))
+ if err := syscall.WSAIoctl(syscall.Handle(s), syscall.SIO_KEEPALIVE_VALS, (*byte)(unsafe.Pointer(&keepAlive)), siz, nil, 0, &rv, nil, 0); err != nil {
+ keepAlive.Interval = prev
+ return os.NewSyscallError("wsaioctl", err)
+ }
+ return nil
+ }
+ if len(b) == 4 {
+ v := int(nativeEndian.Uint32(b))
+ return syscall.SetsockoptInt(syscall.Handle(s), level, name, v)
+ }
+ return errors.New("not implemented")
+}
+
+func getsockopt(s uintptr, level, name int, b []byte) (int, error) {
+ return 0, errors.New("not implemented")
+}
diff --git a/vendor/github.com/mikioh/tcp/zsys_darwin.go b/vendor/github.com/mikioh/tcp/zsys_darwin.go
new file mode 100644
index 000000000000..31e2e18c1c6a
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/zsys_darwin.go
@@ -0,0 +1,77 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_darwin.go
+
+package tcp
+
+const (
+ sysSOL_SOCKET = 0xffff
+
+ sysFIONREAD = 0x4004667f
+
+ sysSO_NREAD = 0x1020
+ sysSO_NWRITE = 0x1024
+ sysSO_NUMRCVPKT = 0x1112
+
+ sysAF_INET = 0x2
+ sysAF_INET6 = 0x1e
+
+ sysPF_INOUT = 0
+ sysPF_IN = 1
+ sysPF_OUT = 2
+
+ sysDIOCNATLOOK = 0xc0544417
+)
+
+type sockaddrStorage struct {
+ Len uint8
+ Family uint8
+ X__ss_pad1 [6]int8
+ X__ss_align int64
+ X__ss_pad2 [112]int8
+}
+
+type sockaddr struct {
+ Len uint8
+ Family uint8
+ Data [14]int8
+}
+
+type sockaddrInet struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Addr [4]byte /* in_addr */
+ Zero [8]int8
+}
+
+type sockaddrInet6 struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type pfiocNatlook struct {
+ Saddr [16]byte /* pf_addr */
+ Daddr [16]byte /* pf_addr */
+ Rsaddr [16]byte /* pf_addr */
+ Rdaddr [16]byte /* pf_addr */
+ Sxport [4]byte
+ Dxport [4]byte
+ Rsxport [4]byte
+ Rdxport [4]byte
+ Af uint8
+ Proto uint8
+ Variant uint8
+ Direction uint8
+}
+
+const (
+ sizeofSockaddrStorage = 0x80
+ sizeofSockaddr = 0x10
+ sizeofSockaddrInet = 0x10
+ sizeofSockaddrInet6 = 0x1c
+ sizeofPfiocNatlook = 0x54
+)
diff --git a/vendor/github.com/mikioh/tcp/zsys_dragonfly.go b/vendor/github.com/mikioh/tcp/zsys_dragonfly.go
new file mode 100644
index 000000000000..67037f555e07
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/zsys_dragonfly.go
@@ -0,0 +1,71 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_dragonfly.go
+
+package tcp
+
+const (
+ sysFIONREAD = 0x4004667f
+
+ sysAF_INET = 0x2
+ sysAF_INET6 = 0x1c
+
+ sysPF_INOUT = 0x0
+ sysPF_IN = 0x1
+ sysPF_OUT = 0x2
+
+ sysDIOCNATLOOK = 0xc04c4417
+)
+
+type sockaddrStorage struct {
+ Len uint8
+ Family uint8
+ X__ss_pad1 [6]int8
+ X__ss_align int64
+ X__ss_pad2 [112]int8
+}
+
+type sockaddr struct {
+ Len uint8
+ Family uint8
+ Data [14]int8
+}
+
+type sockaddrInet struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Addr [4]byte /* in_addr */
+ Zero [8]int8
+}
+
+type sockaddrInet6 struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type pfiocNatlook struct {
+ Saddr [16]byte /* pf_addr */
+ Daddr [16]byte /* pf_addr */
+ Rsaddr [16]byte /* pf_addr */
+ Rdaddr [16]byte /* pf_addr */
+ Sport uint16
+ Dport uint16
+ Rsport uint16
+ Rdport uint16
+ Af uint8
+ Proto uint8
+ Direction uint8
+ Pad_cgo_0 [1]byte
+}
+
+const (
+ sizeofSockaddrStorage = 0x80
+ sizeofSockaddr = 0x10
+ sizeofSockaddrInet = 0x10
+ sizeofSockaddrInet6 = 0x1c
+ sizeofPfiocNatlook = 0x4c
+)
diff --git a/vendor/github.com/mikioh/tcp/zsys_freebsd.go b/vendor/github.com/mikioh/tcp/zsys_freebsd.go
new file mode 100644
index 000000000000..ee46b9f26626
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/zsys_freebsd.go
@@ -0,0 +1,74 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_freebsd.go
+
+package tcp
+
+const (
+ sysFIONREAD = 0x4004667f
+ sysFIONWRITE = 0x40046677
+ sysFIONSPACE = 0x40046676
+
+ sysAF_INET = 0x2
+ sysAF_INET6 = 0x1c
+
+ sysPF_INOUT = 0x0
+ sysPF_IN = 0x1
+ sysPF_OUT = 0x2
+ sysPF_FWD = 0x3
+
+ sysDIOCNATLOOK = 0xc04c4417
+)
+
+type sockaddrStorage struct {
+ Len uint8
+ Family uint8
+ X__ss_pad1 [6]int8
+ X__ss_align int64
+ X__ss_pad2 [112]int8
+}
+
+type sockaddr struct {
+ Len uint8
+ Family uint8
+ Data [14]int8
+}
+
+type sockaddrInet struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Addr [4]byte /* in_addr */
+ Zero [8]int8
+}
+
+type sockaddrInet6 struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type pfiocNatlook struct {
+ Saddr [16]byte /* pf_addr */
+ Daddr [16]byte /* pf_addr */
+ Rsaddr [16]byte /* pf_addr */
+ Rdaddr [16]byte /* pf_addr */
+ Sport uint16
+ Dport uint16
+ Rsport uint16
+ Rdport uint16
+ Af uint8
+ Proto uint8
+ Direction uint8
+ Pad_cgo_0 [1]byte
+}
+
+const (
+ sizeofSockaddrStorage = 0x80
+ sizeofSockaddr = 0x10
+ sizeofSockaddrInet = 0x10
+ sizeofSockaddrInet6 = 0x1c
+ sizeofPfiocNatlook = 0x4c
+)
diff --git a/vendor/github.com/mikioh/tcp/zsys_linux.go b/vendor/github.com/mikioh/tcp/zsys_linux.go
new file mode 100644
index 000000000000..d3e65aed7d6f
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/zsys_linux.go
@@ -0,0 +1,42 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_linux.go
+
+package tcp
+
+const (
+ sysSO_ORIGINAL_DST = 0x50
+ sysIP6T_SO_ORIGINAL_DST = 0x50
+)
+
+type sockaddrStorage struct {
+ Family uint16
+ X__ss_padding [118]int8
+ X__ss_align uint64
+}
+
+type sockaddr struct {
+ Family uint16
+ Data [14]int8
+}
+
+type sockaddrInet struct {
+ Family uint16
+ Port uint16
+ Addr [4]byte /* in_addr */
+ X__pad [8]uint8
+}
+
+type sockaddrInet6 struct {
+ Family uint16
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+const (
+ sizeofSockaddrStorage = 0x80
+ sizeofSockaddr = 0x10
+ sizeofSockaddrInet = 0x10
+ sizeofSockaddrInet6 = 0x1c
+)
diff --git a/vendor/github.com/mikioh/tcp/zsys_netbsd.go b/vendor/github.com/mikioh/tcp/zsys_netbsd.go
new file mode 100644
index 000000000000..2bc05dacc46d
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/zsys_netbsd.go
@@ -0,0 +1,10 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_netbsd.go
+
+package tcp
+
+const (
+ sysFIONREAD = 0x4004667f
+ sysFIONWRITE = 0x40046679
+ sysFIONSPACE = 0x40046678
+)
diff --git a/vendor/github.com/mikioh/tcp/zsys_openbsd.go b/vendor/github.com/mikioh/tcp/zsys_openbsd.go
new file mode 100644
index 000000000000..34b85852227b
--- /dev/null
+++ b/vendor/github.com/mikioh/tcp/zsys_openbsd.go
@@ -0,0 +1,74 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_openbsd.go
+
+package tcp
+
+const (
+ sysFIONREAD = 0x4004667f
+
+ sysAF_INET = 0x2
+ sysAF_INET6 = 0x18
+
+ sysPF_INOUT = 0x0
+ sysPF_IN = 0x1
+ sysPF_OUT = 0x2
+ sysPF_FWD = 0x3
+
+ sysDIOCNATLOOK = 0xc0504417
+)
+
+type sockaddrStorage struct {
+ Len uint8
+ Family uint8
+ X__ss_pad1 [6]uint8
+ X__ss_pad2 uint64
+ X__ss_pad3 [240]uint8
+}
+
+type sockaddr struct {
+ Len uint8
+ Family uint8
+ Data [14]int8
+}
+
+type sockaddrInet struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Addr [4]byte /* in_addr */
+ Zero [8]int8
+}
+
+type sockaddrInet6 struct {
+ Len uint8
+ Family uint8
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type pfiocNatlook struct {
+ Saddr [16]byte /* pf_addr */
+ Daddr [16]byte /* pf_addr */
+ Rsaddr [16]byte /* pf_addr */
+ Rdaddr [16]byte /* pf_addr */
+ Rdomain uint16
+ Rrdomain uint16
+ Sport uint16
+ Dport uint16
+ Rsport uint16
+ Rdport uint16
+ Af uint8
+ Proto uint8
+ Direction uint8
+ Pad_cgo_0 [1]byte
+}
+
+const (
+ sizeofSockaddrStorage = 0x100
+ sizeofSockaddr = 0x10
+ sizeofSockaddrInet = 0x10
+ sizeofSockaddrInet6 = 0x1c
+ sizeofPfiocNatlook = 0x50
+)
diff --git a/vendor/github.com/mikioh/tcpinfo/LICENSE b/vendor/github.com/mikioh/tcpinfo/LICENSE
new file mode 100644
index 000000000000..5a4edfbebc0a
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpinfo/LICENSE
@@ -0,0 +1,23 @@
+Copyright (c) 2016, Mikio Hara
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/mikioh/tcpinfo/README.md b/vendor/github.com/mikioh/tcpinfo/README.md
new file mode 100644
index 000000000000..1fa4b44cf299
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpinfo/README.md
@@ -0,0 +1,6 @@
+Package tcpinfo implements encoding and decoding of TCP-level socket options regarding connection information.
+
+[![GoDoc](https://godoc.org/github.com/mikioh/tcpinfo?status.png)](https://godoc.org/github.com/mikioh/tcpinfo)
+[![Build Status](https://travis-ci.org/mikioh/tcpinfo.svg?branch=master)](https://travis-ci.org/mikioh/tcpinfo)
+[![Build status](https://ci.appveyor.com/api/projects/status/7x72aqqg95d3qe57?svg=true)](https://ci.appveyor.com/project/mikioh/tcpinfo)
+[![Go Report Card](https://goreportcard.com/badge/github.com/mikioh/tcpinfo)](https://goreportcard.com/report/github.com/mikioh/tcpinfo)
diff --git a/vendor/github.com/mikioh/tcpinfo/appveyor.yml b/vendor/github.com/mikioh/tcpinfo/appveyor.yml
new file mode 100644
index 000000000000..9ad48270344e
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpinfo/appveyor.yml
@@ -0,0 +1,18 @@
+version: "{build}"
+
+branches:
+ only:
+ - master
+
+environment:
+ GOPATH: c:\gopath
+
+install:
+ - set PATH=%GOPATH%\bin;c:\go\bin;%PATH%
+ - mkdir c:\gopath
+ - go get github.com/mikioh/tcp
+ - go get github.com/mikioh/tcpopt
+ - go get github.com/mikioh/tcpinfo
+
+build_script:
+ - go test -v -race
diff --git a/vendor/github.com/mikioh/tcpinfo/doc.go b/vendor/github.com/mikioh/tcpinfo/doc.go
new file mode 100644
index 000000000000..bfdd4a23b54d
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpinfo/doc.go
@@ -0,0 +1,20 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package tcpinfo implements encoding and decoding of TCP-level
+// socket options regarding connection information.
+//
+// The Transmission Control Protocol (TCP) is defined in RFC 793.
+// TCP Selective Acknowledgment Options is defined in RFC 2018.
+// Management Information Base for the Transmission Control Protocol
+// (TCP) is defined in RFC 4022.
+// TCP Congestion Control is defined in RFC 5681.
+// Computing TCP's Retransmission Timer is described in RFC 6298.
+// TCP Options and Maximum Segment Size (MSS) is defined in RFC 6691.
+// Shared Use of Experimental TCP Options is defined in RFC 6994.
+// TCP Extensions for High Performance is defined in RFC 7323.
+//
+// NOTE: Older Linux kernels may not support extended TCP statistics
+// described in RFC 4898.
+package tcpinfo
diff --git a/vendor/github.com/mikioh/tcpinfo/option.go b/vendor/github.com/mikioh/tcpinfo/option.go
new file mode 100644
index 000000000000..bb6e015c41d9
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpinfo/option.go
@@ -0,0 +1,157 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcpinfo
+
+import (
+ "encoding/json"
+ "time"
+
+ "github.com/mikioh/tcpopt"
+)
+
+var (
+ _ json.Marshaler = &Info{}
+ _ tcpopt.Option = &Info{}
+)
+
+// An Info represents connection information.
+//
+// Only supported on Darwin, FreeBSD, Linux and NetBSD.
+type Info struct {
+ State State `json:"state"` // connection state
+ Options []Option `json:"opts,omitempty"` // requesting options
+ PeerOptions []Option `json:"peer_opts,omitempty"` // options requested from peer
+ SenderMSS MaxSegSize `json:"snd_mss"` // maximum segment size for sender in bytes
+ ReceiverMSS MaxSegSize `json:"rcv_mss"` // maximum segment size for receiver in bytes
+ RTT time.Duration `json:"rtt"` // round-trip time
+ RTTVar time.Duration `json:"rttvar"` // round-trip time variation
+ RTO time.Duration `json:"rto"` // retransmission timeout
+ ATO time.Duration `json:"ato"` // delayed acknowledgement timeout [Linux only]
+ LastDataSent time.Duration `json:"last_data_sent"` // since last data sent [Linux only]
+ LastDataReceived time.Duration `json:"last_data_rcvd"` // since last data received [FreeBSD and Linux]
+ LastAckReceived time.Duration `json:"last_ack_rcvd"` // since last ack received [Linux only]
+ FlowControl *FlowControl `json:"flow_ctl,omitempty"` // flow control information
+ CongestionControl *CongestionControl `json:"cong_ctl,omitempty"` // congestion control information
+ Sys *SysInfo `json:"sys,omitempty"` // platform-specific information
+}
+
+// A FlowControl represents flow control information.
+type FlowControl struct {
+ ReceiverWindow uint `json:"rcv_wnd"` // advertised receiver window in bytes
+}
+
+// A CongestionControl represents congestion control information.
+type CongestionControl struct {
+ SenderSSThreshold uint `json:"snd_ssthresh"` // slow start threshold for sender in bytes or # of segments
+ ReceiverSSThreshold uint `json:"rcv_ssthresh"` // slow start threshold for receiver in bytes [Linux only]
+ SenderWindowBytes uint `json:"snd_cwnd_bytes"` // congestion window for sender in bytes [Darwin and FreeBSD]
+ SenderWindowSegs uint `json:"snd_cwnd_segs"` // congestion window for sender in # of segments [Linux and NetBSD]
+}
+
+// Level implements the Level method of tcpopt.Option interface.
+func (i *Info) Level() int { return options[soInfo].level }
+
+// Name implements the Name method of tcpopt.Option interface.
+func (i *Info) Name() int { return options[soInfo].name }
+
+// MarshalJSON implements the MarshalJSON method of json.Marshaler
+// interface.
+func (i *Info) MarshalJSON() ([]byte, error) {
+ raw := make(map[string]interface{})
+ raw["state"] = i.State.String()
+ if len(i.Options) > 0 {
+ opts := make(map[string]interface{})
+ for _, opt := range i.Options {
+ opts[opt.Kind().String()] = opt
+ }
+ raw["opts"] = opts
+ }
+ if len(i.PeerOptions) > 0 {
+ opts := make(map[string]interface{})
+ for _, opt := range i.PeerOptions {
+ opts[opt.Kind().String()] = opt
+ }
+ raw["peer_opts"] = opts
+ }
+ raw["snd_mss"] = i.SenderMSS
+ raw["rcv_mss"] = i.ReceiverMSS
+ raw["rtt"] = i.RTT
+ raw["rttvar"] = i.RTTVar
+ raw["rto"] = i.RTO
+ raw["ato"] = i.ATO
+ raw["last_data_sent"] = i.LastDataSent
+ raw["last_data_rcvd"] = i.LastDataReceived
+ raw["last_ack_rcvd"] = i.LastAckReceived
+ if i.FlowControl != nil {
+ raw["flow_ctl"] = i.FlowControl
+ }
+ if i.CongestionControl != nil {
+ raw["cong_ctl"] = i.CongestionControl
+ }
+ if i.Sys != nil {
+ raw["sys"] = i.Sys
+ }
+ return json.Marshal(&raw)
+}
+
+// A CCInfo represents raw information of congestion control
+// algorithm.
+//
+// Only supported on Linux.
+type CCInfo struct {
+ Raw []byte `json:"raw,omitempty"`
+}
+
+// Level implements the Level method of tcpopt.Option interface.
+func (cci *CCInfo) Level() int { return options[soCCInfo].level }
+
+// Name implements the Name method of tcpopt.Option interface.
+func (cci *CCInfo) Name() int { return options[soCCInfo].name }
+
+// Marshal implements the Marshal method of tcpopt.Option interface.
+func (cci *CCInfo) Marshal() ([]byte, error) { return cci.Raw, nil }
+
+func parseCCInfo(b []byte) (tcpopt.Option, error) { return &CCInfo{Raw: b}, nil }
+
+// A CCAlgorithm represents a name of congestion control algorithm.
+//
+// Only supported on Linux.
+type CCAlgorithm string
+
+// Level implements the Level method of tcpopt.Option interface.
+func (cca CCAlgorithm) Level() int { return options[soCCAlgo].level }
+
+// Name implements the Name method of tcpopt.Option interface.
+func (cca CCAlgorithm) Name() int { return options[soCCAlgo].name }
+
+// Marshal implements the Marshal method of tcpopt.Option interface.
+func (cca CCAlgorithm) Marshal() ([]byte, error) {
+ if cca == "" {
+ return nil, nil
+ }
+ return []byte(cca), nil
+}
+
+func parseCCAlgorithm(b []byte) (tcpopt.Option, error) { return CCAlgorithm(b), nil }
+
+// A CCAlgorithmInfo represents congestion control algorithm
+// information.
+//
+// Only supported on Linux.
+type CCAlgorithmInfo interface {
+ Algorithm() string
+}
+
+// ParseCCAlgorithmInfo parses congestion control algorithm
+// information.
+//
+// Only supported on Linux.
+func ParseCCAlgorithmInfo(name string, b []byte) (CCAlgorithmInfo, error) {
+ ccai, err := parseCCAlgorithmInfo(name, b)
+ if err != nil {
+ return nil, err
+ }
+ return ccai, nil
+}
diff --git a/vendor/github.com/mikioh/tcpinfo/sys.go b/vendor/github.com/mikioh/tcpinfo/sys.go
new file mode 100644
index 000000000000..482eec24f65d
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpinfo/sys.go
@@ -0,0 +1,34 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcpinfo
+
+import "github.com/mikioh/tcpopt"
+
+func init() {
+ for _, o := range options {
+ if o.name == 0 || o.parseFn == nil {
+ continue
+ }
+ tcpopt.Register(o.level, o.name, o.parseFn)
+ }
+}
+
+const (
+ ianaProtocolTCP = 0x6
+)
+
+const (
+ soInfo = iota
+ soCCInfo
+ soCCAlgo
+ soMax
+)
+
+// An option represents a binding for socket option.
+type option struct {
+ level int // option level
+ name int // option name, must be equal or greater than 1
+ parseFn func([]byte) (tcpopt.Option, error)
+}
diff --git a/vendor/github.com/mikioh/tcpinfo/sys_bsd.go b/vendor/github.com/mikioh/tcpinfo/sys_bsd.go
new file mode 100644
index 000000000000..c080f5869bc8
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpinfo/sys_bsd.go
@@ -0,0 +1,96 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build freebsd netbsd
+
+package tcpinfo
+
+import (
+ "errors"
+ "runtime"
+ "time"
+ "unsafe"
+
+ "github.com/mikioh/tcpopt"
+)
+
+var options = [soMax]option{
+ soInfo: {ianaProtocolTCP, sysTCP_INFO, parseInfo},
+}
+
+// Marshal implements the Marshal method of tcpopt.Option interface.
+func (i *Info) Marshal() ([]byte, error) { return (*[sizeofTCPInfo]byte)(unsafe.Pointer(i))[:], nil }
+
+// A SysInfo represents platform-specific information.
+type SysInfo struct {
+ SenderWindowBytes uint `json:"snd_wnd_bytes"` // advertised sender window in bytes [FreeBSD]
+ SenderWindowSegs uint `json:"snd_wnd_segs"` // advertised sender window in # of segments [NetBSD]
+ NextEgressSeq uint `json:"egress_seq"` // next egress seq. number
+ NextIngressSeq uint `json:"ingress_seq"` // next ingress seq. number
+ RetransSegs uint `json:"retrans_segs"` // # of retransmit segments sent
+ OutOfOrderSegs uint `json:"ooo_segs"` // # of out-of-order segments received
+ ZeroWindowUpdates uint `json:"zerownd_updates"` // # of zero-window updates sent
+ Offloading bool `json:"offloading"` // TCP offload processing
+}
+
+var sysStates = [11]State{Closed, Listen, SynSent, SynReceived, Established, CloseWait, FinWait1, Closing, LastAck, FinWait2, TimeWait}
+
+func parseInfo(b []byte) (tcpopt.Option, error) {
+ if len(b) < sizeofTCPInfo {
+ return nil, errors.New("short buffer")
+ }
+ ti := (*tcpInfo)(unsafe.Pointer(&b[0]))
+ i := &Info{State: sysStates[ti.State]}
+ if ti.Options&sysTCPI_OPT_WSCALE != 0 {
+ i.Options = append(i.Options, WindowScale(ti.Pad_cgo_0[0]>>4))
+ i.PeerOptions = append(i.PeerOptions, WindowScale(ti.Pad_cgo_0[0]&0x0f))
+ }
+ if ti.Options&sysTCPI_OPT_SACK != 0 {
+ i.Options = append(i.Options, SACKPermitted(true))
+ i.PeerOptions = append(i.PeerOptions, SACKPermitted(true))
+ }
+ if ti.Options&sysTCPI_OPT_TIMESTAMPS != 0 {
+ i.Options = append(i.Options, Timestamps(true))
+ i.PeerOptions = append(i.PeerOptions, Timestamps(true))
+ }
+ i.SenderMSS = MaxSegSize(ti.Snd_mss)
+ i.ReceiverMSS = MaxSegSize(ti.Rcv_mss)
+ i.RTT = time.Duration(ti.Rtt) * time.Microsecond
+ i.RTTVar = time.Duration(ti.Rttvar) * time.Microsecond
+ i.RTO = time.Duration(ti.Rto) * time.Microsecond
+ i.ATO = time.Duration(ti.X__tcpi_ato) * time.Microsecond
+ i.LastDataSent = time.Duration(ti.X__tcpi_last_data_sent) * time.Microsecond
+ i.LastDataReceived = time.Duration(ti.Last_data_recv) * time.Microsecond
+ i.LastAckReceived = time.Duration(ti.X__tcpi_last_ack_recv) * time.Microsecond
+ i.FlowControl = &FlowControl{
+ ReceiverWindow: uint(ti.Rcv_space),
+ }
+ i.CongestionControl = &CongestionControl{
+ SenderSSThreshold: uint(ti.Snd_ssthresh),
+ ReceiverSSThreshold: uint(ti.X__tcpi_rcv_ssthresh),
+ }
+ i.Sys = &SysInfo{
+ NextEgressSeq: uint(ti.Snd_nxt),
+ NextIngressSeq: uint(ti.Rcv_nxt),
+ RetransSegs: uint(ti.Snd_rexmitpack),
+ OutOfOrderSegs: uint(ti.Rcv_ooopack),
+ ZeroWindowUpdates: uint(ti.Snd_zerowin),
+ }
+ if ti.Options&sysTCPI_OPT_TOE != 0 {
+ i.Sys.Offloading = true
+ }
+ switch runtime.GOOS {
+ case "freebsd":
+ i.CongestionControl.SenderWindowBytes = uint(ti.Snd_cwnd)
+ i.Sys.SenderWindowBytes = uint(ti.Snd_wnd)
+ case "netbsd":
+ i.CongestionControl.SenderWindowSegs = uint(ti.Snd_cwnd)
+ i.Sys.SenderWindowSegs = uint(ti.Snd_wnd)
+ }
+ return i, nil
+}
+
+func parseCCAlgorithmInfo(name string, b []byte) (CCAlgorithmInfo, error) {
+ return nil, errors.New("operation not supported")
+}
diff --git a/vendor/github.com/mikioh/tcpinfo/sys_darwin.go b/vendor/github.com/mikioh/tcpinfo/sys_darwin.go
new file mode 100644
index 000000000000..6b1599dfb3a9
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpinfo/sys_darwin.go
@@ -0,0 +1,114 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcpinfo
+
+import (
+ "errors"
+ "time"
+ "unsafe"
+
+ "github.com/mikioh/tcpopt"
+)
+
+var options = [soMax]option{
+ soInfo: {ianaProtocolTCP, sysTCP_CONNECTION_INFO, parseInfo},
+}
+
+// Marshal implements the Marshal method of tcpopt.Option interface.
+func (i *Info) Marshal() ([]byte, error) {
+ return (*[sizeofTCPConnectionInfo]byte)(unsafe.Pointer(i))[:], nil
+}
+
+type SysFlags uint
+
+func (f SysFlags) String() string {
+ s := ""
+ for i, name := range []string{
+ "loss recovery",
+ "reordering detected",
+ } {
+ if f&(1< sizeofTCPConnectionInfoV15 {
+ i.Sys.RetransSegs = uint64(tci.Txretransmitpackets)
+ }
+ return i, nil
+}
+
+func parseCCAlgorithmInfo(name string, b []byte) (CCAlgorithmInfo, error) {
+ return nil, errors.New("operation not supported")
+}
diff --git a/vendor/github.com/mikioh/tcpinfo/sys_linux.go b/vendor/github.com/mikioh/tcpinfo/sys_linux.go
new file mode 100644
index 000000000000..77ab8ecdfcf9
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpinfo/sys_linux.go
@@ -0,0 +1,276 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcpinfo
+
+import (
+ "errors"
+ "strings"
+ "time"
+ "unsafe"
+
+ "github.com/mikioh/tcpopt"
+)
+
+var options = [soMax]option{
+ soInfo: {ianaProtocolTCP, sysTCP_INFO, parseInfo},
+ soCCInfo: {ianaProtocolTCP, sysTCP_CC_INFO, parseCCInfo},
+ soCCAlgo: {ianaProtocolTCP, sysTCP_CONGESTION, parseCCAlgorithm},
+}
+
+// Marshal implements the Marshal method of tcpopt.Option interface.
+func (i *Info) Marshal() ([]byte, error) { return (*[sizeofTCPInfo]byte)(unsafe.Pointer(i))[:], nil }
+
+// A CAState represents a state of congestion avoidance.
+type CAState int
+
+var caStates = map[CAState]string{
+ CAOpen: "open",
+ CADisorder: "disorder",
+ CACWR: "congestion window reduced",
+ CARecovery: "recovery",
+ CALoss: "loss",
+}
+
+func (st CAState) String() string {
+ s, ok := caStates[st]
+ if !ok {
+ return ""
+ }
+ return s
+}
+
+// A SysInfo represents platform-specific information.
+type SysInfo struct {
+ PathMTU uint `json:"path_mtu"` // path maximum transmission unit
+ AdvertisedMSS MaxSegSize `json:"adv_mss"` // advertised maximum segment size
+ CAState CAState `json:"ca_state"` // state of congestion avoidance
+ Retransmissions uint `json:"rexmits"` // # of retranmissions on timeout invoked
+ Backoffs uint `json:"backoffs"` // # of times retransmission backoff timer invoked
+ WindowOrKeepAliveProbes uint `json:"wnd_ka_probes"` // # of window or keep alive probes sent
+ UnackedSegs uint `json:"unacked_segs"` // # of unack'd segments
+ SackedSegs uint `json:"sacked_segs"` // # of sack'd segments
+ LostSegs uint `json:"lost_segs"` // # of lost segments
+ RetransSegs uint `json:"retrans_segs"` // # of retransmitting segments in transmission queue
+ ForwardAckSegs uint `json:"fack_segs"` // # of forward ack segments in transmission queue
+ ReorderedSegs uint `json:"reord_segs"` // # of reordered segments allowed
+ ReceiverRTT time.Duration `json:"rcv_rtt"` // current RTT for receiver
+ TotalRetransSegs uint `json:"total_retrans_segs"` // # of retransmitted segments
+ PacingRate uint64 `json:"pacing_rate"` // pacing rate
+ ThruBytesAcked uint64 `json:"thru_bytes_acked"` // # of bytes for which cumulative acknowledgments have been received
+ ThruBytesReceived uint64 `json:"thru_bytes_rcvd"` // # of bytes for which cumulative acknowledgments have been sent
+ SegsOut uint `json:"segs_out"` // # of segments sent
+ SegsIn uint `json:"segs_in"` // # of segments received
+ NotSentBytes uint `json:"not_sent_bytes"` // # of bytes not sent yet
+ MinRTT time.Duration `json:"min_rtt"` // current measured minimum RTT; zero means not available
+ DataSegsOut uint `json:"data_segs_out"` // # of segments sent containing a positive length data segment
+ DataSegsIn uint `json:"data_segs_in"` // # of segments received containing a positive length data segment
+}
+
+var sysStates = [12]State{Unknown, Established, SynSent, SynReceived, FinWait1, FinWait2, TimeWait, Closed, CloseWait, LastAck, Listen, Closing}
+
+const (
+ sizeofTCPInfoV4_9 = 0xa0
+ sizeofTCPInfoV3_19 = 0x78
+)
+
+func parseInfo(b []byte) (tcpopt.Option, error) {
+ if len(b) < sizeofTCPInfoV4_9 {
+ return parseInfo3_19(b)
+ }
+ ti := (*tcpInfo)(unsafe.Pointer(&b[0]))
+ i := &Info{State: sysStates[ti.State]}
+ if ti.Options&sysTCPI_OPT_WSCALE != 0 {
+ i.Options = append(i.Options, WindowScale(ti.Pad_cgo_0[0]>>4))
+ i.PeerOptions = append(i.PeerOptions, WindowScale(ti.Pad_cgo_0[0]&0x0f))
+ }
+ if ti.Options&sysTCPI_OPT_SACK != 0 {
+ i.Options = append(i.Options, SACKPermitted(true))
+ i.PeerOptions = append(i.PeerOptions, SACKPermitted(true))
+ }
+ if ti.Options&sysTCPI_OPT_TIMESTAMPS != 0 {
+ i.Options = append(i.Options, Timestamps(true))
+ i.PeerOptions = append(i.PeerOptions, Timestamps(true))
+ }
+ i.SenderMSS = MaxSegSize(ti.Snd_mss)
+ i.ReceiverMSS = MaxSegSize(ti.Rcv_mss)
+ i.RTT = time.Duration(ti.Rtt) * time.Microsecond
+ i.RTTVar = time.Duration(ti.Rttvar) * time.Microsecond
+ i.RTO = time.Duration(ti.Rto) * time.Microsecond
+ i.ATO = time.Duration(ti.Ato) * time.Microsecond
+ i.LastDataSent = time.Duration(ti.Last_data_sent) * time.Millisecond
+ i.LastDataReceived = time.Duration(ti.Last_data_recv) * time.Millisecond
+ i.LastAckReceived = time.Duration(ti.Last_ack_recv) * time.Millisecond
+ i.FlowControl = &FlowControl{
+ ReceiverWindow: uint(ti.Rcv_space),
+ }
+ i.CongestionControl = &CongestionControl{
+ SenderSSThreshold: uint(ti.Snd_ssthresh),
+ ReceiverSSThreshold: uint(ti.Rcv_ssthresh),
+ SenderWindowSegs: uint(ti.Snd_cwnd),
+ }
+ i.Sys = &SysInfo{
+ PathMTU: uint(ti.Pmtu),
+ AdvertisedMSS: MaxSegSize(ti.Advmss),
+ CAState: CAState(ti.Ca_state),
+ Retransmissions: uint(ti.Retransmits),
+ Backoffs: uint(ti.Backoff),
+ WindowOrKeepAliveProbes: uint(ti.Probes),
+ UnackedSegs: uint(ti.Unacked),
+ SackedSegs: uint(ti.Sacked),
+ LostSegs: uint(ti.Lost),
+ RetransSegs: uint(ti.Retrans),
+ ForwardAckSegs: uint(ti.Fackets),
+ ReorderedSegs: uint(ti.Reordering),
+ ReceiverRTT: time.Duration(ti.Rcv_rtt) * time.Microsecond,
+ TotalRetransSegs: uint(ti.Total_retrans),
+ PacingRate: uint64(ti.Pacing_rate),
+ ThruBytesAcked: uint64(ti.Bytes_acked),
+ ThruBytesReceived: uint64(ti.Bytes_received),
+ SegsIn: uint(ti.Segs_in),
+ SegsOut: uint(ti.Segs_out),
+ NotSentBytes: uint(ti.Notsent_bytes),
+ MinRTT: time.Duration(ti.Min_rtt) * time.Microsecond,
+ DataSegsIn: uint(ti.Data_segs_in),
+ DataSegsOut: uint(ti.Data_segs_out),
+ }
+ return i, nil
+}
+
+func parseInfo3_19(b []byte) (tcpopt.Option, error) {
+ if len(b) < sizeofTCPInfoV3_19 {
+ return nil, errors.New("short buffer")
+ }
+ ti := (*tcpInfo3_19)(unsafe.Pointer(&b[0]))
+ i := &Info{State: sysStates[ti.State]}
+ if ti.Options&sysTCPI_OPT_WSCALE != 0 {
+ i.Options = append(i.Options, WindowScale(ti.Pad_cgo_0[0]>>4))
+ i.PeerOptions = append(i.PeerOptions, WindowScale(ti.Pad_cgo_0[0]&0x0f))
+ }
+ if ti.Options&sysTCPI_OPT_SACK != 0 {
+ i.Options = append(i.Options, SACKPermitted(true))
+ i.PeerOptions = append(i.PeerOptions, SACKPermitted(true))
+ }
+ if ti.Options&sysTCPI_OPT_TIMESTAMPS != 0 {
+ i.Options = append(i.Options, Timestamps(true))
+ i.PeerOptions = append(i.PeerOptions, Timestamps(true))
+ }
+ i.SenderMSS = MaxSegSize(ti.Snd_mss)
+ i.ReceiverMSS = MaxSegSize(ti.Rcv_mss)
+ i.RTT = time.Duration(ti.Rtt) * time.Microsecond
+ i.RTTVar = time.Duration(ti.Rttvar) * time.Microsecond
+ i.RTO = time.Duration(ti.Rto) * time.Microsecond
+ i.ATO = time.Duration(ti.Ato) * time.Microsecond
+ i.LastDataSent = time.Duration(ti.Last_data_sent) * time.Millisecond
+ i.LastDataReceived = time.Duration(ti.Last_data_recv) * time.Millisecond
+ i.LastAckReceived = time.Duration(ti.Last_ack_recv) * time.Millisecond
+ i.FlowControl = &FlowControl{
+ ReceiverWindow: uint(ti.Rcv_space),
+ }
+ i.CongestionControl = &CongestionControl{
+ SenderSSThreshold: uint(ti.Snd_ssthresh),
+ ReceiverSSThreshold: uint(ti.Rcv_ssthresh),
+ SenderWindowSegs: uint(ti.Snd_cwnd),
+ }
+ i.Sys = &SysInfo{
+ PathMTU: uint(ti.Pmtu),
+ AdvertisedMSS: MaxSegSize(ti.Advmss),
+ CAState: CAState(ti.Ca_state),
+ Retransmissions: uint(ti.Retransmits),
+ Backoffs: uint(ti.Backoff),
+ WindowOrKeepAliveProbes: uint(ti.Probes),
+ UnackedSegs: uint(ti.Unacked),
+ SackedSegs: uint(ti.Sacked),
+ LostSegs: uint(ti.Lost),
+ RetransSegs: uint(ti.Retrans),
+ ForwardAckSegs: uint(ti.Fackets),
+ ReorderedSegs: uint(ti.Reordering),
+ ReceiverRTT: time.Duration(ti.Rcv_rtt) * time.Microsecond,
+ TotalRetransSegs: uint(ti.Total_retrans),
+ PacingRate: uint64(ti.Pacing_rate),
+ }
+ return i, nil
+}
+
+// A VegasInfo represents Vegas congestion control information.
+type VegasInfo struct {
+ Enabled bool `json:"enabled"`
+ RoundTrips uint `json:"rnd_trips"` // # of round-trips
+ RTT time.Duration `json:"rtt"` // round-trip time
+ MinRTT time.Duration `json:"min_rtt"` // minimum round-trip time
+}
+
+// Algorithm implements the Algorithm method of CCAlgorithmInfo
+// interface.
+func (vi *VegasInfo) Algorithm() string { return "vegas" }
+
+// A CEState represents a state of ECN congestion encountered (CE)
+// codepoint.
+type CEState int
+
+// A DCTCPInfo represents Datacenter TCP congestion control
+// information.
+type DCTCPInfo struct {
+ Enabled bool `json:"enabled"`
+ CEState CEState `json:"ce_state"` // state of ECN CE codepoint
+ Alpha uint `json:"alpha"` // fraction of bytes sent
+ ECNAckedBytes uint `json:"ecn_acked"` // # of acked bytes with ECN
+ TotalAckedBytes uint `json:"total_acked"` // total # of acked bytes
+}
+
+// Algorithm implements the Algorithm method of CCAlgorithmInfo
+// interface.
+func (di *DCTCPInfo) Algorithm() string { return "dctcp" }
+
+// A BBRInfo represents Bottleneck Bandwidth and Round-trip
+// propagation time-based congestion control information.
+type BBRInfo struct {
+ MaxBW uint64 `json:"max_bw"` // maximum-filtered bandwidth in bps
+ MinRTT time.Duration `json:"min_rtt"` // minimum-filtered round-trip time
+ PacingGain uint `json:"pacing_gain"` // pacing gain shifted left 8 bits
+ CongWindowGain uint `json:"cwnd_gain"` // congestion window gain shifted left 8 bits
+}
+
+// Algorithm implements the Algorithm method of CCAlgorithmInfo
+// interface.
+func (bi *BBRInfo) Algorithm() string { return "bbr" }
+
+func parseCCAlgorithmInfo(name string, b []byte) (CCAlgorithmInfo, error) {
+ if strings.HasPrefix(name, "dctcp") {
+ if len(b) < sizeofTCPDCTCPInfo {
+ return nil, errors.New("short buffer")
+ }
+ sdi := (*tcpDCTCPInfo)(unsafe.Pointer(&b[0]))
+ di := &DCTCPInfo{Alpha: uint(sdi.Alpha)}
+ if sdi.Enabled != 0 {
+ di.Enabled = true
+ }
+ return di, nil
+ }
+ if strings.HasPrefix(name, "bbr") {
+ if len(b) < sizeofTCPBBRInfo {
+ return nil, errors.New("short buffer")
+ }
+ sbi := (*tcpBBRInfo)(unsafe.Pointer(&b[0]))
+ return &BBRInfo{
+ MaxBW: uint64(sbi.Bw_hi)<<32 | uint64(sbi.Bw_lo),
+ MinRTT: time.Duration(sbi.Min_rtt) * time.Microsecond,
+ PacingGain: uint(sbi.Pacing_gain),
+ CongWindowGain: uint(sbi.Cwnd_gain),
+ }, nil
+ }
+ if len(b) < sizeofTCPVegasInfo {
+ return nil, errors.New("short buffer")
+ }
+ svi := (*tcpVegasInfo)(unsafe.Pointer(&b[0]))
+ vi := &VegasInfo{
+ RoundTrips: uint(svi.Rttcnt),
+ RTT: time.Duration(svi.Rtt) * time.Microsecond,
+ MinRTT: time.Duration(svi.Minrtt) * time.Microsecond,
+ }
+ if svi.Enabled != 0 {
+ vi.Enabled = true
+ }
+ return vi, nil
+}
diff --git a/vendor/github.com/mikioh/tcpinfo/sys_stub.go b/vendor/github.com/mikioh/tcpinfo/sys_stub.go
new file mode 100644
index 000000000000..82f1462354f8
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpinfo/sys_stub.go
@@ -0,0 +1,31 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !darwin,!freebsd,!linux,!netbsd
+
+package tcpinfo
+
+import (
+ "errors"
+
+ "github.com/mikioh/tcpopt"
+)
+
+var options [soMax]option
+
+// Marshal implements the Marshal method of tcpopt.Option interface.
+func (i *Info) Marshal() ([]byte, error) {
+ return nil, errors.New("operation not supported")
+}
+
+// A SysInfo represents platform-specific information.
+type SysInfo struct{}
+
+func parseInfo(b []byte) (tcpopt.Option, error) {
+ return nil, errors.New("operation not supported")
+}
+
+func parseCCAlgorithmInfo(name string, b []byte) (CCAlgorithmInfo, error) {
+ return nil, errors.New("operation not supported")
+}
diff --git a/vendor/github.com/mikioh/tcpinfo/tcp.go b/vendor/github.com/mikioh/tcpinfo/tcp.go
new file mode 100644
index 000000000000..149192454ac6
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpinfo/tcp.go
@@ -0,0 +1,101 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcpinfo
+
+// A State represents a state of connection.
+type State int
+
+const (
+ Unknown State = iota
+ Closed
+ Listen
+ SynSent
+ SynReceived
+ Established
+ FinWait1
+ FinWait2
+ CloseWait
+ LastAck
+ Closing
+ TimeWait
+)
+
+var states = map[State]string{
+ Unknown: "unknown",
+ Closed: "closed",
+ Listen: "listen",
+ SynSent: "syn-sent",
+ SynReceived: "syn-received",
+ Established: "established",
+ FinWait1: "fin-wait-1",
+ FinWait2: "fin-wait-2",
+ CloseWait: "close-wait",
+ LastAck: "last-ack",
+ Closing: "closing",
+ TimeWait: "time-wait",
+}
+
+func (st State) String() string {
+ s, ok := states[st]
+ if !ok {
+ return ""
+ }
+ return s
+}
+
+// An OptionKind represents an option kind.
+type OptionKind int
+
+const (
+ KindMaxSegSize OptionKind = 2
+ KindWindowScale OptionKind = 3
+ KindSACKPermitted OptionKind = 4
+ KindTimestamps OptionKind = 8
+)
+
+var optionKinds = map[OptionKind]string{
+ KindMaxSegSize: "mss",
+ KindWindowScale: "wscale",
+ KindSACKPermitted: "sack",
+ KindTimestamps: "tmstamps",
+}
+
+func (k OptionKind) String() string {
+ s, ok := optionKinds[k]
+ if !ok {
+ return ""
+ }
+ return s
+}
+
+// An Option represents an option.
+type Option interface {
+ Kind() OptionKind
+}
+
+// A MaxSegSize represents a maxiumum segment size option.
+type MaxSegSize uint
+
+// Kind returns an option kind field.
+func (mss MaxSegSize) Kind() OptionKind { return KindMaxSegSize }
+
+// A WindowScale represents a windows scale option.
+type WindowScale int
+
+// Kind returns an option kind field.
+func (ws WindowScale) Kind() OptionKind { return KindWindowScale }
+
+// A SACKPermitted reports whether a selective acknowledgment
+// permitted option is enabled.
+type SACKPermitted bool
+
+// Kind returns an option kind field.
+func (sp SACKPermitted) Kind() OptionKind { return KindSACKPermitted }
+
+// A Timestamps reports whether a timestamps option is enabled.
+type Timestamps bool
+
+// Kind returns an option kind field.
+func (ts Timestamps) Kind() OptionKind { return KindTimestamps }
diff --git a/vendor/github.com/mikioh/tcpinfo/zsys_3_19_linux.go b/vendor/github.com/mikioh/tcpinfo/zsys_3_19_linux.go
new file mode 100644
index 000000000000..4f142e48f75e
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpinfo/zsys_3_19_linux.go
@@ -0,0 +1,42 @@
+// Created by cgo -godefs - DO NOT EDIT
+// go tool cgo -godefs defs_linux.go
+// it was edited to remove duplicated code. Also removed last field (tcpi_last_new_data_recv)
+// because we do not use it and getsockopt does not fill it anyway
+
+package tcpinfo
+
+type tcpInfo3_19 struct {
+ State uint8
+ Ca_state uint8
+ Retransmits uint8
+ Probes uint8
+ Backoff uint8
+ Options uint8
+ Pad_cgo_0 [2]byte
+ Rto uint32
+ Ato uint32
+ Snd_mss uint32
+ Rcv_mss uint32
+ Unacked uint32
+ Sacked uint32
+ Lost uint32
+ Retrans uint32
+ Fackets uint32
+ Last_data_sent uint32
+ Last_ack_sent uint32
+ Last_data_recv uint32
+ Last_ack_recv uint32
+ Pmtu uint32
+ Rcv_ssthresh uint32
+ Rtt uint32
+ Rttvar uint32
+ Snd_ssthresh uint32
+ Snd_cwnd uint32
+ Advmss uint32
+ Reordering uint32
+ Rcv_rtt uint32
+ Rcv_space uint32
+ Total_retrans uint32
+ Pacing_rate uint64
+ Max_pacing_rate uint64
+}
diff --git a/vendor/github.com/mikioh/tcpinfo/zsys_darwin.go b/vendor/github.com/mikioh/tcpinfo/zsys_darwin.go
new file mode 100644
index 000000000000..cf94cc6a17e3
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpinfo/zsys_darwin.go
@@ -0,0 +1,45 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_darwin.go
+
+package tcpinfo
+
+const (
+ sysTCP_CONNECTION_INFO = 0x106
+
+ sysTCPCI_OPT_TIMESTAMPS = 0x1
+ sysTCPCI_OPT_SACK = 0x2
+ sysTCPCI_OPT_WSCALE = 0x4
+ sysTCPCI_OPT_ECN = 0x8
+
+ SysFlagLossRecovery SysFlags = 0x1
+ SysFlagReorderingDetected SysFlags = 0x2
+
+ sizeofTCPConnectionInfo = 0x70
+)
+
+type tcpConnectionInfo struct {
+ State uint8
+ Snd_wscale uint8
+ Rcv_wscale uint8
+ X__pad1 uint8
+ Options uint32
+ Flags uint32
+ Rto uint32
+ Maxseg uint32
+ Snd_ssthresh uint32
+ Snd_cwnd uint32
+ Snd_wnd uint32
+ Snd_sbbytes uint32
+ Rcv_wnd uint32
+ Rttcur uint32
+ Srtt uint32
+ Rttvar uint32
+ Pad_cgo_0 [4]byte
+ Txpackets uint64
+ Txbytes uint64
+ Txretransmitbytes uint64
+ Rxpackets uint64
+ Rxbytes uint64
+ Rxoutoforderbytes uint64
+ Txretransmitpackets uint64
+}
diff --git a/vendor/github.com/mikioh/tcpinfo/zsys_freebsd.go b/vendor/github.com/mikioh/tcpinfo/zsys_freebsd.go
new file mode 100644
index 000000000000..b92d53eeffd9
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpinfo/zsys_freebsd.go
@@ -0,0 +1,58 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_freebsd.go
+
+package tcpinfo
+
+const (
+ sysTCP_INFO = 0x20
+
+ sysTCPI_OPT_TIMESTAMPS = 0x1
+ sysTCPI_OPT_SACK = 0x2
+ sysTCPI_OPT_WSCALE = 0x4
+ sysTCPI_OPT_ECN = 0x8
+ sysTCPI_OPT_TOE = 0x10
+
+ sizeofTCPInfo = 0xec
+)
+
+type tcpInfo struct {
+ State uint8
+ X__tcpi_ca_state uint8
+ X__tcpi_retransmits uint8
+ X__tcpi_probes uint8
+ X__tcpi_backoff uint8
+ Options uint8
+ Pad_cgo_0 [2]byte
+ Rto uint32
+ X__tcpi_ato uint32
+ Snd_mss uint32
+ Rcv_mss uint32
+ X__tcpi_unacked uint32
+ X__tcpi_sacked uint32
+ X__tcpi_lost uint32
+ X__tcpi_retrans uint32
+ X__tcpi_fackets uint32
+ X__tcpi_last_data_sent uint32
+ X__tcpi_last_ack_sent uint32
+ Last_data_recv uint32
+ X__tcpi_last_ack_recv uint32
+ X__tcpi_pmtu uint32
+ X__tcpi_rcv_ssthresh uint32
+ Rtt uint32
+ Rttvar uint32
+ Snd_ssthresh uint32
+ Snd_cwnd uint32
+ X__tcpi_advmss uint32
+ X__tcpi_reordering uint32
+ X__tcpi_rcv_rtt uint32
+ Rcv_space uint32
+ Snd_wnd uint32
+ Snd_bwnd uint32
+ Snd_nxt uint32
+ Rcv_nxt uint32
+ Toe_tid uint32
+ Snd_rexmitpack uint32
+ Rcv_ooopack uint32
+ Snd_zerowin uint32
+ X__tcpi_pad [26]uint32
+}
diff --git a/vendor/github.com/mikioh/tcpinfo/zsys_linux.go b/vendor/github.com/mikioh/tcpinfo/zsys_linux.go
new file mode 100644
index 000000000000..c6f1e05a3dc5
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpinfo/zsys_linux.go
@@ -0,0 +1,103 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_linux.go
+
+package tcpinfo
+
+const (
+ sysTCP_INFO = 0xb
+ sysTCP_CONGESTION = 0xd
+ sysTCP_CC_INFO = 0x1a
+
+ sysTCPI_OPT_TIMESTAMPS = 0x1
+ sysTCPI_OPT_SACK = 0x2
+ sysTCPI_OPT_WSCALE = 0x4
+ sysTCPI_OPT_ECN = 0x8
+ sysTCPI_OPT_ECN_SEEN = 0x10
+ sysTCPI_OPT_SYN_DATA = 0x20
+
+ CAOpen CAState = 0x0
+ CADisorder CAState = 0x1
+ CACWR CAState = 0x2
+ CARecovery CAState = 0x3
+ CALoss CAState = 0x4
+
+ sizeofTCPInfo = 0xc0
+ sizeofTCPCCInfo = 0x14
+ sizeofTCPVegasInfo = 0x10
+ sizeofTCPDCTCPInfo = 0x10
+ sizeofTCPBBRInfo = 0x14
+)
+
+type tcpInfo struct {
+ State uint8
+ Ca_state uint8
+ Retransmits uint8
+ Probes uint8
+ Backoff uint8
+ Options uint8
+ Pad_cgo_0 [1]byte
+ Pad_cgo_1 [1]byte
+ Rto uint32
+ Ato uint32
+ Snd_mss uint32
+ Rcv_mss uint32
+ Unacked uint32
+ Sacked uint32
+ Lost uint32
+ Retrans uint32
+ Fackets uint32
+ Last_data_sent uint32
+ Last_ack_sent uint32
+ Last_data_recv uint32
+ Last_ack_recv uint32
+ Pmtu uint32
+ Rcv_ssthresh uint32
+ Rtt uint32
+ Rttvar uint32
+ Snd_ssthresh uint32
+ Snd_cwnd uint32
+ Advmss uint32
+ Reordering uint32
+ Rcv_rtt uint32
+ Rcv_space uint32
+ Total_retrans uint32
+ Pacing_rate uint64
+ Max_pacing_rate uint64
+ Bytes_acked uint64
+ Bytes_received uint64
+ Segs_out uint32
+ Segs_in uint32
+ Notsent_bytes uint32
+ Min_rtt uint32
+ Data_segs_in uint32
+ Data_segs_out uint32
+ Delivery_rate uint64
+ Busy_time uint64
+ Rwnd_limited uint64
+ Sndbuf_limited uint64
+}
+
+type tcpCCInfo [20]byte
+
+type tcpVegasInfo struct {
+ Enabled uint32
+ Rttcnt uint32
+ Rtt uint32
+ Minrtt uint32
+}
+
+type tcpDCTCPInfo struct {
+ Enabled uint16
+ Ce_state uint16
+ Alpha uint32
+ Ab_ecn uint32
+ Ab_tot uint32
+}
+
+type tcpBBRInfo struct {
+ Bw_lo uint32
+ Bw_hi uint32
+ Min_rtt uint32
+ Pacing_gain uint32
+ Cwnd_gain uint32
+}
diff --git a/vendor/github.com/mikioh/tcpinfo/zsys_netbsd.go b/vendor/github.com/mikioh/tcpinfo/zsys_netbsd.go
new file mode 100644
index 000000000000..126355e04434
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpinfo/zsys_netbsd.go
@@ -0,0 +1,58 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_netbsd.go
+
+package tcpinfo
+
+const (
+ sysTCP_INFO = 0x9
+
+ sysTCPI_OPT_TIMESTAMPS = 0x1
+ sysTCPI_OPT_SACK = 0x2
+ sysTCPI_OPT_WSCALE = 0x4
+ sysTCPI_OPT_ECN = 0x8
+ sysTCPI_OPT_TOE = 0x10
+
+ sizeofTCPInfo = 0xec
+)
+
+type tcpInfo struct {
+ State uint8
+ X__tcpi_ca_state uint8
+ X__tcpi_retransmits uint8
+ X__tcpi_probes uint8
+ X__tcpi_backoff uint8
+ Options uint8
+ Pad_cgo_0 [2]byte
+ Rto uint32
+ X__tcpi_ato uint32
+ Snd_mss uint32
+ Rcv_mss uint32
+ X__tcpi_unacked uint32
+ X__tcpi_sacked uint32
+ X__tcpi_lost uint32
+ X__tcpi_retrans uint32
+ X__tcpi_fackets uint32
+ X__tcpi_last_data_sent uint32
+ X__tcpi_last_ack_sent uint32
+ Last_data_recv uint32
+ X__tcpi_last_ack_recv uint32
+ X__tcpi_pmtu uint32
+ X__tcpi_rcv_ssthresh uint32
+ Rtt uint32
+ Rttvar uint32
+ Snd_ssthresh uint32
+ Snd_cwnd uint32
+ X__tcpi_advmss uint32
+ X__tcpi_reordering uint32
+ X__tcpi_rcv_rtt uint32
+ Rcv_space uint32
+ Snd_wnd uint32
+ Snd_bwnd uint32
+ Snd_nxt uint32
+ Rcv_nxt uint32
+ Toe_tid uint32
+ Snd_rexmitpack uint32
+ Rcv_ooopack uint32
+ Snd_zerowin uint32
+ X__tcpi_pad [26]uint32
+}
diff --git a/vendor/github.com/mikioh/tcpopt/LICENSE b/vendor/github.com/mikioh/tcpopt/LICENSE
new file mode 100644
index 000000000000..5a4edfbebc0a
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/LICENSE
@@ -0,0 +1,23 @@
+Copyright (c) 2016, Mikio Hara
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/mikioh/tcpopt/README.md b/vendor/github.com/mikioh/tcpopt/README.md
new file mode 100644
index 000000000000..59a930f9738c
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/README.md
@@ -0,0 +1,6 @@
+Package tcpopt implements encoding and decoding of TCP-level socket options.
+
+[![GoDoc](https://godoc.org/github.com/mikioh/tcpopt?status.png)](https://godoc.org/github.com/mikioh/tcpopt)
+[![Build Status](https://travis-ci.org/mikioh/tcpopt.svg?branch=master)](https://travis-ci.org/mikioh/tcpopt)
+[![Build status](https://ci.appveyor.com/api/projects/status/yljh492jsenpi0nd?svg=true)](https://ci.appveyor.com/project/mikioh/tcpopt)
+[![Go Report Card](https://goreportcard.com/badge/github.com/mikioh/tcpopt)](https://goreportcard.com/report/github.com/mikioh/tcpopt)
diff --git a/vendor/github.com/mikioh/tcpopt/appveyor.yml b/vendor/github.com/mikioh/tcpopt/appveyor.yml
new file mode 100644
index 000000000000..9ad48270344e
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/appveyor.yml
@@ -0,0 +1,18 @@
+version: "{build}"
+
+branches:
+ only:
+ - master
+
+environment:
+ GOPATH: c:\gopath
+
+install:
+ - set PATH=%GOPATH%\bin;c:\go\bin;%PATH%
+ - mkdir c:\gopath
+ - go get github.com/mikioh/tcp
+ - go get github.com/mikioh/tcpopt
+ - go get github.com/mikioh/tcpinfo
+
+build_script:
+ - go test -v -race
diff --git a/vendor/github.com/mikioh/tcpopt/doc.go b/vendor/github.com/mikioh/tcpopt/doc.go
new file mode 100644
index 000000000000..32fdd8d7214c
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/doc.go
@@ -0,0 +1,7 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package tcpopt implements encoding and decoding of TCP-level socket
+// options.
+package tcpopt
diff --git a/vendor/github.com/mikioh/tcpopt/option.go b/vendor/github.com/mikioh/tcpopt/option.go
new file mode 100644
index 000000000000..d2a807aacf3a
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/option.go
@@ -0,0 +1,150 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcpopt
+
+import "time"
+
+// An Option represents a socket option.
+type Option interface {
+ // Level returns the platform-specific socket option level.
+ Level() int
+
+ // Name returns the platform-specific socket option name.
+ Name() int
+
+ // Marshal returns the binary encoding of socket option.
+ Marshal() ([]byte, error)
+}
+
+// NoDelay specifies the use of Nagle's algorithm.
+type NoDelay bool
+
+// Level implements the Level method of Option interface.
+func (nd NoDelay) Level() int { return options[soNodelay].level }
+
+// Name implements the Name method of Option interface.
+func (nd NoDelay) Name() int { return options[soNodelay].name }
+
+// MSS specifies the maximum segment size.
+type MSS int
+
+// Level implements the Level method of Option interface.
+func (mss MSS) Level() int { return options[soMaxseg].level }
+
+// Name implements the Name method of Option interface.
+func (mss MSS) Name() int { return options[soMaxseg].name }
+
+// SendBuffer specifies the size of send buffer.
+type SendBuffer int
+
+// Level implements the Level method of Option interface.
+func (sb SendBuffer) Level() int { return options[soSndbuf].level }
+
+// Name implements the Name method of Option interface.
+func (sb SendBuffer) Name() int { return options[soSndbuf].name }
+
+// ReceiveBuffer specifies the size of receive buffer.
+type ReceiveBuffer int
+
+// Level implements the Level method of Option interface.
+func (rb ReceiveBuffer) Level() int { return options[soRcvbuf].level }
+
+// Name implements the Name method of Option interface.
+func (rb ReceiveBuffer) Name() int { return options[soRcvbuf].name }
+
+// KeepAlive specifies the use of keep alive.
+type KeepAlive bool
+
+// Level implements the Level method of Option interface.
+func (ka KeepAlive) Level() int { return options[soKeepalive].level }
+
+// Name implements the Name method of Option interface.
+func (ka KeepAlive) Name() int { return options[soKeepalive].name }
+
+// KeepAliveIdleInterval is the idle interval until the first probe is
+// sent.
+//
+// OpenBSD doesn't support this option.
+// See TCP_KEEPIDLE or TCP_KEEPALIVE for further information.
+type KeepAliveIdleInterval time.Duration
+
+// Level implements the Level method of Option interface.
+func (ka KeepAliveIdleInterval) Level() int { return options[soKeepidle].level }
+
+// Name implements the Name method of Option interface.
+func (ka KeepAliveIdleInterval) Name() int { return options[soKeepidle].name }
+
+// KeepAliveProbeInterval is the interval between keepalive probes.
+//
+// OpenBSD doesn't support this option.
+// See TCP_KEEPINTVL for further information.
+type KeepAliveProbeInterval time.Duration
+
+// Level implements the Level method of Option interface.
+func (ka KeepAliveProbeInterval) Level() int { return options[soKeepintvl].level }
+
+// Name implements the Name method of Option interface.
+func (ka KeepAliveProbeInterval) Name() int { return options[soKeepintvl].name }
+
+// KeepAliveProbeCount is the number of keepalive probes should be
+// repeated when the peer is not responding.
+//
+// OpenBSD and Windows don't support this option.
+// See TCP_KEEPCNT for further information.
+type KeepAliveProbeCount int
+
+// Level implements the Level method of Option interface.
+func (ka KeepAliveProbeCount) Level() int { return options[soKeepcnt].level }
+
+// Name implements the Name method of Option interface.
+func (ka KeepAliveProbeCount) Name() int { return options[soKeepcnt].name }
+
+// Cork specifies the use of TCP_CORK or TCP_NOPUSH option.
+//
+// On DragonFly BSD, the caller may need to adjust the
+// net.inet.tcp.disable_nopush kernel state.
+// NetBSD and Windows don't support this option.
+type Cork bool
+
+// Level implements the Level method of Option interface.
+func (ck Cork) Level() int { return options[soCork].level }
+
+// Name implements the Name method of Option interface.
+func (ck Cork) Name() int { return options[soCork].name }
+
+// NotSentLowWMK specifies the amount of unsent bytes in transmission
+// queue. The network poller such as kqueue or epoll doesn't report
+// that the connection is writable while the amount of unsent data
+// size is greater than NotSentLowWMK.
+//
+// Only Darwin and Linux support this option.
+// See TCP_NOTSENT_LOWAT for further information.
+type NotSentLowWMK int
+
+// Level implements the Level method of Option interface.
+func (ns NotSentLowWMK) Level() int { return options[soNotsentLOWAT].level }
+
+// Name implements the Name method of Option interface.
+func (ns NotSentLowWMK) Name() int { return options[soNotsentLOWAT].name }
+
+// Error represents an error on the socket.
+type Error int
+
+// Level implements the Level method of Option interface.
+func (e Error) Level() int { return options[soError].level }
+
+// Name implements the Name method of Option interface.
+func (e Error) Name() int { return options[soError].name }
+
+// ECN specifies the use of ECN.
+//
+// Only Darwin supports this option.
+type ECN bool
+
+// Level implements the Level method of Option interface.
+func (cn ECN) Level() int { return options[soECN].level }
+
+// Name implements the Name method of Option interface.
+func (cn ECN) Name() int { return options[soECN].name }
diff --git a/vendor/github.com/mikioh/tcpopt/parse.go b/vendor/github.com/mikioh/tcpopt/parse.go
new file mode 100644
index 000000000000..2b22e07777b4
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/parse.go
@@ -0,0 +1,37 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcpopt
+
+import (
+ "fmt"
+ "sync"
+)
+
+var parserMu sync.RWMutex
+
+// Register registers a socket option parser.
+func Register(level, name int, fn func([]byte) (Option, error)) {
+ parserMu.Lock()
+ parsers[int64(level)<<32|int64(name)] = fn
+ parserMu.Unlock()
+}
+
+// Unregister unregisters a socket option parser.
+func Unregister(level, name int) {
+ parserMu.Lock()
+ delete(parsers, int64(level)<<32|int64(name))
+ parserMu.Unlock()
+}
+
+// Parse parses a socket option.
+func Parse(level, name int, b []byte) (Option, error) {
+ parserMu.RLock()
+ defer parserMu.RUnlock()
+ fn, ok := parsers[int64(level)<<32|int64(name)]
+ if !ok {
+ return nil, fmt.Errorf("parser for level=%#x name=%#x not found", level, name)
+ }
+ return fn(b)
+}
diff --git a/vendor/github.com/mikioh/tcpopt/sys.go b/vendor/github.com/mikioh/tcpopt/sys.go
new file mode 100644
index 000000000000..a445eeafa012
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/sys.go
@@ -0,0 +1,66 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcpopt
+
+import (
+ "encoding/binary"
+ "time"
+ "unsafe"
+)
+
+var nativeEndian binary.ByteOrder
+
+func init() {
+ i := uint32(1)
+ b := (*[4]byte)(unsafe.Pointer(&i))
+ if b[0] == 1 {
+ nativeEndian = binary.LittleEndian
+ } else {
+ nativeEndian = binary.BigEndian
+ }
+}
+
+func boolint32(b bool) int32 {
+ if b {
+ return 1
+ }
+ return 0
+}
+
+func uint32bool(n uint32) bool {
+ if n != 0 {
+ return true
+ }
+ return false
+}
+
+const (
+ ianaProtocolIP = 0x0
+ ianaProtocolTCP = 0x6
+ ianaProtocolIPv6 = 0x29
+)
+
+const (
+ soNodelay = iota
+ soSndbuf
+ soRcvbuf
+ soKeepalive
+ soKeepidle
+ soKeepintvl
+ soKeepcnt
+ soCork
+ soNotsentLOWAT
+ soError
+ soECN
+ soMaxseg
+ soMax
+)
+
+// An option represents a binding for socket option.
+type option struct {
+ level int // option level
+ name int // option name, must be equal or greater than 1
+ uot time.Duration // unit of time
+}
diff --git a/vendor/github.com/mikioh/tcpopt/sys_darwin.go b/vendor/github.com/mikioh/tcpopt/sys_darwin.go
new file mode 100644
index 000000000000..3bc70b241663
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/sys_darwin.go
@@ -0,0 +1,37 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcpopt
+
+import "time"
+
+var options = [soMax]option{
+ soNodelay: {ianaProtocolTCP, sysTCP_NODELAY, 0},
+ soMaxseg: {ianaProtocolTCP, sysTCP_MAXSEG, 0},
+ soSndbuf: {sysSOL_SOCKET, sysSO_SNDBUF, 0},
+ soRcvbuf: {sysSOL_SOCKET, sysSO_RCVBUF, 0},
+ soKeepalive: {sysSOL_SOCKET, sysSO_KEEPALIVE, 0},
+ soKeepidle: {ianaProtocolTCP, sysTCP_KEEPALIVE, time.Second},
+ soKeepintvl: {ianaProtocolTCP, sysTCP_KEEPINTVL, time.Second},
+ soKeepcnt: {ianaProtocolTCP, sysTCP_KEEPCNT, 0},
+ soCork: {ianaProtocolTCP, sysTCP_NOPUSH, 0},
+ soNotsentLOWAT: {ianaProtocolTCP, sysTCP_NOTSENT_LOWAT, 0},
+ soError: {sysSOL_SOCKET, sysSO_ERROR, 0},
+ soECN: {ianaProtocolTCP, sysTCP_ENABLE_ECN, 0},
+}
+
+var parsers = map[int64]func([]byte) (Option, error){
+ ianaProtocolTCP<<32 | sysTCP_NODELAY: parseNoDelay,
+ ianaProtocolTCP<<32 | sysTCP_MAXSEG: parseMSS,
+ sysSOL_SOCKET<<32 | sysSO_SNDBUF: parseSendBuffer,
+ sysSOL_SOCKET<<32 | sysSO_RCVBUF: parseReceiveBuffer,
+ sysSOL_SOCKET<<32 | sysSO_KEEPALIVE: parseKeepAlive,
+ ianaProtocolTCP<<32 | sysTCP_KEEPALIVE: parseKeepAliveIdleInterval,
+ ianaProtocolTCP<<32 | sysTCP_KEEPINTVL: parseKeepAliveProbeInterval,
+ ianaProtocolTCP<<32 | sysTCP_KEEPCNT: parseKeepAliveProbeCount,
+ ianaProtocolTCP<<32 | sysTCP_NOPUSH: parseCork,
+ ianaProtocolTCP<<32 | sysTCP_NOTSENT_LOWAT: parseNotSentLowWMK,
+ sysSOL_SOCKET<<32 | sysSO_ERROR: parseError,
+ ianaProtocolTCP<<32 | sysTCP_ENABLE_ECN: parseECN,
+}
diff --git a/vendor/github.com/mikioh/tcpopt/sys_dragonfly.go b/vendor/github.com/mikioh/tcpopt/sys_dragonfly.go
new file mode 100644
index 000000000000..7e24d76f3e06
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/sys_dragonfly.go
@@ -0,0 +1,35 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build dragonfly
+
+package tcpopt
+
+import "time"
+
+var options = [soMax]option{
+ soNodelay: {ianaProtocolTCP, sysTCP_NODELAY, 0},
+ soMaxseg: {ianaProtocolTCP, sysTCP_MAXSEG, 0},
+ soSndbuf: {sysSOL_SOCKET, sysSO_SNDBUF, 0},
+ soRcvbuf: {sysSOL_SOCKET, sysSO_RCVBUF, 0},
+ soKeepalive: {sysSOL_SOCKET, sysSO_KEEPALIVE, 0},
+ soKeepidle: {ianaProtocolTCP, sysTCP_KEEPIDLE, time.Millisecond},
+ soKeepintvl: {ianaProtocolTCP, sysTCP_KEEPINTVL, time.Millisecond},
+ soKeepcnt: {ianaProtocolTCP, sysTCP_KEEPCNT, 0},
+ soCork: {ianaProtocolTCP, sysTCP_NOPUSH, 0},
+ soError: {sysSOL_SOCKET, sysSO_ERROR, 0},
+}
+
+var parsers = map[int64]func([]byte) (Option, error){
+ ianaProtocolTCP<<32 | sysTCP_NODELAY: parseNoDelay,
+ ianaProtocolTCP<<32 | sysTCP_MAXSEG: parseMSS,
+ sysSOL_SOCKET<<32 | sysSO_SNDBUF: parseSendBuffer,
+ sysSOL_SOCKET<<32 | sysSO_RCVBUF: parseReceiveBuffer,
+ sysSOL_SOCKET<<32 | sysSO_KEEPALIVE: parseKeepAlive,
+ ianaProtocolTCP<<32 | sysTCP_KEEPIDLE: parseKeepAliveIdleInterval,
+ ianaProtocolTCP<<32 | sysTCP_KEEPINTVL: parseKeepAliveProbeInterval,
+ ianaProtocolTCP<<32 | sysTCP_KEEPCNT: parseKeepAliveProbeCount,
+ ianaProtocolTCP<<32 | sysTCP_NOPUSH: parseCork,
+ sysSOL_SOCKET<<32 | sysSO_ERROR: parseError,
+}
diff --git a/vendor/github.com/mikioh/tcpopt/sys_freebsd.go b/vendor/github.com/mikioh/tcpopt/sys_freebsd.go
new file mode 100644
index 000000000000..01c6f155be0b
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/sys_freebsd.go
@@ -0,0 +1,33 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcpopt
+
+import "time"
+
+var options = [soMax]option{
+ soNodelay: {ianaProtocolTCP, sysTCP_NODELAY, 0},
+ soMaxseg: {ianaProtocolTCP, sysTCP_MAXSEG, 0},
+ soSndbuf: {sysSOL_SOCKET, sysSO_SNDBUF, 0},
+ soRcvbuf: {sysSOL_SOCKET, sysSO_RCVBUF, 0},
+ soKeepalive: {sysSOL_SOCKET, sysSO_KEEPALIVE, 0},
+ soKeepidle: {ianaProtocolTCP, sysTCP_KEEPIDLE, time.Second},
+ soKeepintvl: {ianaProtocolTCP, sysTCP_KEEPINTVL, time.Second},
+ soKeepcnt: {ianaProtocolTCP, sysTCP_KEEPCNT, 0},
+ soCork: {ianaProtocolTCP, sysTCP_NOPUSH, 0},
+ soError: {sysSOL_SOCKET, sysSO_ERROR, 0},
+}
+
+var parsers = map[int64]func([]byte) (Option, error){
+ ianaProtocolTCP<<32 | sysTCP_NODELAY: parseNoDelay,
+ ianaProtocolTCP<<32 | sysTCP_MAXSEG: parseMSS,
+ sysSOL_SOCKET<<32 | sysSO_SNDBUF: parseSendBuffer,
+ sysSOL_SOCKET<<32 | sysSO_RCVBUF: parseReceiveBuffer,
+ sysSOL_SOCKET<<32 | sysSO_KEEPALIVE: parseKeepAlive,
+ ianaProtocolTCP<<32 | sysTCP_KEEPIDLE: parseKeepAliveIdleInterval,
+ ianaProtocolTCP<<32 | sysTCP_KEEPINTVL: parseKeepAliveProbeInterval,
+ ianaProtocolTCP<<32 | sysTCP_KEEPCNT: parseKeepAliveProbeCount,
+ ianaProtocolTCP<<32 | sysTCP_NOPUSH: parseCork,
+ sysSOL_SOCKET<<32 | sysSO_ERROR: parseError,
+}
diff --git a/vendor/github.com/mikioh/tcpopt/sys_linux.go b/vendor/github.com/mikioh/tcpopt/sys_linux.go
new file mode 100644
index 000000000000..ff31caea53f3
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/sys_linux.go
@@ -0,0 +1,35 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcpopt
+
+import "time"
+
+var options = [soMax]option{
+ soNodelay: {ianaProtocolTCP, sysTCP_NODELAY, 0},
+ soMaxseg: {ianaProtocolTCP, sysTCP_MAXSEG, 0},
+ soSndbuf: {sysSOL_SOCKET, sysSO_SNDBUF, 0},
+ soRcvbuf: {sysSOL_SOCKET, sysSO_RCVBUF, 0},
+ soKeepalive: {sysSOL_SOCKET, sysSO_KEEPALIVE, 0},
+ soKeepidle: {ianaProtocolTCP, sysTCP_KEEPIDLE, time.Second},
+ soKeepintvl: {ianaProtocolTCP, sysTCP_KEEPINTVL, time.Second},
+ soKeepcnt: {ianaProtocolTCP, sysTCP_KEEPCNT, 0},
+ soCork: {ianaProtocolTCP, sysTCP_CORK, 0},
+ soNotsentLOWAT: {ianaProtocolTCP, sysTCP_NOTSENT_LOWAT, 0},
+ soError: {sysSOL_SOCKET, sysSO_ERROR, 0},
+}
+
+var parsers = map[int64]func([]byte) (Option, error){
+ ianaProtocolTCP<<32 | sysTCP_NODELAY: parseNoDelay,
+ ianaProtocolTCP<<32 | sysTCP_MAXSEG: parseMSS,
+ sysSOL_SOCKET<<32 | sysSO_SNDBUF: parseSendBuffer,
+ sysSOL_SOCKET<<32 | sysSO_RCVBUF: parseReceiveBuffer,
+ sysSOL_SOCKET<<32 | sysSO_KEEPALIVE: parseKeepAlive,
+ ianaProtocolTCP<<32 | sysTCP_KEEPIDLE: parseKeepAliveIdleInterval,
+ ianaProtocolTCP<<32 | sysTCP_KEEPINTVL: parseKeepAliveProbeInterval,
+ ianaProtocolTCP<<32 | sysTCP_KEEPCNT: parseKeepAliveProbeCount,
+ ianaProtocolTCP<<32 | sysTCP_CORK: parseCork,
+ ianaProtocolTCP<<32 | sysTCP_NOTSENT_LOWAT: parseNotSentLowWMK,
+ sysSOL_SOCKET<<32 | sysSO_ERROR: parseError,
+}
diff --git a/vendor/github.com/mikioh/tcpopt/sys_netbsd.go b/vendor/github.com/mikioh/tcpopt/sys_netbsd.go
new file mode 100644
index 000000000000..0de8acd6c88d
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/sys_netbsd.go
@@ -0,0 +1,31 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcpopt
+
+import "time"
+
+var options = [soMax]option{
+ soNodelay: {ianaProtocolTCP, sysTCP_NODELAY, 0},
+ soMaxseg: {ianaProtocolTCP, sysTCP_MAXSEG, 0},
+ soSndbuf: {sysSOL_SOCKET, sysSO_SNDBUF, 0},
+ soRcvbuf: {sysSOL_SOCKET, sysSO_RCVBUF, 0},
+ soKeepalive: {sysSOL_SOCKET, sysSO_KEEPALIVE, 0},
+ soKeepidle: {ianaProtocolTCP, sysTCP_KEEPIDLE, time.Second},
+ soKeepintvl: {ianaProtocolTCP, sysTCP_KEEPINTVL, time.Second},
+ soKeepcnt: {ianaProtocolTCP, sysTCP_KEEPCNT, 0},
+ soError: {sysSOL_SOCKET, sysSO_ERROR, 0},
+}
+
+var parsers = map[int64]func([]byte) (Option, error){
+ ianaProtocolTCP<<32 | sysTCP_NODELAY: parseNoDelay,
+ ianaProtocolTCP<<32 | sysTCP_MAXSEG: parseMSS,
+ sysSOL_SOCKET<<32 | sysSO_SNDBUF: parseSendBuffer,
+ sysSOL_SOCKET<<32 | sysSO_RCVBUF: parseReceiveBuffer,
+ sysSOL_SOCKET<<32 | sysSO_KEEPALIVE: parseKeepAlive,
+ ianaProtocolTCP<<32 | sysTCP_KEEPIDLE: parseKeepAliveIdleInterval,
+ ianaProtocolTCP<<32 | sysTCP_KEEPINTVL: parseKeepAliveProbeInterval,
+ ianaProtocolTCP<<32 | sysTCP_KEEPCNT: parseKeepAliveProbeCount,
+ sysSOL_SOCKET<<32 | sysSO_ERROR: parseError,
+}
diff --git a/vendor/github.com/mikioh/tcpopt/sys_openbsd.go b/vendor/github.com/mikioh/tcpopt/sys_openbsd.go
new file mode 100644
index 000000000000..712073e3517f
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/sys_openbsd.go
@@ -0,0 +1,25 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcpopt
+
+var options = [soMax]option{
+ soNodelay: {ianaProtocolTCP, sysTCP_NODELAY, 0},
+ soMaxseg: {ianaProtocolTCP, sysTCP_MAXSEG, 0},
+ soSndbuf: {sysSOL_SOCKET, sysSO_SNDBUF, 0},
+ soRcvbuf: {sysSOL_SOCKET, sysSO_RCVBUF, 0},
+ soKeepalive: {sysSOL_SOCKET, sysSO_KEEPALIVE, 0},
+ soCork: {ianaProtocolTCP, sysTCP_NOPUSH, 0},
+ soError: {sysSOL_SOCKET, sysSO_ERROR, 0},
+}
+
+var parsers = map[int64]func([]byte) (Option, error){
+ ianaProtocolTCP<<32 | sysTCP_NODELAY: parseNoDelay,
+ ianaProtocolTCP<<32 | sysTCP_MAXSEG: parseMSS,
+ sysSOL_SOCKET<<32 | sysSO_SNDBUF: parseSendBuffer,
+ sysSOL_SOCKET<<32 | sysSO_RCVBUF: parseReceiveBuffer,
+ sysSOL_SOCKET<<32 | sysSO_KEEPALIVE: parseKeepAlive,
+ ianaProtocolTCP<<32 | sysTCP_NOPUSH: parseCork,
+ sysSOL_SOCKET<<32 | sysSO_ERROR: parseError,
+}
diff --git a/vendor/github.com/mikioh/tcpopt/sys_solaris.go b/vendor/github.com/mikioh/tcpopt/sys_solaris.go
new file mode 100644
index 000000000000..b5aafa1e24f4
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/sys_solaris.go
@@ -0,0 +1,54 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build solaris
+
+package tcpopt
+
+import "time"
+
+const (
+ sysSOL_SOCKET = 0xffff
+
+ sysSO_SNDBUF = 0x1001
+ sysSO_RCVBUF = 0x1002
+ sysSO_KEEPALIVE = 0x8
+
+ sysTCP_NODELAY = 0x1
+ sysTCP_MAXSEG = 0x2
+ sysTCP_KEEPALIVE = 0x8
+ sysTCP_KEEPALIVE_THRESHOLD = 0x16
+ sysTCP_KEEPALIVE_ABORT_THRESHOLD = 0x17
+ sysTCP_KEEPIDLE = 0x22
+ sysTCP_KEEPCNT = 0x23
+ sysTCP_KEEPINTVL = 0x24
+ sysTCP_CORK = 0x18
+ sysSO_ERROR = 0x1007
+)
+
+var options = [soMax]option{
+ soNodelay: {ianaProtocolTCP, sysTCP_NODELAY, 0},
+ soMaxseg: {ianaProtocolTCP, sysTCP_MAXSEG, 0},
+ soSndbuf: {sysSOL_SOCKET, sysSO_SNDBUF, 0},
+ soRcvbuf: {sysSOL_SOCKET, sysSO_RCVBUF, 0},
+ soKeepalive: {sysSOL_SOCKET, sysSO_KEEPALIVE, 0},
+ soKeepidle: {ianaProtocolTCP, sysTCP_KEEPIDLE, time.Second},
+ soKeepintvl: {ianaProtocolTCP, sysTCP_KEEPINTVL, time.Second},
+ soKeepcnt: {ianaProtocolTCP, sysTCP_KEEPCNT, 0},
+ soCork: {ianaProtocolTCP, sysTCP_CORK, 0},
+ soError: {sysSOL_SOCKET, sysSO_ERROR, 0},
+}
+
+var parsers = map[int64]func([]byte) (Option, error){
+ ianaProtocolTCP<<32 | sysTCP_NODELAY: parseNoDelay,
+ ianaProtocolTCP<<32 | sysTCP_MAXSEG: parseMSS,
+ sysSOL_SOCKET<<32 | sysSO_SNDBUF: parseSendBuffer,
+ sysSOL_SOCKET<<32 | sysSO_RCVBUF: parseReceiveBuffer,
+ sysSOL_SOCKET<<32 | sysSO_KEEPALIVE: parseKeepAlive,
+ ianaProtocolTCP<<32 | sysTCP_KEEPIDLE: parseKeepAliveIdleInterval,
+ ianaProtocolTCP<<32 | sysTCP_KEEPINTVL: parseKeepAliveProbeInterval,
+ ianaProtocolTCP<<32 | sysTCP_KEEPCNT: parseKeepAliveProbeCount,
+ ianaProtocolTCP<<32 | sysTCP_CORK: parseCork,
+ sysSOL_SOCKET<<32 | sysSO_ERROR: parseError,
+}
diff --git a/vendor/github.com/mikioh/tcpopt/sys_stub.go b/vendor/github.com/mikioh/tcpopt/sys_stub.go
new file mode 100644
index 000000000000..5e6bd9ac3b89
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/sys_stub.go
@@ -0,0 +1,73 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows
+
+package tcpopt
+
+import "errors"
+
+var options [soMax]option
+
+var parsers = map[int64]func([]byte) (Option, error){}
+
+// Marshal implements the Marshal method of Option interface.
+func (nd NoDelay) Marshal() ([]byte, error) {
+ return nil, errors.New("operation not supported")
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (mss MSS) Marshal() ([]byte, error) {
+ return nil, errors.New("operation not supported")
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (sb SendBuffer) Marshal() ([]byte, error) {
+ return nil, errors.New("operation not supported")
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (rb ReceiveBuffer) Marshal() ([]byte, error) {
+ return nil, errors.New("operation not supported")
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (ka KeepAlive) Marshal() ([]byte, error) {
+ return nil, errors.New("operation not supported")
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (ka KeepAliveIdleInterval) Marshal() ([]byte, error) {
+ return nil, errors.New("operation not supported")
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (ka KeepAliveProbeInterval) Marshal() ([]byte, error) {
+ return nil, errors.New("operation not supported")
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (ka KeepAliveProbeCount) Marshal() ([]byte, error) {
+ return nil, errors.New("operation not supported")
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (ck Cork) Marshal() ([]byte, error) {
+ return nil, errors.New("operation not supported")
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (ns NotSentLowWMK) Marshal() ([]byte, error) {
+ return nil, errors.New("operation not supported")
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (e Error) Marshal() ([]byte, error) {
+ return nil, errors.New("operation not supported")
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (cn ECN) Marshal() ([]byte, error) {
+ return nil, errors.New("operation not supported")
+}
diff --git a/vendor/github.com/mikioh/tcpopt/sys_unix.go b/vendor/github.com/mikioh/tcpopt/sys_unix.go
new file mode 100644
index 000000000000..dfe1237f126e
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/sys_unix.go
@@ -0,0 +1,173 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package tcpopt
+
+import (
+ "errors"
+ "time"
+ "unsafe"
+)
+
+// Marshal implements the Marshal method of Option interface.
+func (nd NoDelay) Marshal() ([]byte, error) {
+ v := boolint32(bool(nd))
+ return (*[4]byte)(unsafe.Pointer(&v))[:], nil
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (mss MSS) Marshal() ([]byte, error) {
+ v := int32(mss)
+ return (*[4]byte)(unsafe.Pointer(&v))[:], nil
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (sb SendBuffer) Marshal() ([]byte, error) {
+ v := int32(sb)
+ return (*[4]byte)(unsafe.Pointer(&v))[:], nil
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (rb ReceiveBuffer) Marshal() ([]byte, error) {
+ v := int32(rb)
+ return (*[4]byte)(unsafe.Pointer(&v))[:], nil
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (ka KeepAlive) Marshal() ([]byte, error) {
+ v := boolint32(bool(ka))
+ return (*[4]byte)(unsafe.Pointer(&v))[:], nil
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (ka KeepAliveIdleInterval) Marshal() ([]byte, error) {
+ ka += KeepAliveIdleInterval(options[soKeepidle].uot - time.Nanosecond)
+ v := int32(time.Duration(ka) / options[soKeepidle].uot)
+ return (*[4]byte)(unsafe.Pointer(&v))[:], nil
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (ka KeepAliveProbeInterval) Marshal() ([]byte, error) {
+ ka += KeepAliveProbeInterval(options[soKeepintvl].uot - time.Nanosecond)
+ v := int32(time.Duration(ka) / options[soKeepintvl].uot)
+ return (*[4]byte)(unsafe.Pointer(&v))[:], nil
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (ka KeepAliveProbeCount) Marshal() ([]byte, error) {
+ v := int32(ka)
+ return (*[4]byte)(unsafe.Pointer(&v))[:], nil
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (ck Cork) Marshal() ([]byte, error) {
+ v := boolint32(bool(ck))
+ return (*[4]byte)(unsafe.Pointer(&v))[:], nil
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (ns NotSentLowWMK) Marshal() ([]byte, error) {
+ v := int32(ns)
+ return (*[4]byte)(unsafe.Pointer(&v))[:], nil
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (e Error) Marshal() ([]byte, error) {
+ v := int32(e)
+ return (*[4]byte)(unsafe.Pointer(&v))[:], nil
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (cn ECN) Marshal() ([]byte, error) {
+ v := boolint32(bool(cn))
+ return (*[4]byte)(unsafe.Pointer(&v))[:], nil
+}
+
+func parseNoDelay(b []byte) (Option, error) {
+ if len(b) < 4 {
+ return nil, errors.New("short buffer")
+ }
+ return NoDelay(uint32bool(nativeEndian.Uint32(b))), nil
+}
+
+func parseMSS(b []byte) (Option, error) {
+ if len(b) < 4 {
+ return nil, errors.New("short buffer")
+ }
+ return MSS(nativeEndian.Uint32(b)), nil
+}
+
+func parseSendBuffer(b []byte) (Option, error) {
+ if len(b) < 4 {
+ return nil, errors.New("short buffer")
+ }
+ return SendBuffer(nativeEndian.Uint32(b)), nil
+}
+
+func parseReceiveBuffer(b []byte) (Option, error) {
+ if len(b) < 4 {
+ return nil, errors.New("short buffer")
+ }
+ return ReceiveBuffer(nativeEndian.Uint32(b)), nil
+}
+
+func parseKeepAlive(b []byte) (Option, error) {
+ if len(b) < 4 {
+ return nil, errors.New("short buffer")
+ }
+ return KeepAlive(uint32bool(nativeEndian.Uint32(b))), nil
+}
+
+func parseKeepAliveIdleInterval(b []byte) (Option, error) {
+ if len(b) < 4 {
+ return nil, errors.New("short buffer")
+ }
+ v := time.Duration(nativeEndian.Uint32(b)) * options[soKeepidle].uot
+ return KeepAliveIdleInterval(v), nil
+}
+
+func parseKeepAliveProbeInterval(b []byte) (Option, error) {
+ if len(b) < 4 {
+ return nil, errors.New("short buffer")
+ }
+ v := time.Duration(nativeEndian.Uint32(b)) * options[soKeepintvl].uot
+ return KeepAliveProbeInterval(v), nil
+}
+
+func parseKeepAliveProbeCount(b []byte) (Option, error) {
+ if len(b) < 4 {
+ return nil, errors.New("short buffer")
+ }
+ return KeepAliveProbeCount(nativeEndian.Uint32(b)), nil
+}
+
+func parseCork(b []byte) (Option, error) {
+ if len(b) < 4 {
+ return nil, errors.New("short buffer")
+ }
+ return Cork(uint32bool(nativeEndian.Uint32(b))), nil
+}
+
+func parseNotSentLowWMK(b []byte) (Option, error) {
+ if len(b) < 4 {
+ return nil, errors.New("short buffer")
+ }
+ return NotSentLowWMK(nativeEndian.Uint32(b)), nil
+}
+
+func parseError(b []byte) (Option, error) {
+ if len(b) < 4 {
+ return nil, errors.New("short buffer")
+ }
+ return Error(nativeEndian.Uint32(b)), nil
+}
+
+func parseECN(b []byte) (Option, error) {
+ if len(b) < 4 {
+ return nil, errors.New("short buffer")
+ }
+ return ECN(uint32bool(nativeEndian.Uint32(b))), nil
+}
diff --git a/vendor/github.com/mikioh/tcpopt/sys_windows.go b/vendor/github.com/mikioh/tcpopt/sys_windows.go
new file mode 100644
index 000000000000..2f4b2c76b997
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/sys_windows.go
@@ -0,0 +1,144 @@
+// Copyright 2016 Mikio Hara. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tcpopt
+
+import (
+ "errors"
+ "time"
+ "unsafe"
+)
+
+const (
+ sysSOL_SOCKET = 0xffff
+
+ sysSO_SNDBUF = 0x1001
+ sysSO_RCVBUF = 0x1002
+ sysSO_KEEPALIVE = 0x8
+
+ sysTCP_NODELAY = 0x1
+
+ sysIOC_OUT = 0x40000000
+ sysIOC_IN = 0x80000000
+ sysIOC_VENDOR = 0x18000000
+)
+
+var sysSIO_KEEPALIVE_VALS uint = sysIOC_IN | sysIOC_VENDOR | 4
+
+var options = [soMax]option{
+ soNodelay: {ianaProtocolTCP, sysTCP_NODELAY, 0},
+ soSndbuf: {sysSOL_SOCKET, sysSO_SNDBUF, 0},
+ soRcvbuf: {sysSOL_SOCKET, sysSO_RCVBUF, 0},
+ soKeepalive: {sysSOL_SOCKET, sysSO_KEEPALIVE, 0},
+ soKeepidle: {ianaProtocolTCP, int(sysSIO_KEEPALIVE_VALS), time.Millisecond},
+ soKeepintvl: {ianaProtocolTCP, int(sysSIO_KEEPALIVE_VALS), time.Millisecond},
+}
+
+var parsers = map[int64]func([]byte) (Option, error){
+ ianaProtocolTCP<<32 | sysTCP_NODELAY: parseNoDelay,
+ sysSOL_SOCKET<<32 | sysSO_SNDBUF: parseSendBuffer,
+ sysSOL_SOCKET<<32 | sysSO_RCVBUF: parseReceiveBuffer,
+ sysSOL_SOCKET<<32 | sysSO_KEEPALIVE: parseKeepAlive,
+ ianaProtocolTCP<<32 | int64(sysSIO_KEEPALIVE_VALS): parseKeepAliveValues,
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (nd NoDelay) Marshal() ([]byte, error) {
+ v := boolint32(bool(nd))
+ return (*[4]byte)(unsafe.Pointer(&v))[:], nil
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (mss MSS) Marshal() ([]byte, error) {
+ return nil, errors.New("operation not supported")
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (sb SendBuffer) Marshal() ([]byte, error) {
+ v := int32(sb)
+ return (*[4]byte)(unsafe.Pointer(&v))[:], nil
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (rb ReceiveBuffer) Marshal() ([]byte, error) {
+ v := int32(rb)
+ return (*[4]byte)(unsafe.Pointer(&v))[:], nil
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (ka KeepAlive) Marshal() ([]byte, error) {
+ v := boolint32(bool(ka))
+ return (*[4]byte)(unsafe.Pointer(&v))[:], nil
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (ka KeepAliveIdleInterval) Marshal() ([]byte, error) {
+ ka += KeepAliveIdleInterval(options[soKeepidle].uot - time.Nanosecond)
+ v := uint32(time.Duration(ka) / options[soKeepidle].uot)
+ return (*[4]byte)(unsafe.Pointer(&v))[:], nil
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (ka KeepAliveProbeInterval) Marshal() ([]byte, error) {
+ ka += KeepAliveProbeInterval(options[soKeepintvl].uot - time.Nanosecond)
+ v := uint32(time.Duration(ka) / options[soKeepintvl].uot)
+ return (*[4]byte)(unsafe.Pointer(&v))[:], nil
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (ka KeepAliveProbeCount) Marshal() ([]byte, error) {
+ return nil, errors.New("operation not supported")
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (ck Cork) Marshal() ([]byte, error) {
+ return nil, errors.New("operation not supported")
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (ns NotSentLowWMK) Marshal() ([]byte, error) {
+ return nil, errors.New("operation not supported")
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (e Error) Marshal() ([]byte, error) {
+ return nil, errors.New("operation not supported")
+}
+
+// Marshal implements the Marshal method of Option interface.
+func (cn ECN) Marshal() ([]byte, error) {
+ return nil, errors.New("operation not supported")
+}
+
+func parseNoDelay(b []byte) (Option, error) {
+ if len(b) < 4 {
+ return nil, errors.New("short buffer")
+ }
+ return NoDelay(uint32bool(nativeEndian.Uint32(b))), nil
+}
+
+func parseSendBuffer(b []byte) (Option, error) {
+ if len(b) < 4 {
+ return nil, errors.New("short buffer")
+ }
+ return SendBuffer(nativeEndian.Uint32(b)), nil
+}
+
+func parseReceiveBuffer(b []byte) (Option, error) {
+ if len(b) < 4 {
+ return nil, errors.New("short buffer")
+ }
+ return ReceiveBuffer(nativeEndian.Uint32(b)), nil
+}
+
+func parseKeepAlive(b []byte) (Option, error) {
+ if len(b) < 4 {
+ return nil, errors.New("short buffer")
+ }
+ return KeepAlive(uint32bool(nativeEndian.Uint32(b))), nil
+}
+
+func parseKeepAliveValues(b []byte) (Option, error) {
+ return nil, errors.New("operation not supported")
+}
diff --git a/vendor/github.com/mikioh/tcpopt/zsys_darwin.go b/vendor/github.com/mikioh/tcpopt/zsys_darwin.go
new file mode 100644
index 000000000000..729ca354e172
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/zsys_darwin.go
@@ -0,0 +1,22 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_darwin.go
+
+package tcpopt
+
+const (
+ sysSOL_SOCKET = 0xffff
+
+ sysSO_KEEPALIVE = 0x8
+ sysSO_SNDBUF = 0x1001
+ sysSO_RCVBUF = 0x1002
+ sysSO_ERROR = 0x1007
+
+ sysTCP_NODELAY = 0x1
+ sysTCP_MAXSEG = 0x2
+ sysTCP_KEEPALIVE = 0x10
+ sysTCP_KEEPINTVL = 0x101
+ sysTCP_KEEPCNT = 0x102
+ sysTCP_NOPUSH = 0x4
+ sysTCP_ENABLE_ECN = 0x104
+ sysTCP_NOTSENT_LOWAT = 0x201
+)
diff --git a/vendor/github.com/mikioh/tcpopt/zsys_dragonfly.go b/vendor/github.com/mikioh/tcpopt/zsys_dragonfly.go
new file mode 100644
index 000000000000..c1d727fe5bb6
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/zsys_dragonfly.go
@@ -0,0 +1,20 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_dragonfly.go
+
+package tcpopt
+
+const (
+ sysSOL_SOCKET = 0xffff
+
+ sysSO_KEEPALIVE = 0x8
+ sysSO_SNDBUF = 0x1001
+ sysSO_RCVBUF = 0x1002
+ sysSO_ERROR = 0x1007
+
+ sysTCP_NODELAY = 0x1
+ sysTCP_MAXSEG = 0x2
+ sysTCP_KEEPIDLE = 0x100
+ sysTCP_KEEPINTVL = 0x200
+ sysTCP_KEEPCNT = 0x400
+ sysTCP_NOPUSH = 0x4
+)
diff --git a/vendor/github.com/mikioh/tcpopt/zsys_freebsd.go b/vendor/github.com/mikioh/tcpopt/zsys_freebsd.go
new file mode 100644
index 000000000000..c9bd5b0c976b
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/zsys_freebsd.go
@@ -0,0 +1,20 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_freebsd.go
+
+package tcpopt
+
+const (
+ sysSOL_SOCKET = 0xffff
+
+ sysSO_KEEPALIVE = 0x8
+ sysSO_SNDBUF = 0x1001
+ sysSO_RCVBUF = 0x1002
+ sysSO_ERROR = 0x1007
+
+ sysTCP_NODELAY = 0x1
+ sysTCP_MAXSEG = 0x2
+ sysTCP_KEEPIDLE = 0x100
+ sysTCP_KEEPINTVL = 0x200
+ sysTCP_KEEPCNT = 0x400
+ sysTCP_NOPUSH = 0x4
+)
diff --git a/vendor/github.com/mikioh/tcpopt/zsys_linux_generic.go b/vendor/github.com/mikioh/tcpopt/zsys_linux_generic.go
new file mode 100644
index 000000000000..74c0a269f15e
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/zsys_linux_generic.go
@@ -0,0 +1,25 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_linux.go
+
+// +build !mips64
+// +build !mips64le
+// +build linux
+
+package tcpopt
+
+const (
+ sysSOL_SOCKET = 0x1
+
+ sysSO_KEEPALIVE = 0x9
+ sysSO_SNDBUF = 0x7
+ sysSO_RCVBUF = 0x8
+ sysSO_ERROR = 0x4
+
+ sysTCP_NODELAY = 0x1
+ sysTCP_MAXSEG = 0x2
+ sysTCP_KEEPIDLE = 0x4
+ sysTCP_KEEPINTVL = 0x5
+ sysTCP_KEEPCNT = 0x6
+ sysTCP_CORK = 0x3
+ sysTCP_NOTSENT_LOWAT = 0x19
+)
diff --git a/vendor/github.com/mikioh/tcpopt/zsys_linux_mips64x.go b/vendor/github.com/mikioh/tcpopt/zsys_linux_mips64x.go
new file mode 100644
index 000000000000..1121d5858132
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/zsys_linux_mips64x.go
@@ -0,0 +1,24 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_linux.go
+
+// +build mips64 mips64le
+// +build linux
+
+package tcpopt
+
+const (
+ sysSOL_SOCKET = 0x1
+
+ sysSO_KEEPALIVE = 0x8
+ sysSO_SNDBUF = 0x1001
+ sysSO_RCVBUF = 0x1002
+ sysSO_ERROR = 0x1007
+
+ sysTCP_NODELAY = 0x1
+ sysTCP_MAXSEG = 0x2
+ sysTCP_KEEPIDLE = 0x4
+ sysTCP_KEEPINTVL = 0x5
+ sysTCP_KEEPCNT = 0x6
+ sysTCP_CORK = 0x3
+ sysTCP_NOTSENT_LOWAT = 0x19
+)
diff --git a/vendor/github.com/mikioh/tcpopt/zsys_netbsd.go b/vendor/github.com/mikioh/tcpopt/zsys_netbsd.go
new file mode 100644
index 000000000000..c50edc641c6b
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/zsys_netbsd.go
@@ -0,0 +1,19 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_netbsd.go
+
+package tcpopt
+
+const (
+ sysSOL_SOCKET = 0xffff
+
+ sysSO_KEEPALIVE = 0x8
+ sysSO_SNDBUF = 0x1001
+ sysSO_RCVBUF = 0x1002
+ sysSO_ERROR = 0x1007
+
+ sysTCP_NODELAY = 0x1
+ sysTCP_MAXSEG = 0x2
+ sysTCP_KEEPIDLE = 0x3
+ sysTCP_KEEPINTVL = 0x5
+ sysTCP_KEEPCNT = 0x6
+)
diff --git a/vendor/github.com/mikioh/tcpopt/zsys_openbsd.go b/vendor/github.com/mikioh/tcpopt/zsys_openbsd.go
new file mode 100644
index 000000000000..981aadb6cc56
--- /dev/null
+++ b/vendor/github.com/mikioh/tcpopt/zsys_openbsd.go
@@ -0,0 +1,17 @@
+// Created by cgo -godefs - DO NOT EDIT
+// cgo -godefs defs_openbsd.go
+
+package tcpopt
+
+const (
+ sysSOL_SOCKET = 0xffff
+
+ sysSO_KEEPALIVE = 0x8
+ sysSO_SNDBUF = 0x1001
+ sysSO_RCVBUF = 0x1002
+ sysSO_ERROR = 0x1007
+
+ sysTCP_NODELAY = 0x1
+ sysTCP_MAXSEG = 0x2
+ sysTCP_NOPUSH = 0x10
+)
diff --git a/vendor/github.com/naoina/go-stringutil/strings.go b/vendor/github.com/naoina/go-stringutil/strings.go
index 881ca2c8f670..a628f70537b9 100644
--- a/vendor/github.com/naoina/go-stringutil/strings.go
+++ b/vendor/github.com/naoina/go-stringutil/strings.go
@@ -11,43 +11,43 @@ var (
// Based on https://github.com/golang/lint/blob/32a87160691b3c96046c0c678fe57c5bef761456/lint.go#L702
commonInitialismMap = map[string]struct{}{
- "API": struct{}{},
- "ASCII": struct{}{},
- "CPU": struct{}{},
- "CSRF": struct{}{},
- "CSS": struct{}{},
- "DNS": struct{}{},
- "EOF": struct{}{},
- "GUID": struct{}{},
- "HTML": struct{}{},
- "HTTP": struct{}{},
- "HTTPS": struct{}{},
- "ID": struct{}{},
- "IP": struct{}{},
- "JSON": struct{}{},
- "LHS": struct{}{},
- "QPS": struct{}{},
- "RAM": struct{}{},
- "RHS": struct{}{},
- "RPC": struct{}{},
- "SLA": struct{}{},
- "SMTP": struct{}{},
- "SQL": struct{}{},
- "SSH": struct{}{},
- "TCP": struct{}{},
- "TLS": struct{}{},
- "TTL": struct{}{},
- "UDP": struct{}{},
- "UI": struct{}{},
- "UID": struct{}{},
- "UUID": struct{}{},
- "URI": struct{}{},
- "URL": struct{}{},
- "UTF8": struct{}{},
- "VM": struct{}{},
- "XML": struct{}{},
- "XSRF": struct{}{},
- "XSS": struct{}{},
+ "API": {},
+ "ASCII": {},
+ "CPU": {},
+ "CSRF": {},
+ "CSS": {},
+ "DNS": {},
+ "EOF": {},
+ "GUID": {},
+ "HTML": {},
+ "HTTP": {},
+ "HTTPS": {},
+ "ID": {},
+ "IP": {},
+ "JSON": {},
+ "LHS": {},
+ "QPS": {},
+ "RAM": {},
+ "RHS": {},
+ "RPC": {},
+ "SLA": {},
+ "SMTP": {},
+ "SQL": {},
+ "SSH": {},
+ "TCP": {},
+ "TLS": {},
+ "TTL": {},
+ "UDP": {},
+ "UI": {},
+ "UID": {},
+ "UUID": {},
+ "URI": {},
+ "URL": {},
+ "UTF8": {},
+ "VM": {},
+ "XML": {},
+ "XSRF": {},
+ "XSS": {},
}
commonInitialisms = keys(commonInitialismMap)
commonInitialism = mustDoubleArray(newDoubleArray(commonInitialisms))
diff --git a/vendor/github.com/nsf/termbox-go/terminfo.go b/vendor/github.com/nsf/termbox-go/terminfo.go
index 35dbd70b8941..116231066cbe 100644
--- a/vendor/github.com/nsf/termbox-go/terminfo.go
+++ b/vendor/github.com/nsf/termbox-go/terminfo.go
@@ -159,7 +159,7 @@ func setup_term() (err error) {
table_offset = str_offset + 2*header[4]
keys = make([]string, 0xFFFF-key_min)
- for i, _ := range keys {
+ for i := range keys {
keys[i], err = ti_read_string(rd, str_offset+2*ti_keys[i], table_offset)
if err != nil {
return
@@ -168,7 +168,7 @@ func setup_term() (err error) {
funcs = make([]string, t_max_funcs)
// the last two entries are reserved for mouse. because the table offset is
// not there, the two entries have to fill in manually
- for i, _ := range funcs[:len(funcs)-2] {
+ for i := range funcs[:len(funcs)-2] {
funcs[i], err = ti_read_string(rd, str_offset+2*ti_funcs[i], table_offset)
if err != nil {
return
diff --git a/vendor/github.com/pmezard/go-difflib/difflib/difflib.go b/vendor/github.com/pmezard/go-difflib/difflib/difflib.go
index 003e99fadb4f..3cfbc1f7e715 100644
--- a/vendor/github.com/pmezard/go-difflib/difflib/difflib.go
+++ b/vendor/github.com/pmezard/go-difflib/difflib/difflib.go
@@ -161,12 +161,12 @@ func (m *SequenceMatcher) chainB() {
m.bJunk = map[string]struct{}{}
if m.IsJunk != nil {
junk := m.bJunk
- for s, _ := range b2j {
+ for s := range b2j {
if m.IsJunk(s) {
junk[s] = struct{}{}
}
}
- for s, _ := range junk {
+ for s := range junk {
delete(b2j, s)
}
}
@@ -181,7 +181,7 @@ func (m *SequenceMatcher) chainB() {
popular[s] = struct{}{}
}
}
- for s, _ := range popular {
+ for s := range popular {
delete(b2j, s)
}
}
@@ -416,7 +416,7 @@ func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode {
}
codes := m.GetOpCodes()
if len(codes) == 0 {
- codes = []OpCode{OpCode{'e', 0, 1, 0, 1}}
+ codes = []OpCode{{'e', 0, 1, 0, 1}}
}
// Fixup leading and trailing groups if they show no changes.
if codes[0].Tag == 'e' {
diff --git a/vendor/github.com/rcrowley/go-metrics/debug.go b/vendor/github.com/rcrowley/go-metrics/debug.go
index 043ccefab612..944412666bca 100644
--- a/vendor/github.com/rcrowley/go-metrics/debug.go
+++ b/vendor/github.com/rcrowley/go-metrics/debug.go
@@ -22,7 +22,7 @@ var (
// Capture new values for the Go garbage collector statistics exported in
// debug.GCStats. This is designed to be called as a goroutine.
func CaptureDebugGCStats(r Registry, d time.Duration) {
- for _ = range time.Tick(d) {
+ for range time.Tick(d) {
CaptureDebugGCStatsOnce(r)
}
}
diff --git a/vendor/github.com/rcrowley/go-metrics/graphite.go b/vendor/github.com/rcrowley/go-metrics/graphite.go
index abd0a7d2918b..142eec86beb4 100644
--- a/vendor/github.com/rcrowley/go-metrics/graphite.go
+++ b/vendor/github.com/rcrowley/go-metrics/graphite.go
@@ -39,7 +39,7 @@ func Graphite(r Registry, d time.Duration, prefix string, addr *net.TCPAddr) {
// but it takes a GraphiteConfig instead.
func GraphiteWithConfig(c GraphiteConfig) {
log.Printf("WARNING: This go-metrics client has been DEPRECATED! It has been moved to https://github.com/cyberdelia/go-metrics-graphite and will be removed from rcrowley/go-metrics on August 12th 2015")
- for _ = range time.Tick(c.FlushInterval) {
+ for range time.Tick(c.FlushInterval) {
if err := graphite(&c); nil != err {
log.Println(err)
}
diff --git a/vendor/github.com/rcrowley/go-metrics/json.go b/vendor/github.com/rcrowley/go-metrics/json.go
index 2fdcbcfbf1da..bf977ff9c62e 100644
--- a/vendor/github.com/rcrowley/go-metrics/json.go
+++ b/vendor/github.com/rcrowley/go-metrics/json.go
@@ -71,7 +71,7 @@ func (r *StandardRegistry) MarshalJSON() ([]byte, error) {
// WriteJSON writes metrics from the given registry periodically to the
// specified io.Writer as JSON.
func WriteJSON(r Registry, d time.Duration, w io.Writer) {
- for _ = range time.Tick(d) {
+ for range time.Tick(d) {
WriteJSONOnce(r, w)
}
}
diff --git a/vendor/github.com/rcrowley/go-metrics/log.go b/vendor/github.com/rcrowley/go-metrics/log.go
index f8074c045768..0c8ea7c97123 100644
--- a/vendor/github.com/rcrowley/go-metrics/log.go
+++ b/vendor/github.com/rcrowley/go-metrics/log.go
@@ -18,7 +18,7 @@ func LogScaled(r Registry, freq time.Duration, scale time.Duration, l Logger) {
du := float64(scale)
duSuffix := scale.String()[1:]
- for _ = range time.Tick(freq) {
+ for range time.Tick(freq) {
r.Each(func(name string, i interface{}) {
switch metric := i.(type) {
case Counter:
diff --git a/vendor/github.com/rcrowley/go-metrics/opentsdb.go b/vendor/github.com/rcrowley/go-metrics/opentsdb.go
index 266b6c93d21d..df7f152ed2eb 100644
--- a/vendor/github.com/rcrowley/go-metrics/opentsdb.go
+++ b/vendor/github.com/rcrowley/go-metrics/opentsdb.go
@@ -38,7 +38,7 @@ func OpenTSDB(r Registry, d time.Duration, prefix string, addr *net.TCPAddr) {
// OpenTSDBWithConfig is a blocking exporter function just like OpenTSDB,
// but it takes a OpenTSDBConfig instead.
func OpenTSDBWithConfig(c OpenTSDBConfig) {
- for _ = range time.Tick(c.FlushInterval) {
+ for range time.Tick(c.FlushInterval) {
if err := openTSDB(&c); nil != err {
log.Println(err)
}
diff --git a/vendor/github.com/rcrowley/go-metrics/registry.go b/vendor/github.com/rcrowley/go-metrics/registry.go
index 2bb7a1e7d0fd..898a72ee6eaa 100644
--- a/vendor/github.com/rcrowley/go-metrics/registry.go
+++ b/vendor/github.com/rcrowley/go-metrics/registry.go
@@ -120,7 +120,7 @@ func (r *StandardRegistry) Unregister(name string) {
func (r *StandardRegistry) UnregisterAll() {
r.mutex.Lock()
defer r.mutex.Unlock()
- for name, _ := range r.metrics {
+ for name := range r.metrics {
delete(r.metrics, name)
}
}
diff --git a/vendor/github.com/rcrowley/go-metrics/runtime.go b/vendor/github.com/rcrowley/go-metrics/runtime.go
index 11c6b785a0f8..9450c479bad7 100644
--- a/vendor/github.com/rcrowley/go-metrics/runtime.go
+++ b/vendor/github.com/rcrowley/go-metrics/runtime.go
@@ -55,7 +55,7 @@ var (
// Capture new values for the Go runtime statistics exported in
// runtime.MemStats. This is designed to be called as a goroutine.
func CaptureRuntimeMemStats(r Registry, d time.Duration) {
- for _ = range time.Tick(d) {
+ for range time.Tick(d) {
CaptureRuntimeMemStatsOnce(r)
}
}
diff --git a/vendor/github.com/rcrowley/go-metrics/syslog.go b/vendor/github.com/rcrowley/go-metrics/syslog.go
index 693f190855c1..a0ed4b1b2364 100644
--- a/vendor/github.com/rcrowley/go-metrics/syslog.go
+++ b/vendor/github.com/rcrowley/go-metrics/syslog.go
@@ -11,7 +11,7 @@ import (
// Output each metric in the given registry to syslog periodically using
// the given syslogger.
func Syslog(r Registry, d time.Duration, w *syslog.Writer) {
- for _ = range time.Tick(d) {
+ for range time.Tick(d) {
r.Each(func(name string, i interface{}) {
switch metric := i.(type) {
case Counter:
diff --git a/vendor/github.com/rcrowley/go-metrics/writer.go b/vendor/github.com/rcrowley/go-metrics/writer.go
index 091e971d2e6f..88521a80d9d7 100644
--- a/vendor/github.com/rcrowley/go-metrics/writer.go
+++ b/vendor/github.com/rcrowley/go-metrics/writer.go
@@ -10,7 +10,7 @@ import (
// Write sorts writes each metric in the given registry periodically to the
// given io.Writer.
func Write(r Registry, d time.Duration, w io.Writer) {
- for _ = range time.Tick(d) {
+ for range time.Tick(d) {
WriteOnce(r, w)
}
}
diff --git a/vendor/github.com/robertkrimen/otto/builtin_json.go b/vendor/github.com/robertkrimen/otto/builtin_json.go
index aed54bf1264f..4f41ef346a4e 100644
--- a/vendor/github.com/robertkrimen/otto/builtin_json.go
+++ b/vendor/github.com/robertkrimen/otto/builtin_json.go
@@ -118,7 +118,7 @@ func builtinJSON_stringify(call FunctionCall) Value {
seen := map[string]bool{}
propertyList := make([]string, length)
length = 0
- for index, _ := range propertyList {
+ for index := range propertyList {
value := replacer.get(arrayIndexToString(int64(index)))
switch value.kind {
case valueObject:
@@ -266,7 +266,7 @@ func builtinJSON_stringifyWalk(ctx _builtinJSON_stringifyContext, key string, ho
panic(ctx.call.runtime.panicTypeError(fmt.Sprintf("JSON.stringify: invalid length: %v (%[1]T)", value)))
}
array := make([]interface{}, length)
- for index, _ := range array {
+ for index := range array {
name := arrayIndexToString(int64(index))
value, _ := builtinJSON_stringifyWalk(ctx, name, holder)
array[index] = value
diff --git a/vendor/github.com/robertkrimen/otto/builtin_string.go b/vendor/github.com/robertkrimen/otto/builtin_string.go
index 6a17184589dd..af19dcaddc6d 100644
--- a/vendor/github.com/robertkrimen/otto/builtin_string.go
+++ b/vendor/github.com/robertkrimen/otto/builtin_string.go
@@ -171,7 +171,7 @@ func builtinString_findAndReplaceString(input []byte, lastIndex int, match []int
case '`':
return target[:match[0]]
case '\'':
- return target[match[1]:len(target)]
+ return target[match[1]:]
}
matchNumberParse, error := strconv.ParseInt(string(part[1:]), 10, 64)
matchNumber := int(matchNumberParse)
diff --git a/vendor/github.com/robertkrimen/otto/cmpl_evaluate.go b/vendor/github.com/robertkrimen/otto/cmpl_evaluate.go
index 6741bf394553..74048bf5b0b5 100644
--- a/vendor/github.com/robertkrimen/otto/cmpl_evaluate.go
+++ b/vendor/github.com/robertkrimen/otto/cmpl_evaluate.go
@@ -46,7 +46,7 @@ func (self *_runtime) cmpl_call_nodeFunction(function *_object, stash *_fnStash,
stash.arguments = arguments
// strict = false
self.scope.lexical.setValue("arguments", toValue_object(arguments), false)
- for index, _ := range argumentList {
+ for index := range argumentList {
if index < len(node.parameterList) {
continue
}
diff --git a/vendor/github.com/robertkrimen/otto/inline.go b/vendor/github.com/robertkrimen/otto/inline.go
index 6e5df8393ee1..5d31aa39cd62 100644
--- a/vendor/github.com/robertkrimen/otto/inline.go
+++ b/vendor/github.com/robertkrimen/otto/inline.go
@@ -33,7 +33,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -56,7 +56,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -79,7 +79,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -102,7 +102,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -125,7 +125,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -148,7 +148,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -165,49 +165,49 @@ func _newContext(runtime *_runtime) {
},
}
runtime.global.ObjectPrototype.property = map[string]_property{
- "valueOf": _property{
+ "valueOf": {
mode: 0101,
value: Value{
kind: valueObject,
value: valueOf_function,
},
},
- "toString": _property{
+ "toString": {
mode: 0101,
value: Value{
kind: valueObject,
value: toString_function,
},
},
- "toLocaleString": _property{
+ "toLocaleString": {
mode: 0101,
value: Value{
kind: valueObject,
value: toLocaleString_function,
},
},
- "hasOwnProperty": _property{
+ "hasOwnProperty": {
mode: 0101,
value: Value{
kind: valueObject,
value: hasOwnProperty_function,
},
},
- "isPrototypeOf": _property{
+ "isPrototypeOf": {
mode: 0101,
value: Value{
kind: valueObject,
value: isPrototypeOf_function,
},
},
- "propertyIsEnumerable": _property{
+ "propertyIsEnumerable": {
mode: 0101,
value: Value{
kind: valueObject,
value: propertyIsEnumerable_function,
},
},
- "constructor": _property{
+ "constructor": {
mode: 0101,
value: Value{},
},
@@ -230,7 +230,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -253,7 +253,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -276,7 +276,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -299,7 +299,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -316,39 +316,39 @@ func _newContext(runtime *_runtime) {
},
}
runtime.global.FunctionPrototype.property = map[string]_property{
- "toString": _property{
+ "toString": {
mode: 0101,
value: Value{
kind: valueObject,
value: toString_function,
},
},
- "apply": _property{
+ "apply": {
mode: 0101,
value: Value{
kind: valueObject,
value: apply_function,
},
},
- "call": _property{
+ "call": {
mode: 0101,
value: Value{
kind: valueObject,
value: call_function,
},
},
- "bind": _property{
+ "bind": {
mode: 0101,
value: Value{
kind: valueObject,
value: bind_function,
},
},
- "constructor": _property{
+ "constructor": {
mode: 0101,
value: Value{},
},
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -373,7 +373,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -396,7 +396,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -419,7 +419,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -442,7 +442,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -465,7 +465,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -488,7 +488,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -511,7 +511,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -534,7 +534,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -557,7 +557,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -580,7 +580,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -603,7 +603,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -626,7 +626,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -649,7 +649,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -677,105 +677,105 @@ func _newContext(runtime *_runtime) {
construct: builtinNewObject,
},
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
value: 1,
},
},
- "prototype": _property{
+ "prototype": {
mode: 0,
value: Value{
kind: valueObject,
value: runtime.global.ObjectPrototype,
},
},
- "getPrototypeOf": _property{
+ "getPrototypeOf": {
mode: 0101,
value: Value{
kind: valueObject,
value: getPrototypeOf_function,
},
},
- "getOwnPropertyDescriptor": _property{
+ "getOwnPropertyDescriptor": {
mode: 0101,
value: Value{
kind: valueObject,
value: getOwnPropertyDescriptor_function,
},
},
- "defineProperty": _property{
+ "defineProperty": {
mode: 0101,
value: Value{
kind: valueObject,
value: defineProperty_function,
},
},
- "defineProperties": _property{
+ "defineProperties": {
mode: 0101,
value: Value{
kind: valueObject,
value: defineProperties_function,
},
},
- "create": _property{
+ "create": {
mode: 0101,
value: Value{
kind: valueObject,
value: create_function,
},
},
- "isExtensible": _property{
+ "isExtensible": {
mode: 0101,
value: Value{
kind: valueObject,
value: isExtensible_function,
},
},
- "preventExtensions": _property{
+ "preventExtensions": {
mode: 0101,
value: Value{
kind: valueObject,
value: preventExtensions_function,
},
},
- "isSealed": _property{
+ "isSealed": {
mode: 0101,
value: Value{
kind: valueObject,
value: isSealed_function,
},
},
- "seal": _property{
+ "seal": {
mode: 0101,
value: Value{
kind: valueObject,
value: seal_function,
},
},
- "isFrozen": _property{
+ "isFrozen": {
mode: 0101,
value: Value{
kind: valueObject,
value: isFrozen_function,
},
},
- "freeze": _property{
+ "freeze": {
mode: 0101,
value: Value{
kind: valueObject,
value: freeze_function,
},
},
- "keys": _property{
+ "keys": {
mode: 0101,
value: Value{
kind: valueObject,
value: keys_function,
},
},
- "getOwnPropertyNames": _property{
+ "getOwnPropertyNames": {
mode: 0101,
value: Value{
kind: valueObject,
@@ -823,14 +823,14 @@ func _newContext(runtime *_runtime) {
construct: builtinNewFunction,
},
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
value: 1,
},
},
- "prototype": _property{
+ "prototype": {
mode: 0,
value: Value{
kind: valueObject,
@@ -861,7 +861,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -884,7 +884,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -907,7 +907,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -930,7 +930,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -953,7 +953,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -976,7 +976,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -999,7 +999,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1022,7 +1022,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1045,7 +1045,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1068,7 +1068,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1091,7 +1091,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1114,7 +1114,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1137,7 +1137,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1160,7 +1160,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1183,7 +1183,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1206,7 +1206,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1229,7 +1229,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1252,7 +1252,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1275,7 +1275,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1298,7 +1298,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1321,7 +1321,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1344,7 +1344,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1368,154 +1368,154 @@ func _newContext(runtime *_runtime) {
extensible: true,
value: nil,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0100,
value: Value{
kind: valueNumber,
value: uint32(0),
},
},
- "toString": _property{
+ "toString": {
mode: 0101,
value: Value{
kind: valueObject,
value: toString_function,
},
},
- "toLocaleString": _property{
+ "toLocaleString": {
mode: 0101,
value: Value{
kind: valueObject,
value: toLocaleString_function,
},
},
- "concat": _property{
+ "concat": {
mode: 0101,
value: Value{
kind: valueObject,
value: concat_function,
},
},
- "join": _property{
+ "join": {
mode: 0101,
value: Value{
kind: valueObject,
value: join_function,
},
},
- "splice": _property{
+ "splice": {
mode: 0101,
value: Value{
kind: valueObject,
value: splice_function,
},
},
- "shift": _property{
+ "shift": {
mode: 0101,
value: Value{
kind: valueObject,
value: shift_function,
},
},
- "pop": _property{
+ "pop": {
mode: 0101,
value: Value{
kind: valueObject,
value: pop_function,
},
},
- "push": _property{
+ "push": {
mode: 0101,
value: Value{
kind: valueObject,
value: push_function,
},
},
- "slice": _property{
+ "slice": {
mode: 0101,
value: Value{
kind: valueObject,
value: slice_function,
},
},
- "unshift": _property{
+ "unshift": {
mode: 0101,
value: Value{
kind: valueObject,
value: unshift_function,
},
},
- "reverse": _property{
+ "reverse": {
mode: 0101,
value: Value{
kind: valueObject,
value: reverse_function,
},
},
- "sort": _property{
+ "sort": {
mode: 0101,
value: Value{
kind: valueObject,
value: sort_function,
},
},
- "indexOf": _property{
+ "indexOf": {
mode: 0101,
value: Value{
kind: valueObject,
value: indexOf_function,
},
},
- "lastIndexOf": _property{
+ "lastIndexOf": {
mode: 0101,
value: Value{
kind: valueObject,
value: lastIndexOf_function,
},
},
- "every": _property{
+ "every": {
mode: 0101,
value: Value{
kind: valueObject,
value: every_function,
},
},
- "some": _property{
+ "some": {
mode: 0101,
value: Value{
kind: valueObject,
value: some_function,
},
},
- "forEach": _property{
+ "forEach": {
mode: 0101,
value: Value{
kind: valueObject,
value: forEach_function,
},
},
- "map": _property{
+ "map": {
mode: 0101,
value: Value{
kind: valueObject,
value: map_function,
},
},
- "filter": _property{
+ "filter": {
mode: 0101,
value: Value{
kind: valueObject,
value: filter_function,
},
},
- "reduce": _property{
+ "reduce": {
mode: 0101,
value: Value{
kind: valueObject,
value: reduce_function,
},
},
- "reduceRight": _property{
+ "reduceRight": {
mode: 0101,
value: Value{
kind: valueObject,
@@ -1560,21 +1560,21 @@ func _newContext(runtime *_runtime) {
construct: builtinNewArray,
},
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
value: 1,
},
},
- "prototype": _property{
+ "prototype": {
mode: 0,
value: Value{
kind: valueObject,
value: runtime.global.ArrayPrototype,
},
},
- "isArray": _property{
+ "isArray": {
mode: 0101,
value: Value{
kind: valueObject,
@@ -1605,7 +1605,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1628,7 +1628,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1651,7 +1651,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1674,7 +1674,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1697,7 +1697,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1720,7 +1720,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1743,7 +1743,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1766,7 +1766,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1789,7 +1789,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1812,7 +1812,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1835,7 +1835,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1858,7 +1858,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1881,7 +1881,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1904,7 +1904,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1927,7 +1927,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1950,7 +1950,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1973,7 +1973,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -1996,7 +1996,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2019,7 +2019,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2042,7 +2042,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2065,7 +2065,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2088,7 +2088,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2111,7 +2111,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2135,161 +2135,161 @@ func _newContext(runtime *_runtime) {
extensible: true,
value: prototypeValueString,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
value: int(0),
},
},
- "toString": _property{
+ "toString": {
mode: 0101,
value: Value{
kind: valueObject,
value: toString_function,
},
},
- "valueOf": _property{
+ "valueOf": {
mode: 0101,
value: Value{
kind: valueObject,
value: valueOf_function,
},
},
- "charAt": _property{
+ "charAt": {
mode: 0101,
value: Value{
kind: valueObject,
value: charAt_function,
},
},
- "charCodeAt": _property{
+ "charCodeAt": {
mode: 0101,
value: Value{
kind: valueObject,
value: charCodeAt_function,
},
},
- "concat": _property{
+ "concat": {
mode: 0101,
value: Value{
kind: valueObject,
value: concat_function,
},
},
- "indexOf": _property{
+ "indexOf": {
mode: 0101,
value: Value{
kind: valueObject,
value: indexOf_function,
},
},
- "lastIndexOf": _property{
+ "lastIndexOf": {
mode: 0101,
value: Value{
kind: valueObject,
value: lastIndexOf_function,
},
},
- "match": _property{
+ "match": {
mode: 0101,
value: Value{
kind: valueObject,
value: match_function,
},
},
- "replace": _property{
+ "replace": {
mode: 0101,
value: Value{
kind: valueObject,
value: replace_function,
},
},
- "search": _property{
+ "search": {
mode: 0101,
value: Value{
kind: valueObject,
value: search_function,
},
},
- "split": _property{
+ "split": {
mode: 0101,
value: Value{
kind: valueObject,
value: split_function,
},
},
- "slice": _property{
+ "slice": {
mode: 0101,
value: Value{
kind: valueObject,
value: slice_function,
},
},
- "substring": _property{
+ "substring": {
mode: 0101,
value: Value{
kind: valueObject,
value: substring_function,
},
},
- "toLowerCase": _property{
+ "toLowerCase": {
mode: 0101,
value: Value{
kind: valueObject,
value: toLowerCase_function,
},
},
- "toUpperCase": _property{
+ "toUpperCase": {
mode: 0101,
value: Value{
kind: valueObject,
value: toUpperCase_function,
},
},
- "substr": _property{
+ "substr": {
mode: 0101,
value: Value{
kind: valueObject,
value: substr_function,
},
},
- "trim": _property{
+ "trim": {
mode: 0101,
value: Value{
kind: valueObject,
value: trim_function,
},
},
- "trimLeft": _property{
+ "trimLeft": {
mode: 0101,
value: Value{
kind: valueObject,
value: trimLeft_function,
},
},
- "trimRight": _property{
+ "trimRight": {
mode: 0101,
value: Value{
kind: valueObject,
value: trimRight_function,
},
},
- "localeCompare": _property{
+ "localeCompare": {
mode: 0101,
value: Value{
kind: valueObject,
value: localeCompare_function,
},
},
- "toLocaleLowerCase": _property{
+ "toLocaleLowerCase": {
mode: 0101,
value: Value{
kind: valueObject,
value: toLocaleLowerCase_function,
},
},
- "toLocaleUpperCase": _property{
+ "toLocaleUpperCase": {
mode: 0101,
value: Value{
kind: valueObject,
@@ -2335,21 +2335,21 @@ func _newContext(runtime *_runtime) {
construct: builtinNewString,
},
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
value: 1,
},
},
- "prototype": _property{
+ "prototype": {
mode: 0,
value: Value{
kind: valueObject,
value: runtime.global.StringPrototype,
},
},
- "fromCharCode": _property{
+ "fromCharCode": {
mode: 0101,
value: Value{
kind: valueObject,
@@ -2380,7 +2380,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2403,7 +2403,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2427,14 +2427,14 @@ func _newContext(runtime *_runtime) {
extensible: true,
value: prototypeValueBoolean,
property: map[string]_property{
- "toString": _property{
+ "toString": {
mode: 0101,
value: Value{
kind: valueObject,
value: toString_function,
},
},
- "valueOf": _property{
+ "valueOf": {
mode: 0101,
value: Value{
kind: valueObject,
@@ -2459,14 +2459,14 @@ func _newContext(runtime *_runtime) {
construct: builtinNewBoolean,
},
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
value: 1,
},
},
- "prototype": _property{
+ "prototype": {
mode: 0,
value: Value{
kind: valueObject,
@@ -2496,7 +2496,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2519,7 +2519,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2542,7 +2542,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2565,7 +2565,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2588,7 +2588,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2611,7 +2611,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2635,42 +2635,42 @@ func _newContext(runtime *_runtime) {
extensible: true,
value: prototypeValueNumber,
property: map[string]_property{
- "toString": _property{
+ "toString": {
mode: 0101,
value: Value{
kind: valueObject,
value: toString_function,
},
},
- "valueOf": _property{
+ "valueOf": {
mode: 0101,
value: Value{
kind: valueObject,
value: valueOf_function,
},
},
- "toFixed": _property{
+ "toFixed": {
mode: 0101,
value: Value{
kind: valueObject,
value: toFixed_function,
},
},
- "toExponential": _property{
+ "toExponential": {
mode: 0101,
value: Value{
kind: valueObject,
value: toExponential_function,
},
},
- "toPrecision": _property{
+ "toPrecision": {
mode: 0101,
value: Value{
kind: valueObject,
value: toPrecision_function,
},
},
- "toLocaleString": _property{
+ "toLocaleString": {
mode: 0101,
value: Value{
kind: valueObject,
@@ -2699,49 +2699,49 @@ func _newContext(runtime *_runtime) {
construct: builtinNewNumber,
},
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
value: 1,
},
},
- "prototype": _property{
+ "prototype": {
mode: 0,
value: Value{
kind: valueObject,
value: runtime.global.NumberPrototype,
},
},
- "MAX_VALUE": _property{
+ "MAX_VALUE": {
mode: 0,
value: Value{
kind: valueNumber,
value: math.MaxFloat64,
},
},
- "MIN_VALUE": _property{
+ "MIN_VALUE": {
mode: 0,
value: Value{
kind: valueNumber,
value: math.SmallestNonzeroFloat64,
},
},
- "NaN": _property{
+ "NaN": {
mode: 0,
value: Value{
kind: valueNumber,
value: math.NaN(),
},
},
- "NEGATIVE_INFINITY": _property{
+ "NEGATIVE_INFINITY": {
mode: 0,
value: Value{
kind: valueNumber,
value: math.Inf(-1),
},
},
- "POSITIVE_INFINITY": _property{
+ "POSITIVE_INFINITY": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2776,7 +2776,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2799,7 +2799,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2822,7 +2822,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2845,7 +2845,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2868,7 +2868,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2891,7 +2891,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2914,7 +2914,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2937,7 +2937,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2960,7 +2960,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -2983,7 +2983,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3006,7 +3006,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3029,7 +3029,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3052,7 +3052,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3075,7 +3075,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3098,7 +3098,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3121,7 +3121,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3144,7 +3144,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3167,7 +3167,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3190,182 +3190,182 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.ObjectPrototype,
extensible: true,
property: map[string]_property{
- "abs": _property{
+ "abs": {
mode: 0101,
value: Value{
kind: valueObject,
value: abs_function,
},
},
- "acos": _property{
+ "acos": {
mode: 0101,
value: Value{
kind: valueObject,
value: acos_function,
},
},
- "asin": _property{
+ "asin": {
mode: 0101,
value: Value{
kind: valueObject,
value: asin_function,
},
},
- "atan": _property{
+ "atan": {
mode: 0101,
value: Value{
kind: valueObject,
value: atan_function,
},
},
- "atan2": _property{
+ "atan2": {
mode: 0101,
value: Value{
kind: valueObject,
value: atan2_function,
},
},
- "ceil": _property{
+ "ceil": {
mode: 0101,
value: Value{
kind: valueObject,
value: ceil_function,
},
},
- "cos": _property{
+ "cos": {
mode: 0101,
value: Value{
kind: valueObject,
value: cos_function,
},
},
- "exp": _property{
+ "exp": {
mode: 0101,
value: Value{
kind: valueObject,
value: exp_function,
},
},
- "floor": _property{
+ "floor": {
mode: 0101,
value: Value{
kind: valueObject,
value: floor_function,
},
},
- "log": _property{
+ "log": {
mode: 0101,
value: Value{
kind: valueObject,
value: log_function,
},
},
- "max": _property{
+ "max": {
mode: 0101,
value: Value{
kind: valueObject,
value: max_function,
},
},
- "min": _property{
+ "min": {
mode: 0101,
value: Value{
kind: valueObject,
value: min_function,
},
},
- "pow": _property{
+ "pow": {
mode: 0101,
value: Value{
kind: valueObject,
value: pow_function,
},
},
- "random": _property{
+ "random": {
mode: 0101,
value: Value{
kind: valueObject,
value: random_function,
},
},
- "round": _property{
+ "round": {
mode: 0101,
value: Value{
kind: valueObject,
value: round_function,
},
},
- "sin": _property{
+ "sin": {
mode: 0101,
value: Value{
kind: valueObject,
value: sin_function,
},
},
- "sqrt": _property{
+ "sqrt": {
mode: 0101,
value: Value{
kind: valueObject,
value: sqrt_function,
},
},
- "tan": _property{
+ "tan": {
mode: 0101,
value: Value{
kind: valueObject,
value: tan_function,
},
},
- "E": _property{
+ "E": {
mode: 0,
value: Value{
kind: valueNumber,
value: math.E,
},
},
- "LN10": _property{
+ "LN10": {
mode: 0,
value: Value{
kind: valueNumber,
value: math.Ln10,
},
},
- "LN2": _property{
+ "LN2": {
mode: 0,
value: Value{
kind: valueNumber,
value: math.Ln2,
},
},
- "LOG2E": _property{
+ "LOG2E": {
mode: 0,
value: Value{
kind: valueNumber,
value: math.Log2E,
},
},
- "LOG10E": _property{
+ "LOG10E": {
mode: 0,
value: Value{
kind: valueNumber,
value: math.Log10E,
},
},
- "PI": _property{
+ "PI": {
mode: 0,
value: Value{
kind: valueNumber,
value: math.Pi,
},
},
- "SQRT1_2": _property{
+ "SQRT1_2": {
mode: 0,
value: Value{
kind: valueNumber,
value: sqrt1_2,
},
},
- "SQRT2": _property{
+ "SQRT2": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3411,7 +3411,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3434,7 +3434,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3457,7 +3457,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3480,7 +3480,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3503,7 +3503,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3526,7 +3526,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3549,7 +3549,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3572,7 +3572,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3595,7 +3595,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3618,7 +3618,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3641,7 +3641,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3664,7 +3664,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3687,7 +3687,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3710,7 +3710,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3733,7 +3733,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3756,7 +3756,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3779,7 +3779,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3802,7 +3802,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3825,7 +3825,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3848,7 +3848,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3871,7 +3871,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3894,7 +3894,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3917,7 +3917,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3940,7 +3940,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3963,7 +3963,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -3986,7 +3986,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4009,7 +4009,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4032,7 +4032,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4055,7 +4055,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4078,7 +4078,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4101,7 +4101,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4124,7 +4124,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4147,7 +4147,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4170,7 +4170,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4193,7 +4193,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4216,7 +4216,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4239,7 +4239,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4262,7 +4262,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4285,7 +4285,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4308,7 +4308,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4331,7 +4331,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4354,7 +4354,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4377,7 +4377,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4400,7 +4400,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4423,7 +4423,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4446,7 +4446,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4469,7 +4469,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4492,7 +4492,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4515,7 +4515,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -4539,322 +4539,322 @@ func _newContext(runtime *_runtime) {
extensible: true,
value: prototypeValueDate,
property: map[string]_property{
- "toString": _property{
+ "toString": {
mode: 0101,
value: Value{
kind: valueObject,
value: toString_function,
},
},
- "toDateString": _property{
+ "toDateString": {
mode: 0101,
value: Value{
kind: valueObject,
value: toDateString_function,
},
},
- "toTimeString": _property{
+ "toTimeString": {
mode: 0101,
value: Value{
kind: valueObject,
value: toTimeString_function,
},
},
- "toUTCString": _property{
+ "toUTCString": {
mode: 0101,
value: Value{
kind: valueObject,
value: toUTCString_function,
},
},
- "toISOString": _property{
+ "toISOString": {
mode: 0101,
value: Value{
kind: valueObject,
value: toISOString_function,
},
},
- "toJSON": _property{
+ "toJSON": {
mode: 0101,
value: Value{
kind: valueObject,
value: toJSON_function,
},
},
- "toGMTString": _property{
+ "toGMTString": {
mode: 0101,
value: Value{
kind: valueObject,
value: toGMTString_function,
},
},
- "toLocaleString": _property{
+ "toLocaleString": {
mode: 0101,
value: Value{
kind: valueObject,
value: toLocaleString_function,
},
},
- "toLocaleDateString": _property{
+ "toLocaleDateString": {
mode: 0101,
value: Value{
kind: valueObject,
value: toLocaleDateString_function,
},
},
- "toLocaleTimeString": _property{
+ "toLocaleTimeString": {
mode: 0101,
value: Value{
kind: valueObject,
value: toLocaleTimeString_function,
},
},
- "valueOf": _property{
+ "valueOf": {
mode: 0101,
value: Value{
kind: valueObject,
value: valueOf_function,
},
},
- "getTime": _property{
+ "getTime": {
mode: 0101,
value: Value{
kind: valueObject,
value: getTime_function,
},
},
- "getYear": _property{
+ "getYear": {
mode: 0101,
value: Value{
kind: valueObject,
value: getYear_function,
},
},
- "getFullYear": _property{
+ "getFullYear": {
mode: 0101,
value: Value{
kind: valueObject,
value: getFullYear_function,
},
},
- "getUTCFullYear": _property{
+ "getUTCFullYear": {
mode: 0101,
value: Value{
kind: valueObject,
value: getUTCFullYear_function,
},
},
- "getMonth": _property{
+ "getMonth": {
mode: 0101,
value: Value{
kind: valueObject,
value: getMonth_function,
},
},
- "getUTCMonth": _property{
+ "getUTCMonth": {
mode: 0101,
value: Value{
kind: valueObject,
value: getUTCMonth_function,
},
},
- "getDate": _property{
+ "getDate": {
mode: 0101,
value: Value{
kind: valueObject,
value: getDate_function,
},
},
- "getUTCDate": _property{
+ "getUTCDate": {
mode: 0101,
value: Value{
kind: valueObject,
value: getUTCDate_function,
},
},
- "getDay": _property{
+ "getDay": {
mode: 0101,
value: Value{
kind: valueObject,
value: getDay_function,
},
},
- "getUTCDay": _property{
+ "getUTCDay": {
mode: 0101,
value: Value{
kind: valueObject,
value: getUTCDay_function,
},
},
- "getHours": _property{
+ "getHours": {
mode: 0101,
value: Value{
kind: valueObject,
value: getHours_function,
},
},
- "getUTCHours": _property{
+ "getUTCHours": {
mode: 0101,
value: Value{
kind: valueObject,
value: getUTCHours_function,
},
},
- "getMinutes": _property{
+ "getMinutes": {
mode: 0101,
value: Value{
kind: valueObject,
value: getMinutes_function,
},
},
- "getUTCMinutes": _property{
+ "getUTCMinutes": {
mode: 0101,
value: Value{
kind: valueObject,
value: getUTCMinutes_function,
},
},
- "getSeconds": _property{
+ "getSeconds": {
mode: 0101,
value: Value{
kind: valueObject,
value: getSeconds_function,
},
},
- "getUTCSeconds": _property{
+ "getUTCSeconds": {
mode: 0101,
value: Value{
kind: valueObject,
value: getUTCSeconds_function,
},
},
- "getMilliseconds": _property{
+ "getMilliseconds": {
mode: 0101,
value: Value{
kind: valueObject,
value: getMilliseconds_function,
},
},
- "getUTCMilliseconds": _property{
+ "getUTCMilliseconds": {
mode: 0101,
value: Value{
kind: valueObject,
value: getUTCMilliseconds_function,
},
},
- "getTimezoneOffset": _property{
+ "getTimezoneOffset": {
mode: 0101,
value: Value{
kind: valueObject,
value: getTimezoneOffset_function,
},
},
- "setTime": _property{
+ "setTime": {
mode: 0101,
value: Value{
kind: valueObject,
value: setTime_function,
},
},
- "setMilliseconds": _property{
+ "setMilliseconds": {
mode: 0101,
value: Value{
kind: valueObject,
value: setMilliseconds_function,
},
},
- "setUTCMilliseconds": _property{
+ "setUTCMilliseconds": {
mode: 0101,
value: Value{
kind: valueObject,
value: setUTCMilliseconds_function,
},
},
- "setSeconds": _property{
+ "setSeconds": {
mode: 0101,
value: Value{
kind: valueObject,
value: setSeconds_function,
},
},
- "setUTCSeconds": _property{
+ "setUTCSeconds": {
mode: 0101,
value: Value{
kind: valueObject,
value: setUTCSeconds_function,
},
},
- "setMinutes": _property{
+ "setMinutes": {
mode: 0101,
value: Value{
kind: valueObject,
value: setMinutes_function,
},
},
- "setUTCMinutes": _property{
+ "setUTCMinutes": {
mode: 0101,
value: Value{
kind: valueObject,
value: setUTCMinutes_function,
},
},
- "setHours": _property{
+ "setHours": {
mode: 0101,
value: Value{
kind: valueObject,
value: setHours_function,
},
},
- "setUTCHours": _property{
+ "setUTCHours": {
mode: 0101,
value: Value{
kind: valueObject,
value: setUTCHours_function,
},
},
- "setDate": _property{
+ "setDate": {
mode: 0101,
value: Value{
kind: valueObject,
value: setDate_function,
},
},
- "setUTCDate": _property{
+ "setUTCDate": {
mode: 0101,
value: Value{
kind: valueObject,
value: setUTCDate_function,
},
},
- "setMonth": _property{
+ "setMonth": {
mode: 0101,
value: Value{
kind: valueObject,
value: setMonth_function,
},
},
- "setUTCMonth": _property{
+ "setUTCMonth": {
mode: 0101,
value: Value{
kind: valueObject,
value: setUTCMonth_function,
},
},
- "setYear": _property{
+ "setYear": {
mode: 0101,
value: Value{
kind: valueObject,
value: setYear_function,
},
},
- "setFullYear": _property{
+ "setFullYear": {
mode: 0101,
value: Value{
kind: valueObject,
value: setFullYear_function,
},
},
- "setUTCFullYear": _property{
+ "setUTCFullYear": {
mode: 0101,
value: Value{
kind: valueObject,
@@ -4923,35 +4923,35 @@ func _newContext(runtime *_runtime) {
construct: builtinNewDate,
},
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
value: 7,
},
},
- "prototype": _property{
+ "prototype": {
mode: 0,
value: Value{
kind: valueObject,
value: runtime.global.DatePrototype,
},
},
- "parse": _property{
+ "parse": {
mode: 0101,
value: Value{
kind: valueObject,
value: parse_function,
},
},
- "UTC": _property{
+ "UTC": {
mode: 0101,
value: Value{
kind: valueObject,
value: UTC_function,
},
},
- "now": _property{
+ "now": {
mode: 0101,
value: Value{
kind: valueObject,
@@ -4984,7 +4984,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -5007,7 +5007,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -5030,7 +5030,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -5053,7 +5053,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -5077,28 +5077,28 @@ func _newContext(runtime *_runtime) {
extensible: true,
value: prototypeValueRegExp,
property: map[string]_property{
- "toString": _property{
+ "toString": {
mode: 0101,
value: Value{
kind: valueObject,
value: toString_function,
},
},
- "exec": _property{
+ "exec": {
mode: 0101,
value: Value{
kind: valueObject,
value: exec_function,
},
},
- "test": _property{
+ "test": {
mode: 0101,
value: Value{
kind: valueObject,
value: test_function,
},
},
- "compile": _property{
+ "compile": {
mode: 0101,
value: Value{
kind: valueObject,
@@ -5125,14 +5125,14 @@ func _newContext(runtime *_runtime) {
construct: builtinNewRegExp,
},
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
value: 2,
},
},
- "prototype": _property{
+ "prototype": {
mode: 0,
value: Value{
kind: valueObject,
@@ -5162,7 +5162,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -5186,21 +5186,21 @@ func _newContext(runtime *_runtime) {
extensible: true,
value: nil,
property: map[string]_property{
- "toString": _property{
+ "toString": {
mode: 0101,
value: Value{
kind: valueObject,
value: toString_function,
},
},
- "name": _property{
+ "name": {
mode: 0101,
value: Value{
kind: valueString,
value: "Error",
},
},
- "message": _property{
+ "message": {
mode: 0101,
value: Value{
kind: valueString,
@@ -5226,14 +5226,14 @@ func _newContext(runtime *_runtime) {
construct: builtinNewError,
},
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
value: 1,
},
},
- "prototype": _property{
+ "prototype": {
mode: 0,
value: Value{
kind: valueObject,
@@ -5264,7 +5264,7 @@ func _newContext(runtime *_runtime) {
extensible: true,
value: nil,
property: map[string]_property{
- "name": _property{
+ "name": {
mode: 0101,
value: Value{
kind: valueString,
@@ -5288,14 +5288,14 @@ func _newContext(runtime *_runtime) {
construct: builtinNewEvalError,
},
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
value: 1,
},
},
- "prototype": _property{
+ "prototype": {
mode: 0,
value: Value{
kind: valueObject,
@@ -5326,7 +5326,7 @@ func _newContext(runtime *_runtime) {
extensible: true,
value: nil,
property: map[string]_property{
- "name": _property{
+ "name": {
mode: 0101,
value: Value{
kind: valueString,
@@ -5350,14 +5350,14 @@ func _newContext(runtime *_runtime) {
construct: builtinNewTypeError,
},
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
value: 1,
},
},
- "prototype": _property{
+ "prototype": {
mode: 0,
value: Value{
kind: valueObject,
@@ -5388,7 +5388,7 @@ func _newContext(runtime *_runtime) {
extensible: true,
value: nil,
property: map[string]_property{
- "name": _property{
+ "name": {
mode: 0101,
value: Value{
kind: valueString,
@@ -5412,14 +5412,14 @@ func _newContext(runtime *_runtime) {
construct: builtinNewRangeError,
},
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
value: 1,
},
},
- "prototype": _property{
+ "prototype": {
mode: 0,
value: Value{
kind: valueObject,
@@ -5450,7 +5450,7 @@ func _newContext(runtime *_runtime) {
extensible: true,
value: nil,
property: map[string]_property{
- "name": _property{
+ "name": {
mode: 0101,
value: Value{
kind: valueString,
@@ -5474,14 +5474,14 @@ func _newContext(runtime *_runtime) {
construct: builtinNewReferenceError,
},
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
value: 1,
},
},
- "prototype": _property{
+ "prototype": {
mode: 0,
value: Value{
kind: valueObject,
@@ -5512,7 +5512,7 @@ func _newContext(runtime *_runtime) {
extensible: true,
value: nil,
property: map[string]_property{
- "name": _property{
+ "name": {
mode: 0101,
value: Value{
kind: valueString,
@@ -5536,14 +5536,14 @@ func _newContext(runtime *_runtime) {
construct: builtinNewSyntaxError,
},
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
value: 1,
},
},
- "prototype": _property{
+ "prototype": {
mode: 0,
value: Value{
kind: valueObject,
@@ -5574,7 +5574,7 @@ func _newContext(runtime *_runtime) {
extensible: true,
value: nil,
property: map[string]_property{
- "name": _property{
+ "name": {
mode: 0101,
value: Value{
kind: valueString,
@@ -5598,14 +5598,14 @@ func _newContext(runtime *_runtime) {
construct: builtinNewURIError,
},
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
value: 1,
},
},
- "prototype": _property{
+ "prototype": {
mode: 0,
value: Value{
kind: valueObject,
@@ -5635,7 +5635,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -5658,7 +5658,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -5681,14 +5681,14 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.ObjectPrototype,
extensible: true,
property: map[string]_property{
- "parse": _property{
+ "parse": {
mode: 0101,
value: Value{
kind: valueObject,
value: parse_function,
},
},
- "stringify": _property{
+ "stringify": {
mode: 0101,
value: Value{
kind: valueObject,
@@ -5710,7 +5710,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -5733,7 +5733,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -5756,7 +5756,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -5779,7 +5779,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -5802,7 +5802,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -5825,7 +5825,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -5848,7 +5848,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -5871,7 +5871,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -5894,7 +5894,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -5917,7 +5917,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -5940,7 +5940,7 @@ func _newContext(runtime *_runtime) {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -5957,216 +5957,216 @@ func _newContext(runtime *_runtime) {
},
}
runtime.globalObject.property = map[string]_property{
- "eval": _property{
+ "eval": {
mode: 0101,
value: Value{
kind: valueObject,
value: eval_function,
},
},
- "parseInt": _property{
+ "parseInt": {
mode: 0101,
value: Value{
kind: valueObject,
value: parseInt_function,
},
},
- "parseFloat": _property{
+ "parseFloat": {
mode: 0101,
value: Value{
kind: valueObject,
value: parseFloat_function,
},
},
- "isNaN": _property{
+ "isNaN": {
mode: 0101,
value: Value{
kind: valueObject,
value: isNaN_function,
},
},
- "isFinite": _property{
+ "isFinite": {
mode: 0101,
value: Value{
kind: valueObject,
value: isFinite_function,
},
},
- "decodeURI": _property{
+ "decodeURI": {
mode: 0101,
value: Value{
kind: valueObject,
value: decodeURI_function,
},
},
- "decodeURIComponent": _property{
+ "decodeURIComponent": {
mode: 0101,
value: Value{
kind: valueObject,
value: decodeURIComponent_function,
},
},
- "encodeURI": _property{
+ "encodeURI": {
mode: 0101,
value: Value{
kind: valueObject,
value: encodeURI_function,
},
},
- "encodeURIComponent": _property{
+ "encodeURIComponent": {
mode: 0101,
value: Value{
kind: valueObject,
value: encodeURIComponent_function,
},
},
- "escape": _property{
+ "escape": {
mode: 0101,
value: Value{
kind: valueObject,
value: escape_function,
},
},
- "unescape": _property{
+ "unescape": {
mode: 0101,
value: Value{
kind: valueObject,
value: unescape_function,
},
},
- "Object": _property{
+ "Object": {
mode: 0101,
value: Value{
kind: valueObject,
value: runtime.global.Object,
},
},
- "Function": _property{
+ "Function": {
mode: 0101,
value: Value{
kind: valueObject,
value: runtime.global.Function,
},
},
- "Array": _property{
+ "Array": {
mode: 0101,
value: Value{
kind: valueObject,
value: runtime.global.Array,
},
},
- "String": _property{
+ "String": {
mode: 0101,
value: Value{
kind: valueObject,
value: runtime.global.String,
},
},
- "Boolean": _property{
+ "Boolean": {
mode: 0101,
value: Value{
kind: valueObject,
value: runtime.global.Boolean,
},
},
- "Number": _property{
+ "Number": {
mode: 0101,
value: Value{
kind: valueObject,
value: runtime.global.Number,
},
},
- "Math": _property{
+ "Math": {
mode: 0101,
value: Value{
kind: valueObject,
value: runtime.global.Math,
},
},
- "Date": _property{
+ "Date": {
mode: 0101,
value: Value{
kind: valueObject,
value: runtime.global.Date,
},
},
- "RegExp": _property{
+ "RegExp": {
mode: 0101,
value: Value{
kind: valueObject,
value: runtime.global.RegExp,
},
},
- "Error": _property{
+ "Error": {
mode: 0101,
value: Value{
kind: valueObject,
value: runtime.global.Error,
},
},
- "EvalError": _property{
+ "EvalError": {
mode: 0101,
value: Value{
kind: valueObject,
value: runtime.global.EvalError,
},
},
- "TypeError": _property{
+ "TypeError": {
mode: 0101,
value: Value{
kind: valueObject,
value: runtime.global.TypeError,
},
},
- "RangeError": _property{
+ "RangeError": {
mode: 0101,
value: Value{
kind: valueObject,
value: runtime.global.RangeError,
},
},
- "ReferenceError": _property{
+ "ReferenceError": {
mode: 0101,
value: Value{
kind: valueObject,
value: runtime.global.ReferenceError,
},
},
- "SyntaxError": _property{
+ "SyntaxError": {
mode: 0101,
value: Value{
kind: valueObject,
value: runtime.global.SyntaxError,
},
},
- "URIError": _property{
+ "URIError": {
mode: 0101,
value: Value{
kind: valueObject,
value: runtime.global.URIError,
},
},
- "JSON": _property{
+ "JSON": {
mode: 0101,
value: Value{
kind: valueObject,
value: runtime.global.JSON,
},
},
- "undefined": _property{
+ "undefined": {
mode: 0,
value: Value{
kind: valueUndefined,
},
},
- "NaN": _property{
+ "NaN": {
mode: 0,
value: Value{
kind: valueNumber,
value: math.NaN(),
},
},
- "Infinity": _property{
+ "Infinity": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -6219,7 +6219,7 @@ func newConsoleObject(runtime *_runtime) *_object {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -6242,7 +6242,7 @@ func newConsoleObject(runtime *_runtime) *_object {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -6265,7 +6265,7 @@ func newConsoleObject(runtime *_runtime) *_object {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -6288,7 +6288,7 @@ func newConsoleObject(runtime *_runtime) *_object {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -6311,7 +6311,7 @@ func newConsoleObject(runtime *_runtime) *_object {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -6334,7 +6334,7 @@ func newConsoleObject(runtime *_runtime) *_object {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -6357,7 +6357,7 @@ func newConsoleObject(runtime *_runtime) *_object {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -6380,7 +6380,7 @@ func newConsoleObject(runtime *_runtime) *_object {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -6403,7 +6403,7 @@ func newConsoleObject(runtime *_runtime) *_object {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -6426,7 +6426,7 @@ func newConsoleObject(runtime *_runtime) *_object {
prototype: runtime.global.FunctionPrototype,
extensible: true,
property: map[string]_property{
- "length": _property{
+ "length": {
mode: 0,
value: Value{
kind: valueNumber,
@@ -6449,70 +6449,70 @@ func newConsoleObject(runtime *_runtime) *_object {
prototype: runtime.global.ObjectPrototype,
extensible: true,
property: map[string]_property{
- "log": _property{
+ "log": {
mode: 0101,
value: Value{
kind: valueObject,
value: log_function,
},
},
- "debug": _property{
+ "debug": {
mode: 0101,
value: Value{
kind: valueObject,
value: debug_function,
},
},
- "info": _property{
+ "info": {
mode: 0101,
value: Value{
kind: valueObject,
value: info_function,
},
},
- "error": _property{
+ "error": {
mode: 0101,
value: Value{
kind: valueObject,
value: error_function,
},
},
- "warn": _property{
+ "warn": {
mode: 0101,
value: Value{
kind: valueObject,
value: warn_function,
},
},
- "dir": _property{
+ "dir": {
mode: 0101,
value: Value{
kind: valueObject,
value: dir_function,
},
},
- "time": _property{
+ "time": {
mode: 0101,
value: Value{
kind: valueObject,
value: time_function,
},
},
- "timeEnd": _property{
+ "timeEnd": {
mode: 0101,
value: Value{
kind: valueObject,
value: timeEnd_function,
},
},
- "trace": _property{
+ "trace": {
mode: 0101,
value: Value{
kind: valueObject,
value: trace_function,
},
},
- "assert": _property{
+ "assert": {
mode: 0101,
value: Value{
kind: valueObject,
diff --git a/vendor/github.com/robertkrimen/otto/result.go b/vendor/github.com/robertkrimen/otto/result.go
index 63642e7d039e..a8f9b3b185cd 100644
--- a/vendor/github.com/robertkrimen/otto/result.go
+++ b/vendor/github.com/robertkrimen/otto/result.go
@@ -1,7 +1,5 @@
package otto
-import ()
-
type _resultKind int
const (
diff --git a/vendor/github.com/robertkrimen/otto/token/token_const.go b/vendor/github.com/robertkrimen/otto/token/token_const.go
index b1d83c6de9b3..c87959544d21 100644
--- a/vendor/github.com/robertkrimen/otto/token/token_const.go
+++ b/vendor/github.com/robertkrimen/otto/token/token_const.go
@@ -200,148 +200,148 @@ var token2string = [...]string{
}
var keywordTable = map[string]_keyword{
- "if": _keyword{
+ "if": {
token: IF,
},
- "in": _keyword{
+ "in": {
token: IN,
},
- "do": _keyword{
+ "do": {
token: DO,
},
- "var": _keyword{
+ "var": {
token: VAR,
},
- "for": _keyword{
+ "for": {
token: FOR,
},
- "new": _keyword{
+ "new": {
token: NEW,
},
- "try": _keyword{
+ "try": {
token: TRY,
},
- "this": _keyword{
+ "this": {
token: THIS,
},
- "else": _keyword{
+ "else": {
token: ELSE,
},
- "case": _keyword{
+ "case": {
token: CASE,
},
- "void": _keyword{
+ "void": {
token: VOID,
},
- "with": _keyword{
+ "with": {
token: WITH,
},
- "while": _keyword{
+ "while": {
token: WHILE,
},
- "break": _keyword{
+ "break": {
token: BREAK,
},
- "catch": _keyword{
+ "catch": {
token: CATCH,
},
- "throw": _keyword{
+ "throw": {
token: THROW,
},
- "return": _keyword{
+ "return": {
token: RETURN,
},
- "typeof": _keyword{
+ "typeof": {
token: TYPEOF,
},
- "delete": _keyword{
+ "delete": {
token: DELETE,
},
- "switch": _keyword{
+ "switch": {
token: SWITCH,
},
- "default": _keyword{
+ "default": {
token: DEFAULT,
},
- "finally": _keyword{
+ "finally": {
token: FINALLY,
},
- "function": _keyword{
+ "function": {
token: FUNCTION,
},
- "continue": _keyword{
+ "continue": {
token: CONTINUE,
},
- "debugger": _keyword{
+ "debugger": {
token: DEBUGGER,
},
- "instanceof": _keyword{
+ "instanceof": {
token: INSTANCEOF,
},
- "const": _keyword{
+ "const": {
token: KEYWORD,
futureKeyword: true,
},
- "class": _keyword{
+ "class": {
token: KEYWORD,
futureKeyword: true,
},
- "enum": _keyword{
+ "enum": {
token: KEYWORD,
futureKeyword: true,
},
- "export": _keyword{
+ "export": {
token: KEYWORD,
futureKeyword: true,
},
- "extends": _keyword{
+ "extends": {
token: KEYWORD,
futureKeyword: true,
},
- "import": _keyword{
+ "import": {
token: KEYWORD,
futureKeyword: true,
},
- "super": _keyword{
+ "super": {
token: KEYWORD,
futureKeyword: true,
},
- "implements": _keyword{
+ "implements": {
token: KEYWORD,
futureKeyword: true,
strict: true,
},
- "interface": _keyword{
+ "interface": {
token: KEYWORD,
futureKeyword: true,
strict: true,
},
- "let": _keyword{
+ "let": {
token: KEYWORD,
futureKeyword: true,
strict: true,
},
- "package": _keyword{
+ "package": {
token: KEYWORD,
futureKeyword: true,
strict: true,
},
- "private": _keyword{
+ "private": {
token: KEYWORD,
futureKeyword: true,
strict: true,
},
- "protected": _keyword{
+ "protected": {
token: KEYWORD,
futureKeyword: true,
strict: true,
},
- "public": _keyword{
+ "public": {
token: KEYWORD,
futureKeyword: true,
strict: true,
},
- "static": _keyword{
+ "static": {
token: KEYWORD,
futureKeyword: true,
strict: true,
diff --git a/vendor/github.com/robertkrimen/otto/type_arguments.go b/vendor/github.com/robertkrimen/otto/type_arguments.go
index 841d758553b3..2f2906a0e2ec 100644
--- a/vendor/github.com/robertkrimen/otto/type_arguments.go
+++ b/vendor/github.com/robertkrimen/otto/type_arguments.go
@@ -7,7 +7,7 @@ import (
func (runtime *_runtime) newArgumentsObject(indexOfParameterName []string, stash _stash, length int) *_object {
self := runtime.newClassObject("Arguments")
- for index, _ := range indexOfParameterName {
+ for index := range indexOfParameterName {
name := strconv.FormatInt(int64(index), 10)
objectDefineOwnProperty(self, name, _property{Value{}, 0111}, false)
}
diff --git a/vendor/github.com/robertkrimen/otto/type_regexp.go b/vendor/github.com/robertkrimen/otto/type_regexp.go
index 57fe31640591..6ce416b95b1e 100644
--- a/vendor/github.com/robertkrimen/otto/type_regexp.go
+++ b/vendor/github.com/robertkrimen/otto/type_regexp.go
@@ -108,7 +108,7 @@ func execRegExp(this *_object, target string) (match bool, result []int) {
endIndex := int(lastIndex) + result[1]
// We do this shift here because the .FindStringSubmatchIndex above
// was done on a local subordinate slice of the string, not the whole string
- for index, _ := range result {
+ for index := range result {
result[index] += int(startIndex)
}
if global {
diff --git a/vendor/github.com/rs/cors/cors.go b/vendor/github.com/rs/cors/cors.go
index 4bb22d8fcef5..55853dc7ae5e 100644
--- a/vendor/github.com/rs/cors/cors.go
+++ b/vendor/github.com/rs/cors/cors.go
@@ -128,7 +128,7 @@ func New(options Options) *Cors {
break
} else if i := strings.IndexByte(origin, '*'); i >= 0 {
// Split the origin in two: start and end string without the *
- w := wildcard{origin[0:i], origin[i+1 : len(origin)]}
+ w := wildcard{origin[0:i], origin[i+1:]}
c.allowedWOrigins = append(c.allowedWOrigins, w)
} else {
c.allowedOrigins = append(c.allowedOrigins, origin)
diff --git a/vendor/golang.org/x/crypto/ssh/certs.go b/vendor/golang.org/x/crypto/ssh/certs.go
index b1f02207819f..5c9fadcee355 100644
--- a/vendor/golang.org/x/crypto/ssh/certs.go
+++ b/vendor/golang.org/x/crypto/ssh/certs.go
@@ -343,7 +343,7 @@ func (c *CertChecker) CheckCert(principal string, cert *Certificate) error {
return fmt.Errorf("ssh: certicate serial %d revoked", cert.Serial)
}
- for opt, _ := range cert.CriticalOptions {
+ for opt := range cert.CriticalOptions {
// sourceAddressCriticalOption will be enforced by
// serverAuthenticate
if opt == sourceAddressCriticalOption {
diff --git a/vendor/golang.org/x/crypto/ssh/session.go b/vendor/golang.org/x/crypto/ssh/session.go
index cc06e03f5c1a..d3321f6b784b 100644
--- a/vendor/golang.org/x/crypto/ssh/session.go
+++ b/vendor/golang.org/x/crypto/ssh/session.go
@@ -406,7 +406,7 @@ func (s *Session) Wait() error {
s.stdinPipeWriter.Close()
}
var copyError error
- for _ = range s.copyFuncs {
+ for range s.copyFuncs {
if err := <-s.errors; err != nil && copyError == nil {
copyError = err
}
diff --git a/vendor/golang.org/x/text/encoding/unicode/unicode.go b/vendor/golang.org/x/text/encoding/unicode/unicode.go
index 579cadfb12ab..bfcb4e380408 100644
--- a/vendor/golang.org/x/text/encoding/unicode/unicode.go
+++ b/vendor/golang.org/x/text/encoding/unicode/unicode.go
@@ -158,12 +158,12 @@ func UTF16(e Endianness, b BOMPolicy) encoding.Encoding {
// and recommendations. Some of the "configurations" are merely recommendations,
// so multiple configurations could match.
var mibValue = map[Endianness][numBOMValues]identifier.MIB{
- BigEndian: [numBOMValues]identifier.MIB{
+ BigEndian: {
IgnoreBOM: identifier.UTF16BE,
UseBOM: identifier.UTF16, // BigEnding default is preferred by RFC 2781.
// TODO: acceptBOM | strictBOM would map to UTF16BE as well.
},
- LittleEndian: [numBOMValues]identifier.MIB{
+ LittleEndian: {
IgnoreBOM: identifier.UTF16LE,
UseBOM: identifier.UTF16, // LittleEndian default is allowed and preferred on Windows.
// TODO: acceptBOM | strictBOM would map to UTF16LE as well.
diff --git a/vendor/golang.org/x/text/language/maketables.go b/vendor/golang.org/x/text/language/maketables.go
index 107f99254d36..1cfaebdb3b2c 100644
--- a/vendor/golang.org/x/text/language/maketables.go
+++ b/vendor/golang.org/x/text/language/maketables.go
@@ -1050,7 +1050,7 @@ func (b *builder) writeRegion() {
m49Index := [9]int16{}
fromM49 := []uint16{}
m49 := []int{}
- for k, _ := range fromM49map {
+ for k := range fromM49map {
m49 = append(m49, int(k))
}
sort.Ints(m49)
diff --git a/vendor/gopkg.in/check.v1/benchmark.go b/vendor/gopkg.in/check.v1/benchmark.go
index 46ea9dc6dad6..b2d351948d22 100644
--- a/vendor/gopkg.in/check.v1/benchmark.go
+++ b/vendor/gopkg.in/check.v1/benchmark.go
@@ -1,9 +1,9 @@
// Copyright (c) 2012 The Go Authors. All rights reserved.
-//
+//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
-//
+//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
@@ -13,7 +13,7 @@
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
-//
+//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
diff --git a/vendor/vendor.json b/vendor/vendor.json
index 3d5c675e25b4..ebba356057e6 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -219,6 +219,24 @@
"revision": "14207d285c6c197daabb5c9793d63e7af9ab2d50",
"revisionTime": "2017-02-01T02:35:40Z"
},
+ {
+ "checksumSHA1": "ivtw8g85QHSNcSMfrBo7W/+Jxuk=",
+ "path": "github.com/mikioh/tcp",
+ "revision": "a2964c74d73b11ff68e6c9bfabb496cfe29a9a60",
+ "revisionTime": "2018-03-12T23:28:10Z"
+ },
+ {
+ "checksumSHA1": "A8zHFqov7rdzEf/U7GZ0sxyuR6o=",
+ "path": "github.com/mikioh/tcpinfo",
+ "revision": "fd8b9a80d71e11a9ffcf963e3548d336c8b39e1d",
+ "revisionTime": "2018-02-10T23:49:01Z"
+ },
+ {
+ "checksumSHA1": "CckjL74KJmJeLPVVm7BKDf8pSYk=",
+ "path": "github.com/mikioh/tcpopt",
+ "revision": "18f4a8218095cbd44df0d49c3dd91e7f2a3b12e0",
+ "revisionTime": "2018-02-10T23:37:10Z"
+ },
{
"checksumSHA1": "L3leymg2RT8hFl5uL+5KP/LpBkg=",
"path": "github.com/mitchellh/go-wordwrap",
@@ -712,5 +730,5 @@
"revisionTime": "2017-08-11T01:42:03Z"
}
],
- "rootPath": "github.com/ethereum/go-ethereum"
+ "rootPath": "github.com/teamnsrg/go-ethereum"
}
diff --git a/whisper/mailserver/mailserver.go b/whisper/mailserver/mailserver.go
deleted file mode 100644
index 0ec6ec570c17..000000000000
--- a/whisper/mailserver/mailserver.go
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright 2017 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package mailserver
-
-import (
- "bytes"
- "encoding/binary"
- "fmt"
-
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/rlp"
- whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
- "github.com/syndtr/goleveldb/leveldb"
- "github.com/syndtr/goleveldb/leveldb/util"
-)
-
-type WMailServer struct {
- db *leveldb.DB
- w *whisper.Whisper
- pow float64
- key []byte
-}
-
-type DBKey struct {
- timestamp uint32
- hash common.Hash
- raw []byte
-}
-
-func NewDbKey(t uint32, h common.Hash) *DBKey {
- const sz = common.HashLength + 4
- var k DBKey
- k.timestamp = t
- k.hash = h
- k.raw = make([]byte, sz)
- binary.BigEndian.PutUint32(k.raw, k.timestamp)
- copy(k.raw[4:], k.hash[:])
- return &k
-}
-
-func (s *WMailServer) Init(shh *whisper.Whisper, path string, password string, pow float64) {
- var err error
- if len(path) == 0 {
- utils.Fatalf("DB file is not specified")
- }
-
- if len(password) == 0 {
- utils.Fatalf("Password is not specified for MailServer")
- }
-
- s.db, err = leveldb.OpenFile(path, nil)
- if err != nil {
- utils.Fatalf("Failed to open DB file: %s", err)
- }
-
- s.w = shh
- s.pow = pow
-
- MailServerKeyID, err := s.w.AddSymKeyFromPassword(password)
- if err != nil {
- utils.Fatalf("Failed to create symmetric key for MailServer: %s", err)
- }
- s.key, err = s.w.GetSymKey(MailServerKeyID)
- if err != nil {
- utils.Fatalf("Failed to save symmetric key for MailServer")
- }
-}
-
-func (s *WMailServer) Close() {
- if s.db != nil {
- s.db.Close()
- }
-}
-
-func (s *WMailServer) Archive(env *whisper.Envelope) {
- key := NewDbKey(env.Expiry-env.TTL, env.Hash())
- rawEnvelope, err := rlp.EncodeToBytes(env)
- if err != nil {
- log.Error(fmt.Sprintf("rlp.EncodeToBytes failed: %s", err))
- } else {
- err = s.db.Put(key.raw, rawEnvelope, nil)
- if err != nil {
- log.Error(fmt.Sprintf("Writing to DB failed: %s", err))
- }
- }
-}
-
-func (s *WMailServer) DeliverMail(peer *whisper.Peer, request *whisper.Envelope) {
- if peer == nil {
- log.Error("Whisper peer is nil")
- return
- }
-
- ok, lower, upper, topic := s.validateRequest(peer.ID(), request)
- if ok {
- s.processRequest(peer, lower, upper, topic)
- }
-}
-
-func (s *WMailServer) processRequest(peer *whisper.Peer, lower, upper uint32, topic whisper.TopicType) []*whisper.Envelope {
- ret := make([]*whisper.Envelope, 0)
- var err error
- var zero common.Hash
- var empty whisper.TopicType
- kl := NewDbKey(lower, zero)
- ku := NewDbKey(upper, zero)
- i := s.db.NewIterator(&util.Range{Start: kl.raw, Limit: ku.raw}, nil)
- defer i.Release()
-
- for i.Next() {
- var envelope whisper.Envelope
- err = rlp.DecodeBytes(i.Value(), &envelope)
- if err != nil {
- log.Error(fmt.Sprintf("RLP decoding failed: %s", err))
- }
-
- if topic == empty || envelope.Topic == topic {
- if peer == nil {
- // used for test purposes
- ret = append(ret, &envelope)
- } else {
- err = s.w.SendP2PDirect(peer, &envelope)
- if err != nil {
- log.Error(fmt.Sprintf("Failed to send direct message to peer: %s", err))
- return nil
- }
- }
- }
- }
-
- err = i.Error()
- if err != nil {
- log.Error(fmt.Sprintf("Level DB iterator error: %s", err))
- }
-
- return ret
-}
-
-func (s *WMailServer) validateRequest(peerID []byte, request *whisper.Envelope) (bool, uint32, uint32, whisper.TopicType) {
- var topic whisper.TopicType
- if s.pow > 0.0 && request.PoW() < s.pow {
- return false, 0, 0, topic
- }
-
- f := whisper.Filter{KeySym: s.key}
- decrypted := request.Open(&f)
- if decrypted == nil {
- log.Warn(fmt.Sprintf("Failed to decrypt p2p request"))
- return false, 0, 0, topic
- }
-
- if len(decrypted.Payload) < 8 {
- log.Warn(fmt.Sprintf("Undersized p2p request"))
- return false, 0, 0, topic
- }
-
- src := crypto.FromECDSAPub(decrypted.Src)
- if len(src)-len(peerID) == 1 {
- src = src[1:]
- }
- if !bytes.Equal(peerID, src) {
- log.Warn(fmt.Sprintf("Wrong signature of p2p request"))
- return false, 0, 0, topic
- }
-
- lower := binary.BigEndian.Uint32(decrypted.Payload[:4])
- upper := binary.BigEndian.Uint32(decrypted.Payload[4:8])
-
- if len(decrypted.Payload) >= 8+whisper.TopicLength {
- topic = whisper.BytesToTopic(decrypted.Payload[8:])
- }
-
- return true, lower, upper, topic
-}
diff --git a/whisper/mailserver/server_test.go b/whisper/mailserver/server_test.go
deleted file mode 100644
index 9155ee85a6ee..000000000000
--- a/whisper/mailserver/server_test.go
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright 2017 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package mailserver
-
-import (
- "crypto/ecdsa"
- "encoding/binary"
- "io/ioutil"
- "math/rand"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
-)
-
-const powRequirement = 0.00001
-
-var keyID string
-var shh *whisper.Whisper
-var seed = time.Now().Unix()
-
-type ServerTestParams struct {
- topic whisper.TopicType
- low uint32
- upp uint32
- key *ecdsa.PrivateKey
-}
-
-func assert(statement bool, text string, t *testing.T) {
- if !statement {
- t.Fatal(text)
- }
-}
-
-func TestDBKey(t *testing.T) {
- var h common.Hash
- i := uint32(time.Now().Unix())
- k := NewDbKey(i, h)
- assert(len(k.raw) == common.HashLength+4, "wrong DB key length", t)
- assert(byte(i%0x100) == k.raw[3], "raw representation should be big endian", t)
- assert(byte(i/0x1000000) == k.raw[0], "big endian expected", t)
-}
-
-func generateEnvelope(t *testing.T) *whisper.Envelope {
- h := crypto.Keccak256Hash([]byte("test sample data"))
- params := &whisper.MessageParams{
- KeySym: h[:],
- Topic: whisper.TopicType{},
- Payload: []byte("test payload"),
- PoW: powRequirement,
- WorkTime: 2,
- }
-
- msg, err := whisper.NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed to wrap with seed %d: %s.", seed, err)
- }
- return env
-}
-
-func TestMailServer(t *testing.T) {
- const password = "password_for_this_test"
- const dbPath = "whisper-server-test"
-
- dir, err := ioutil.TempDir("", dbPath)
- if err != nil {
- t.Fatal(err)
- }
-
- var server WMailServer
- shh = whisper.New(&whisper.DefaultConfig)
- shh.RegisterServer(&server)
-
- server.Init(shh, dir, password, powRequirement)
- defer server.Close()
-
- keyID, err = shh.AddSymKeyFromPassword(password)
- if err != nil {
- t.Fatalf("Failed to create symmetric key for mail request: %s", err)
- }
-
- rand.Seed(seed)
- env := generateEnvelope(t)
- server.Archive(env)
- deliverTest(t, &server, env)
-}
-
-func deliverTest(t *testing.T, server *WMailServer, env *whisper.Envelope) {
- id, err := shh.NewKeyPair()
- if err != nil {
- t.Fatalf("failed to generate new key pair with seed %d: %s.", seed, err)
- }
- testPeerID, err := shh.GetPrivateKey(id)
- if err != nil {
- t.Fatalf("failed to retrieve new key pair with seed %d: %s.", seed, err)
- }
- birth := env.Expiry - env.TTL
- p := &ServerTestParams{
- topic: env.Topic,
- low: birth - 1,
- upp: birth + 1,
- key: testPeerID,
- }
- singleRequest(t, server, env, p, true)
-
- p.low, p.upp = birth+1, 0xffffffff
- singleRequest(t, server, env, p, false)
-
- p.low, p.upp = 0, birth-1
- singleRequest(t, server, env, p, false)
-
- p.low = birth - 1
- p.upp = birth + 1
- p.topic[0]++
- singleRequest(t, server, env, p, false)
-}
-
-func singleRequest(t *testing.T, server *WMailServer, env *whisper.Envelope, p *ServerTestParams, expect bool) {
- request := createRequest(t, p)
- src := crypto.FromECDSAPub(&p.key.PublicKey)
- ok, lower, upper, topic := server.validateRequest(src, request)
- if !ok {
- t.Fatalf("request validation failed, seed: %d.", seed)
- }
- if lower != p.low {
- t.Fatalf("request validation failed (lower bound), seed: %d.", seed)
- }
- if upper != p.upp {
- t.Fatalf("request validation failed (upper bound), seed: %d.", seed)
- }
- if topic != p.topic {
- t.Fatalf("request validation failed (topic), seed: %d.", seed)
- }
-
- var exist bool
- mail := server.processRequest(nil, p.low, p.upp, p.topic)
- for _, msg := range mail {
- if msg.Hash() == env.Hash() {
- exist = true
- break
- }
- }
-
- if exist != expect {
- t.Fatalf("error: exist = %v, seed: %d.", exist, seed)
- }
-
- src[0]++
- ok, lower, upper, topic = server.validateRequest(src, request)
- if ok {
- t.Fatalf("request validation false positive, seed: %d (lower: %d, upper: %d).", seed, lower, upper)
- }
-}
-
-func createRequest(t *testing.T, p *ServerTestParams) *whisper.Envelope {
- data := make([]byte, 8+whisper.TopicLength)
- binary.BigEndian.PutUint32(data, p.low)
- binary.BigEndian.PutUint32(data[4:], p.upp)
- copy(data[8:], p.topic[:])
-
- key, err := shh.GetSymKey(keyID)
- if err != nil {
- t.Fatalf("failed to retrieve sym key with seed %d: %s.", seed, err)
- }
-
- params := &whisper.MessageParams{
- KeySym: key,
- Topic: p.topic,
- Payload: data,
- PoW: powRequirement * 2,
- WorkTime: 2,
- Src: p.key,
- }
-
- msg, err := whisper.NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed to wrap with seed %d: %s.", seed, err)
- }
- return env
-}
diff --git a/whisper/shhclient/client.go b/whisper/shhclient/client.go
deleted file mode 100644
index 61b4775d9536..000000000000
--- a/whisper/shhclient/client.go
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright 2017 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package shhclient
-
-import (
- "context"
-
- "github.com/ethereum/go-ethereum"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/rpc"
- whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
-)
-
-// Client defines typed wrappers for the Whisper v5 RPC API.
-type Client struct {
- c *rpc.Client
-}
-
-// Dial connects a client to the given URL.
-func Dial(rawurl string) (*Client, error) {
- c, err := rpc.Dial(rawurl)
- if err != nil {
- return nil, err
- }
- return NewClient(c), nil
-}
-
-// NewClient creates a client that uses the given RPC client.
-func NewClient(c *rpc.Client) *Client {
- return &Client{c}
-}
-
-// Version returns the Whisper sub-protocol version.
-func (sc *Client) Version(ctx context.Context) (string, error) {
- var result string
- err := sc.c.CallContext(ctx, &result, "shh_version")
- return result, err
-}
-
-// Info returns diagnostic information about the whisper node.
-func (sc *Client) Info(ctx context.Context) (whisper.Info, error) {
- var info whisper.Info
- err := sc.c.CallContext(ctx, &info, "shh_info")
- return info, err
-}
-
-// SetMaxMessageSize sets the maximal message size allowed by this node. Incoming
-// and outgoing messages with a larger size will be rejected. Whisper message size
-// can never exceed the limit imposed by the underlying P2P protocol (10 Mb).
-func (sc *Client) SetMaxMessageSize(ctx context.Context, size uint32) error {
- var ignored bool
- return sc.c.CallContext(ctx, &ignored, "shh_setMaxMessageSize", size)
-}
-
-// SetMinimumPoW (experimental) sets the minimal PoW required by this node.
-
-// This experimental function was introduced for the future dynamic adjustment of
-// PoW requirement. If the node is overwhelmed with messages, it should raise the
-// PoW requirement and notify the peers. The new value should be set relative to
-// the old value (e.g. double). The old value could be obtained via shh_info call.
-func (sc *Client) SetMinimumPoW(ctx context.Context, pow float64) error {
- var ignored bool
- return sc.c.CallContext(ctx, &ignored, "shh_setMinPoW", pow)
-}
-
-// Marks specific peer trusted, which will allow it to send historic (expired) messages.
-// Note This function is not adding new nodes, the node needs to exists as a peer.
-func (sc *Client) MarkTrustedPeer(ctx context.Context, enode string) error {
- var ignored bool
- return sc.c.CallContext(ctx, &ignored, "shh_markTrustedPeer", enode)
-}
-
-// NewKeyPair generates a new public and private key pair for message decryption and encryption.
-// It returns an identifier that can be used to refer to the key.
-func (sc *Client) NewKeyPair(ctx context.Context) (string, error) {
- var id string
- return id, sc.c.CallContext(ctx, &id, "shh_newKeyPair")
-}
-
-// AddPrivateKey stored the key pair, and returns its ID.
-func (sc *Client) AddPrivateKey(ctx context.Context, key []byte) (string, error) {
- var id string
- return id, sc.c.CallContext(ctx, &id, "shh_addPrivateKey", hexutil.Bytes(key))
-}
-
-// DeleteKeyPair delete the specifies key.
-func (sc *Client) DeleteKeyPair(ctx context.Context, id string) (string, error) {
- var ignored bool
- return id, sc.c.CallContext(ctx, &ignored, "shh_deleteKeyPair", id)
-}
-
-// HasKeyPair returns an indication if the node has a private key or
-// key pair matching the given ID.
-func (sc *Client) HasKeyPair(ctx context.Context, id string) (bool, error) {
- var has bool
- return has, sc.c.CallContext(ctx, &has, "shh_hasKeyPair", id)
-}
-
-// PublicKey return the public key for a key ID.
-func (sc *Client) PublicKey(ctx context.Context, id string) ([]byte, error) {
- var key hexutil.Bytes
- return []byte(key), sc.c.CallContext(ctx, &key, "shh_getPublicKey", id)
-}
-
-// PrivateKey return the private key for a key ID.
-func (sc *Client) PrivateKey(ctx context.Context, id string) ([]byte, error) {
- var key hexutil.Bytes
- return []byte(key), sc.c.CallContext(ctx, &key, "shh_getPrivateKey", id)
-}
-
-// NewSymmetricKey generates a random symmetric key and returns its identifier.
-// Can be used encrypting and decrypting messages where the key is known to both parties.
-func (sc *Client) NewSymmetricKey(ctx context.Context) (string, error) {
- var id string
- return id, sc.c.CallContext(ctx, &id, "shh_newSymKey")
-}
-
-// AddSymmetricKey stores the key, and returns its identifier.
-func (sc *Client) AddSymmetricKey(ctx context.Context, key []byte) (string, error) {
- var id string
- return id, sc.c.CallContext(ctx, &id, "shh_addSymKey", hexutil.Bytes(key))
-}
-
-// GenerateSymmetricKeyFromPassword generates the key from password, stores it, and returns its identifier.
-func (sc *Client) GenerateSymmetricKeyFromPassword(ctx context.Context, passwd []byte) (string, error) {
- var id string
- return id, sc.c.CallContext(ctx, &id, "shh_generateSymKeyFromPassword", hexutil.Bytes(passwd))
-}
-
-// HasSymmetricKey returns an indication if the key associated with the given id is stored in the node.
-func (sc *Client) HasSymmetricKey(ctx context.Context, id string) (bool, error) {
- var found bool
- return found, sc.c.CallContext(ctx, &found, "shh_hasSymKey", id)
-}
-
-// GetSymmetricKey returns the symmetric key associated with the given identifier.
-func (sc *Client) GetSymmetricKey(ctx context.Context, id string) ([]byte, error) {
- var key hexutil.Bytes
- return []byte(key), sc.c.CallContext(ctx, &key, "shh_getSymKey", id)
-}
-
-// DeleteSymmetricKey deletes the symmetric key associated with the given identifier.
-func (sc *Client) DeleteSymmetricKey(ctx context.Context, id string) error {
- var ignored bool
- return sc.c.CallContext(ctx, &ignored, "shh_deleteSymKey", id)
-}
-
-// Post a message onto the network.
-func (sc *Client) Post(ctx context.Context, message whisper.NewMessage) error {
- var ignored bool
- return sc.c.CallContext(ctx, &ignored, "shh_post", message)
-}
-
-// SubscribeMessages subscribes to messages that match the given criteria. This method
-// is only supported on bi-directional connections such as websockets and IPC.
-// NewMessageFilter uses polling and is supported over HTTP.
-func (ec *Client) SubscribeMessages(ctx context.Context, criteria whisper.Criteria, ch chan<- *whisper.Message) (ethereum.Subscription, error) {
- return ec.c.ShhSubscribe(ctx, ch, "messages", criteria)
-}
-
-// NewMessageFilter creates a filter within the node. This filter can be used to poll
-// for new messages (see FilterMessages) that satisfy the given criteria. A filter can
-// timeout when it was polled for in whisper.filterTimeout.
-func (ec *Client) NewMessageFilter(ctx context.Context, criteria whisper.Criteria) (string, error) {
- var id string
- return id, ec.c.CallContext(ctx, &id, "shh_newMessageFilter", criteria)
-}
-
-// DeleteMessageFilter removes the filter associated with the given id.
-func (ec *Client) DeleteMessageFilter(ctx context.Context, id string) error {
- var ignored bool
- return ec.c.CallContext(ctx, &ignored, "shh_deleteMessageFilter", id)
-}
-
-// FilterMessages retrieves all messages that are received between the last call to
-// this function and match the criteria that where given when the filter was created.
-func (ec *Client) FilterMessages(ctx context.Context, id string) ([]*whisper.Message, error) {
- var messages []*whisper.Message
- return messages, ec.c.CallContext(ctx, &messages, "shh_getFilterMessages", id)
-}
diff --git a/whisper/whisperv2/api.go b/whisper/whisperv2/api.go
deleted file mode 100644
index 5c6d1709597f..000000000000
--- a/whisper/whisperv2/api.go
+++ /dev/null
@@ -1,402 +0,0 @@
-// Copyright 2015 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv2
-
-import (
- "encoding/json"
- "fmt"
- "sync"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/crypto"
-)
-
-// PublicWhisperAPI provides the whisper RPC service.
-type PublicWhisperAPI struct {
- w *Whisper
-
- messagesMu sync.RWMutex
- messages map[hexutil.Uint]*whisperFilter
-}
-
-type whisperOfflineError struct{}
-
-func (e *whisperOfflineError) Error() string {
- return "whisper is offline"
-}
-
-// whisperOffLineErr is returned when the node doesn't offer the shh service.
-var whisperOffLineErr = new(whisperOfflineError)
-
-// NewPublicWhisperAPI create a new RPC whisper service.
-func NewPublicWhisperAPI(w *Whisper) *PublicWhisperAPI {
- return &PublicWhisperAPI{w: w, messages: make(map[hexutil.Uint]*whisperFilter)}
-}
-
-// Version returns the Whisper version this node offers.
-func (s *PublicWhisperAPI) Version() (hexutil.Uint, error) {
- if s.w == nil {
- return 0, whisperOffLineErr
- }
- return hexutil.Uint(s.w.Version()), nil
-}
-
-// HasIdentity checks if the the whisper node is configured with the private key
-// of the specified public pair.
-func (s *PublicWhisperAPI) HasIdentity(identity string) (bool, error) {
- if s.w == nil {
- return false, whisperOffLineErr
- }
- return s.w.HasIdentity(crypto.ToECDSAPub(common.FromHex(identity))), nil
-}
-
-// NewIdentity generates a new cryptographic identity for the client, and injects
-// it into the known identities for message decryption.
-func (s *PublicWhisperAPI) NewIdentity() (string, error) {
- if s.w == nil {
- return "", whisperOffLineErr
- }
-
- identity := s.w.NewIdentity()
- return common.ToHex(crypto.FromECDSAPub(&identity.PublicKey)), nil
-}
-
-type NewFilterArgs struct {
- To string
- From string
- Topics [][][]byte
-}
-
-// NewWhisperFilter creates and registers a new message filter to watch for inbound whisper messages.
-func (s *PublicWhisperAPI) NewFilter(args NewFilterArgs) (hexutil.Uint, error) {
- if s.w == nil {
- return 0, whisperOffLineErr
- }
-
- var id hexutil.Uint
- filter := Filter{
- To: crypto.ToECDSAPub(common.FromHex(args.To)),
- From: crypto.ToECDSAPub(common.FromHex(args.From)),
- Topics: NewFilterTopics(args.Topics...),
- Fn: func(message *Message) {
- wmsg := NewWhisperMessage(message)
- s.messagesMu.RLock() // Only read lock to the filter pool
- defer s.messagesMu.RUnlock()
- if s.messages[id] != nil {
- s.messages[id].insert(wmsg)
- }
- },
- }
- id = hexutil.Uint(s.w.Watch(filter))
-
- s.messagesMu.Lock()
- s.messages[id] = newWhisperFilter(id, s.w)
- s.messagesMu.Unlock()
-
- return id, nil
-}
-
-// GetFilterChanges retrieves all the new messages matched by a filter since the last retrieval.
-func (s *PublicWhisperAPI) GetFilterChanges(filterId hexutil.Uint) []WhisperMessage {
- s.messagesMu.RLock()
- defer s.messagesMu.RUnlock()
-
- if s.messages[filterId] != nil {
- if changes := s.messages[filterId].retrieve(); changes != nil {
- return changes
- }
- }
- return returnWhisperMessages(nil)
-}
-
-// UninstallFilter disables and removes an existing filter.
-func (s *PublicWhisperAPI) UninstallFilter(filterId hexutil.Uint) bool {
- s.messagesMu.Lock()
- defer s.messagesMu.Unlock()
-
- if _, ok := s.messages[filterId]; ok {
- delete(s.messages, filterId)
- return true
- }
- return false
-}
-
-// GetMessages retrieves all the known messages that match a specific filter.
-func (s *PublicWhisperAPI) GetMessages(filterId hexutil.Uint) []WhisperMessage {
- // Retrieve all the cached messages matching a specific, existing filter
- s.messagesMu.RLock()
- defer s.messagesMu.RUnlock()
-
- var messages []*Message
- if s.messages[filterId] != nil {
- messages = s.messages[filterId].messages()
- }
-
- return returnWhisperMessages(messages)
-}
-
-// returnWhisperMessages converts aNhisper message to a RPC whisper message.
-func returnWhisperMessages(messages []*Message) []WhisperMessage {
- msgs := make([]WhisperMessage, len(messages))
- for i, msg := range messages {
- msgs[i] = NewWhisperMessage(msg)
- }
- return msgs
-}
-
-type PostArgs struct {
- From string `json:"from"`
- To string `json:"to"`
- Topics [][]byte `json:"topics"`
- Payload string `json:"payload"`
- Priority int64 `json:"priority"`
- TTL int64 `json:"ttl"`
-}
-
-// Post injects a message into the whisper network for distribution.
-func (s *PublicWhisperAPI) Post(args PostArgs) (bool, error) {
- if s.w == nil {
- return false, whisperOffLineErr
- }
-
- // construct whisper message with transmission options
- message := NewMessage(common.FromHex(args.Payload))
- options := Options{
- To: crypto.ToECDSAPub(common.FromHex(args.To)),
- TTL: time.Duration(args.TTL) * time.Second,
- Topics: NewTopics(args.Topics...),
- }
-
- // set sender identity
- if len(args.From) > 0 {
- if key := s.w.GetIdentity(crypto.ToECDSAPub(common.FromHex(args.From))); key != nil {
- options.From = key
- } else {
- return false, fmt.Errorf("unknown identity to send from: %s", args.From)
- }
- }
-
- // Wrap and send the message
- pow := time.Duration(args.Priority) * time.Millisecond
- envelope, err := message.Wrap(pow, options)
- if err != nil {
- return false, err
- }
-
- return true, s.w.Send(envelope)
-}
-
-// WhisperMessage is the RPC representation of a whisper message.
-type WhisperMessage struct {
- ref *Message
-
- Payload string `json:"payload"`
- To string `json:"to"`
- From string `json:"from"`
- Sent int64 `json:"sent"`
- TTL int64 `json:"ttl"`
- Hash string `json:"hash"`
-}
-
-func (args *PostArgs) UnmarshalJSON(data []byte) (err error) {
- var obj struct {
- From string `json:"from"`
- To string `json:"to"`
- Topics []string `json:"topics"`
- Payload string `json:"payload"`
- Priority hexutil.Uint64 `json:"priority"`
- TTL hexutil.Uint64 `json:"ttl"`
- }
-
- if err := json.Unmarshal(data, &obj); err != nil {
- return err
- }
-
- args.From = obj.From
- args.To = obj.To
- args.Payload = obj.Payload
- args.Priority = int64(obj.Priority) // TODO(gluk256): handle overflow
- args.TTL = int64(obj.TTL) // ... here too ...
-
- // decode topic strings
- args.Topics = make([][]byte, len(obj.Topics))
- for i, topic := range obj.Topics {
- args.Topics[i] = common.FromHex(topic)
- }
-
- return nil
-}
-
-// UnmarshalJSON implements the json.Unmarshaler interface, invoked to convert a
-// JSON message blob into a WhisperFilterArgs structure.
-func (args *NewFilterArgs) UnmarshalJSON(b []byte) (err error) {
- // Unmarshal the JSON message and sanity check
- var obj struct {
- To interface{} `json:"to"`
- From interface{} `json:"from"`
- Topics interface{} `json:"topics"`
- }
- if err := json.Unmarshal(b, &obj); err != nil {
- return err
- }
-
- // Retrieve the simple data contents of the filter arguments
- if obj.To == nil {
- args.To = ""
- } else {
- argstr, ok := obj.To.(string)
- if !ok {
- return fmt.Errorf("to is not a string")
- }
- args.To = argstr
- }
- if obj.From == nil {
- args.From = ""
- } else {
- argstr, ok := obj.From.(string)
- if !ok {
- return fmt.Errorf("from is not a string")
- }
- args.From = argstr
- }
- // Construct the nested topic array
- if obj.Topics != nil {
- // Make sure we have an actual topic array
- list, ok := obj.Topics.([]interface{})
- if !ok {
- return fmt.Errorf("topics is not an array")
- }
- // Iterate over each topic and handle nil, string or array
- topics := make([][]string, len(list))
- for idx, field := range list {
- switch value := field.(type) {
- case nil:
- topics[idx] = []string{}
-
- case string:
- topics[idx] = []string{value}
-
- case []interface{}:
- topics[idx] = make([]string, len(value))
- for i, nested := range value {
- switch value := nested.(type) {
- case nil:
- topics[idx][i] = ""
-
- case string:
- topics[idx][i] = value
-
- default:
- return fmt.Errorf("topic[%d][%d] is not a string", idx, i)
- }
- }
- default:
- return fmt.Errorf("topic[%d] not a string or array", idx)
- }
- }
-
- topicsDecoded := make([][][]byte, len(topics))
- for i, condition := range topics {
- topicsDecoded[i] = make([][]byte, len(condition))
- for j, topic := range condition {
- topicsDecoded[i][j] = common.FromHex(topic)
- }
- }
-
- args.Topics = topicsDecoded
- }
- return nil
-}
-
-// whisperFilter is the message cache matching a specific filter, accumulating
-// inbound messages until the are requested by the client.
-type whisperFilter struct {
- id hexutil.Uint // Filter identifier for old message retrieval
- ref *Whisper // Whisper reference for old message retrieval
-
- cache []WhisperMessage // Cache of messages not yet polled
- skip map[common.Hash]struct{} // List of retrieved messages to avoid duplication
- update time.Time // Time of the last message query
-
- lock sync.RWMutex // Lock protecting the filter internals
-}
-
-// messages retrieves all the cached messages from the entire pool matching the
-// filter, resetting the filter's change buffer.
-func (w *whisperFilter) messages() []*Message {
- w.lock.Lock()
- defer w.lock.Unlock()
-
- w.cache = nil
- w.update = time.Now()
-
- w.skip = make(map[common.Hash]struct{})
- messages := w.ref.Messages(int(w.id))
- for _, message := range messages {
- w.skip[message.Hash] = struct{}{}
- }
- return messages
-}
-
-// insert injects a new batch of messages into the filter cache.
-func (w *whisperFilter) insert(messages ...WhisperMessage) {
- w.lock.Lock()
- defer w.lock.Unlock()
-
- for _, message := range messages {
- if _, ok := w.skip[message.ref.Hash]; !ok {
- w.cache = append(w.cache, messages...)
- }
- }
-}
-
-// retrieve fetches all the cached messages from the filter.
-func (w *whisperFilter) retrieve() (messages []WhisperMessage) {
- w.lock.Lock()
- defer w.lock.Unlock()
-
- messages, w.cache = w.cache, nil
- w.update = time.Now()
-
- return
-}
-
-// newWhisperFilter creates a new serialized, poll based whisper topic filter.
-func newWhisperFilter(id hexutil.Uint, ref *Whisper) *whisperFilter {
- return &whisperFilter{
- id: id,
- ref: ref,
- update: time.Now(),
- skip: make(map[common.Hash]struct{}),
- }
-}
-
-// NewWhisperMessage converts an internal message into an API version.
-func NewWhisperMessage(message *Message) WhisperMessage {
- return WhisperMessage{
- ref: message,
-
- Payload: common.ToHex(message.Payload),
- From: common.ToHex(crypto.FromECDSAPub(message.Recover())),
- To: common.ToHex(crypto.FromECDSAPub(message.To)),
- Sent: message.Sent.Unix(),
- TTL: int64(message.TTL / time.Second),
- Hash: common.ToHex(message.Hash.Bytes()),
- }
-}
diff --git a/whisper/whisperv2/doc.go b/whisper/whisperv2/doc.go
deleted file mode 100644
index 7252f44b1002..000000000000
--- a/whisper/whisperv2/doc.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2014 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-/*
-Package whisper implements the Whisper PoC-1.
-
-(https://github.com/ethereum/wiki/wiki/Whisper-PoC-1-Protocol-Spec)
-
-Whisper combines aspects of both DHTs and datagram messaging systems (e.g. UDP).
-As such it may be likened and compared to both, not dissimilar to the
-matter/energy duality (apologies to physicists for the blatant abuse of a
-fundamental and beautiful natural principle).
-
-Whisper is a pure identity-based messaging system. Whisper provides a low-level
-(non-application-specific) but easily-accessible API without being based upon
-or prejudiced by the low-level hardware attributes and characteristics,
-particularly the notion of singular endpoints.
-*/
-package whisperv2
diff --git a/whisper/whisperv2/envelope.go b/whisper/whisperv2/envelope.go
deleted file mode 100644
index 9f1c68204067..000000000000
--- a/whisper/whisperv2/envelope.go
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright 2014 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains the Whisper protocol Envelope element. For formal details please see
-// the specs at https://github.com/ethereum/wiki/wiki/Whisper-PoC-1-Protocol-Spec#envelopes.
-
-package whisperv2
-
-import (
- "crypto/ecdsa"
- "encoding/binary"
- "fmt"
- "math/big"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/ecies"
- "github.com/ethereum/go-ethereum/rlp"
-)
-
-// Envelope represents a clear-text data packet to transmit through the Whisper
-// network. Its contents may or may not be encrypted and signed.
-type Envelope struct {
- Expiry uint32 // Whisper protocol specifies int32, really should be int64
- TTL uint32 // ^^^^^^
- Topics []Topic
- Data []byte
- Nonce uint32
-
- hash common.Hash // Cached hash of the envelope to avoid rehashing every time
-}
-
-// NewEnvelope wraps a Whisper message with expiration and destination data
-// included into an envelope for network forwarding.
-func NewEnvelope(ttl time.Duration, topics []Topic, msg *Message) *Envelope {
- return &Envelope{
- Expiry: uint32(time.Now().Add(ttl).Unix()),
- TTL: uint32(ttl.Seconds()),
- Topics: topics,
- Data: msg.bytes(),
- Nonce: 0,
- }
-}
-
-// Seal closes the envelope by spending the requested amount of time as a proof
-// of work on hashing the data.
-func (self *Envelope) Seal(pow time.Duration) {
- d := make([]byte, 64)
- copy(d[:32], self.rlpWithoutNonce())
-
- finish, bestBit := time.Now().Add(pow).UnixNano(), 0
- for nonce := uint32(0); time.Now().UnixNano() < finish; {
- for i := 0; i < 1024; i++ {
- binary.BigEndian.PutUint32(d[60:], nonce)
-
- d := new(big.Int).SetBytes(crypto.Keccak256(d))
- firstBit := math.FirstBitSet(d)
- if firstBit > bestBit {
- self.Nonce, bestBit = nonce, firstBit
- }
- nonce++
- }
- }
-}
-
-// rlpWithoutNonce returns the RLP encoded envelope contents, except the nonce.
-func (self *Envelope) rlpWithoutNonce() []byte {
- enc, _ := rlp.EncodeToBytes([]interface{}{self.Expiry, self.TTL, self.Topics, self.Data})
- return enc
-}
-
-// Open extracts the message contained within a potentially encrypted envelope.
-func (self *Envelope) Open(key *ecdsa.PrivateKey) (msg *Message, err error) {
- // Split open the payload into a message construct
- data := self.Data
-
- message := &Message{
- Flags: data[0],
- Sent: time.Unix(int64(self.Expiry-self.TTL), 0),
- TTL: time.Duration(self.TTL) * time.Second,
- Hash: self.Hash(),
- }
- data = data[1:]
-
- if message.Flags&signatureFlag == signatureFlag {
- if len(data) < signatureLength {
- return nil, fmt.Errorf("unable to open envelope. First bit set but len(data) < len(signature)")
- }
- message.Signature, data = data[:signatureLength], data[signatureLength:]
- }
- message.Payload = data
-
- // Decrypt the message, if requested
- if key == nil {
- return message, nil
- }
- err = message.decrypt(key)
- switch err {
- case nil:
- return message, nil
-
- case ecies.ErrInvalidPublicKey: // Payload isn't encrypted
- return message, err
-
- default:
- return nil, fmt.Errorf("unable to open envelope, decrypt failed: %v", err)
- }
-}
-
-// Hash returns the SHA3 hash of the envelope, calculating it if not yet done.
-func (self *Envelope) Hash() common.Hash {
- if (self.hash == common.Hash{}) {
- enc, _ := rlp.EncodeToBytes(self)
- self.hash = crypto.Keccak256Hash(enc)
- }
- return self.hash
-}
-
-// DecodeRLP decodes an Envelope from an RLP data stream.
-func (self *Envelope) DecodeRLP(s *rlp.Stream) error {
- raw, err := s.Raw()
- if err != nil {
- return err
- }
- // The decoding of Envelope uses the struct fields but also needs
- // to compute the hash of the whole RLP-encoded envelope. This
- // type has the same structure as Envelope but is not an
- // rlp.Decoder so we can reuse the Envelope struct definition.
- type rlpenv Envelope
- if err := rlp.DecodeBytes(raw, (*rlpenv)(self)); err != nil {
- return err
- }
- self.hash = crypto.Keccak256Hash(raw)
- return nil
-}
diff --git a/whisper/whisperv2/envelope_test.go b/whisper/whisperv2/envelope_test.go
deleted file mode 100644
index 490ed9f6f8a6..000000000000
--- a/whisper/whisperv2/envelope_test.go
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2015 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv2
-
-import (
- "bytes"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/ecies"
-)
-
-func TestEnvelopeOpen(t *testing.T) {
- payload := []byte("hello world")
- message := NewMessage(payload)
-
- envelope, err := message.Wrap(DefaultPoW, Options{})
- if err != nil {
- t.Fatalf("failed to wrap message: %v", err)
- }
- opened, err := envelope.Open(nil)
- if err != nil {
- t.Fatalf("failed to open envelope: %v", err)
- }
- if opened.Flags != message.Flags {
- t.Fatalf("flags mismatch: have %d, want %d", opened.Flags, message.Flags)
- }
- if !bytes.Equal(opened.Signature, message.Signature) {
- t.Fatalf("signature mismatch: have 0x%x, want 0x%x", opened.Signature, message.Signature)
- }
- if !bytes.Equal(opened.Payload, message.Payload) {
- t.Fatalf("payload mismatch: have 0x%x, want 0x%x", opened.Payload, message.Payload)
- }
- if opened.Sent.Unix() != message.Sent.Unix() {
- t.Fatalf("send time mismatch: have %v, want %v", opened.Sent, message.Sent)
- }
- if opened.TTL/time.Second != DefaultTTL/time.Second {
- t.Fatalf("message TTL mismatch: have %v, want %v", opened.TTL, DefaultTTL)
- }
-
- if opened.Hash != envelope.Hash() {
- t.Fatalf("message hash mismatch: have 0x%x, want 0x%x", opened.Hash, envelope.Hash())
- }
-}
-
-func TestEnvelopeAnonymousOpenUntargeted(t *testing.T) {
- payload := []byte("hello envelope")
- envelope, err := NewMessage(payload).Wrap(DefaultPoW, Options{})
- if err != nil {
- t.Fatalf("failed to wrap message: %v", err)
- }
- opened, err := envelope.Open(nil)
- if err != nil {
- t.Fatalf("failed to open envelope: %v", err)
- }
- if opened.To != nil {
- t.Fatalf("recipient mismatch: have 0x%x, want nil", opened.To)
- }
- if !bytes.Equal(opened.Payload, payload) {
- t.Fatalf("payload mismatch: have 0x%x, want 0x%x", opened.Payload, payload)
- }
-}
-
-func TestEnvelopeAnonymousOpenTargeted(t *testing.T) {
- key, err := crypto.GenerateKey()
- if err != nil {
- t.Fatalf("failed to generate test identity: %v", err)
- }
-
- payload := []byte("hello envelope")
- envelope, err := NewMessage(payload).Wrap(DefaultPoW, Options{
- To: &key.PublicKey,
- })
- if err != nil {
- t.Fatalf("failed to wrap message: %v", err)
- }
- opened, err := envelope.Open(nil)
- if err != nil {
- t.Fatalf("failed to open envelope: %v", err)
- }
- if opened.To != nil {
- t.Fatalf("recipient mismatch: have 0x%x, want nil", opened.To)
- }
- if bytes.Equal(opened.Payload, payload) {
- t.Fatalf("payload match, should have been encrypted: 0x%x", opened.Payload)
- }
-}
-
-func TestEnvelopeIdentifiedOpenUntargeted(t *testing.T) {
- key, err := crypto.GenerateKey()
- if err != nil {
- t.Fatalf("failed to generate test identity: %v", err)
- }
-
- payload := []byte("hello envelope")
- envelope, err := NewMessage(payload).Wrap(DefaultPoW, Options{})
- if err != nil {
- t.Fatalf("failed to wrap message: %v", err)
- }
- opened, err := envelope.Open(key)
- switch err {
- case nil:
- t.Fatalf("envelope opened with bad key: %v", opened)
-
- case ecies.ErrInvalidPublicKey:
- // Ok, key mismatch but opened
-
- default:
- t.Fatalf("failed to open envelope: %v", err)
- }
-
- if opened.To != nil {
- t.Fatalf("recipient mismatch: have 0x%x, want nil", opened.To)
- }
- if !bytes.Equal(opened.Payload, payload) {
- t.Fatalf("payload mismatch: have 0x%x, want 0x%x", opened.Payload, payload)
- }
-}
-
-func TestEnvelopeIdentifiedOpenTargeted(t *testing.T) {
- key, err := crypto.GenerateKey()
- if err != nil {
- t.Fatalf("failed to generate test identity: %v", err)
- }
-
- payload := []byte("hello envelope")
- envelope, err := NewMessage(payload).Wrap(DefaultPoW, Options{
- To: &key.PublicKey,
- })
- if err != nil {
- t.Fatalf("failed to wrap message: %v", err)
- }
- opened, err := envelope.Open(key)
- if err != nil {
- t.Fatalf("failed to open envelope: %v", err)
- }
- if opened.To != nil {
- t.Fatalf("recipient mismatch: have 0x%x, want nil", opened.To)
- }
- if !bytes.Equal(opened.Payload, payload) {
- t.Fatalf("payload mismatch: have 0x%x, want 0x%x", opened.Payload, payload)
- }
-}
diff --git a/whisper/whisperv2/filter.go b/whisper/whisperv2/filter.go
deleted file mode 100644
index 7404859b78e5..000000000000
--- a/whisper/whisperv2/filter.go
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2014 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains the message filter for fine grained subscriptions.
-
-package whisperv2
-
-import (
- "crypto/ecdsa"
-
- "github.com/ethereum/go-ethereum/event/filter"
-)
-
-// Filter is used to subscribe to specific types of whisper messages.
-type Filter struct {
- To *ecdsa.PublicKey // Recipient of the message
- From *ecdsa.PublicKey // Sender of the message
- Topics [][]Topic // Topics to filter messages with
- Fn func(msg *Message) // Handler in case of a match
-}
-
-// NewFilterTopics creates a 2D topic array used by whisper.Filter from binary
-// data elements.
-func NewFilterTopics(data ...[][]byte) [][]Topic {
- filter := make([][]Topic, len(data))
- for i, condition := range data {
- // Handle the special case of condition == [[]byte{}]
- if len(condition) == 1 && len(condition[0]) == 0 {
- filter[i] = []Topic{}
- continue
- }
- // Otherwise flatten normally
- filter[i] = NewTopics(condition...)
- }
- return filter
-}
-
-// NewFilterTopicsFlat creates a 2D topic array used by whisper.Filter from flat
-// binary data elements.
-func NewFilterTopicsFlat(data ...[]byte) [][]Topic {
- filter := make([][]Topic, len(data))
- for i, element := range data {
- // Only add non-wildcard topics
- filter[i] = make([]Topic, 0, 1)
- if len(element) > 0 {
- filter[i] = append(filter[i], NewTopic(element))
- }
- }
- return filter
-}
-
-// NewFilterTopicsFromStrings creates a 2D topic array used by whisper.Filter
-// from textual data elements.
-func NewFilterTopicsFromStrings(data ...[]string) [][]Topic {
- filter := make([][]Topic, len(data))
- for i, condition := range data {
- // Handle the special case of condition == [""]
- if len(condition) == 1 && condition[0] == "" {
- filter[i] = []Topic{}
- continue
- }
- // Otherwise flatten normally
- filter[i] = NewTopicsFromStrings(condition...)
- }
- return filter
-}
-
-// NewFilterTopicsFromStringsFlat creates a 2D topic array used by whisper.Filter from flat
-// binary data elements.
-func NewFilterTopicsFromStringsFlat(data ...string) [][]Topic {
- filter := make([][]Topic, len(data))
- for i, element := range data {
- // Only add non-wildcard topics
- filter[i] = make([]Topic, 0, 1)
- if element != "" {
- filter[i] = append(filter[i], NewTopicFromString(element))
- }
- }
- return filter
-}
-
-// filterer is the internal, fully initialized filter ready to match inbound
-// messages to a variety of criteria.
-type filterer struct {
- to string // Recipient of the message
- from string // Sender of the message
- matcher *topicMatcher // Topics to filter messages with
- fn func(data interface{}) // Handler in case of a match
-}
-
-// Compare checks if the specified filter matches the current one.
-func (self filterer) Compare(f filter.Filter) bool {
- filter := f.(filterer)
-
- // Check the message sender and recipient
- if len(self.to) > 0 && self.to != filter.to {
- return false
- }
- if len(self.from) > 0 && self.from != filter.from {
- return false
- }
- // Check the topic filtering
- topics := make([]Topic, len(filter.matcher.conditions))
- for i, group := range filter.matcher.conditions {
- // Message should contain a single topic entry, extract
- for topics[i] = range group {
- break
- }
- }
- return self.matcher.Matches(topics)
-}
-
-// Trigger is called when a filter successfully matches an inbound message.
-func (self filterer) Trigger(data interface{}) {
- self.fn(data)
-}
diff --git a/whisper/whisperv2/filter_test.go b/whisper/whisperv2/filter_test.go
deleted file mode 100644
index ffdfd7b349f4..000000000000
--- a/whisper/whisperv2/filter_test.go
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright 2015 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv2
-
-import (
- "bytes"
-
- "testing"
-)
-
-var filterTopicsCreationTests = []struct {
- topics [][]string
- filter [][][4]byte
-}{
- { // Simple topic filter
- topics: [][]string{
- {"abc", "def", "ghi"},
- {"def"},
- {"ghi", "abc"},
- },
- filter: [][][4]byte{
- {{0x4e, 0x03, 0x65, 0x7a}, {0x34, 0x60, 0x7c, 0x9b}, {0x21, 0x41, 0x7d, 0xf9}},
- {{0x34, 0x60, 0x7c, 0x9b}},
- {{0x21, 0x41, 0x7d, 0xf9}, {0x4e, 0x03, 0x65, 0x7a}},
- },
- },
- { // Wild-carded topic filter
- topics: [][]string{
- {"abc", "def", "ghi"},
- {},
- {""},
- {"def"},
- },
- filter: [][][4]byte{
- {{0x4e, 0x03, 0x65, 0x7a}, {0x34, 0x60, 0x7c, 0x9b}, {0x21, 0x41, 0x7d, 0xf9}},
- {},
- {},
- {{0x34, 0x60, 0x7c, 0x9b}},
- },
- },
-}
-
-var filterTopicsCreationFlatTests = []struct {
- topics []string
- filter [][][4]byte
-}{
- { // Simple topic list
- topics: []string{"abc", "def", "ghi"},
- filter: [][][4]byte{
- {{0x4e, 0x03, 0x65, 0x7a}},
- {{0x34, 0x60, 0x7c, 0x9b}},
- {{0x21, 0x41, 0x7d, 0xf9}},
- },
- },
- { // Wild-carded topic list
- topics: []string{"abc", "", "ghi"},
- filter: [][][4]byte{
- {{0x4e, 0x03, 0x65, 0x7a}},
- {},
- {{0x21, 0x41, 0x7d, 0xf9}},
- },
- },
-}
-
-func TestFilterTopicsCreation(t *testing.T) {
- // Check full filter creation
- for i, tt := range filterTopicsCreationTests {
- // Check the textual creation
- filter := NewFilterTopicsFromStrings(tt.topics...)
- if len(filter) != len(tt.topics) {
- t.Errorf("test %d: condition count mismatch: have %v, want %v", i, len(filter), len(tt.topics))
- continue
- }
- for j, condition := range filter {
- if len(condition) != len(tt.filter[j]) {
- t.Errorf("test %d, condition %d: size mismatch: have %v, want %v", i, j, len(condition), len(tt.filter[j]))
- continue
- }
- for k := 0; k < len(condition); k++ {
- if !bytes.Equal(condition[k][:], tt.filter[j][k][:]) {
- t.Errorf("test %d, condition %d, segment %d: filter mismatch: have 0x%x, want 0x%x", i, j, k, condition[k], tt.filter[j][k])
- }
- }
- }
- // Check the binary creation
- binary := make([][][]byte, len(tt.topics))
- for j, condition := range tt.topics {
- binary[j] = make([][]byte, len(condition))
- for k, segment := range condition {
- binary[j][k] = []byte(segment)
- }
- }
- filter = NewFilterTopics(binary...)
- if len(filter) != len(tt.topics) {
- t.Errorf("test %d: condition count mismatch: have %v, want %v", i, len(filter), len(tt.topics))
- continue
- }
- for j, condition := range filter {
- if len(condition) != len(tt.filter[j]) {
- t.Errorf("test %d, condition %d: size mismatch: have %v, want %v", i, j, len(condition), len(tt.filter[j]))
- continue
- }
- for k := 0; k < len(condition); k++ {
- if !bytes.Equal(condition[k][:], tt.filter[j][k][:]) {
- t.Errorf("test %d, condition %d, segment %d: filter mismatch: have 0x%x, want 0x%x", i, j, k, condition[k], tt.filter[j][k])
- }
- }
- }
- }
- // Check flat filter creation
- for i, tt := range filterTopicsCreationFlatTests {
- // Check the textual creation
- filter := NewFilterTopicsFromStringsFlat(tt.topics...)
- if len(filter) != len(tt.topics) {
- t.Errorf("test %d: condition count mismatch: have %v, want %v", i, len(filter), len(tt.topics))
- continue
- }
- for j, condition := range filter {
- if len(condition) != len(tt.filter[j]) {
- t.Errorf("test %d, condition %d: size mismatch: have %v, want %v", i, j, len(condition), len(tt.filter[j]))
- continue
- }
- for k := 0; k < len(condition); k++ {
- if !bytes.Equal(condition[k][:], tt.filter[j][k][:]) {
- t.Errorf("test %d, condition %d, segment %d: filter mismatch: have 0x%x, want 0x%x", i, j, k, condition[k], tt.filter[j][k])
- }
- }
- }
- // Check the binary creation
- binary := make([][]byte, len(tt.topics))
- for j, topic := range tt.topics {
- binary[j] = []byte(topic)
- }
- filter = NewFilterTopicsFlat(binary...)
- if len(filter) != len(tt.topics) {
- t.Errorf("test %d: condition count mismatch: have %v, want %v", i, len(filter), len(tt.topics))
- continue
- }
- for j, condition := range filter {
- if len(condition) != len(tt.filter[j]) {
- t.Errorf("test %d, condition %d: size mismatch: have %v, want %v", i, j, len(condition), len(tt.filter[j]))
- continue
- }
- for k := 0; k < len(condition); k++ {
- if !bytes.Equal(condition[k][:], tt.filter[j][k][:]) {
- t.Errorf("test %d, condition %d, segment %d: filter mismatch: have 0x%x, want 0x%x", i, j, k, condition[k], tt.filter[j][k])
- }
- }
- }
- }
-}
-
-var filterCompareTests = []struct {
- matcher filterer
- message filterer
- match bool
-}{
- { // Wild-card filter matching anything
- matcher: filterer{to: "", from: "", matcher: newTopicMatcher()},
- message: filterer{to: "to", from: "from", matcher: newTopicMatcher(NewFilterTopicsFromStringsFlat("topic")...)},
- match: true,
- },
- { // Filter matching the to field
- matcher: filterer{to: "to", from: "", matcher: newTopicMatcher()},
- message: filterer{to: "to", from: "from", matcher: newTopicMatcher(NewFilterTopicsFromStringsFlat("topic")...)},
- match: true,
- },
- { // Filter rejecting the to field
- matcher: filterer{to: "to", from: "", matcher: newTopicMatcher()},
- message: filterer{to: "", from: "from", matcher: newTopicMatcher(NewFilterTopicsFromStringsFlat("topic")...)},
- match: false,
- },
- { // Filter matching the from field
- matcher: filterer{to: "", from: "from", matcher: newTopicMatcher()},
- message: filterer{to: "to", from: "from", matcher: newTopicMatcher(NewFilterTopicsFromStringsFlat("topic")...)},
- match: true,
- },
- { // Filter rejecting the from field
- matcher: filterer{to: "", from: "from", matcher: newTopicMatcher()},
- message: filterer{to: "to", from: "", matcher: newTopicMatcher(NewFilterTopicsFromStringsFlat("topic")...)},
- match: false,
- },
- { // Filter matching the topic field
- matcher: filterer{to: "", from: "from", matcher: newTopicMatcher(NewFilterTopicsFromStringsFlat("topic")...)},
- message: filterer{to: "to", from: "from", matcher: newTopicMatcher(NewFilterTopicsFromStringsFlat("topic")...)},
- match: true,
- },
- { // Filter rejecting the topic field
- matcher: filterer{to: "", from: "", matcher: newTopicMatcher(NewFilterTopicsFromStringsFlat("topic")...)},
- message: filterer{to: "to", from: "from", matcher: newTopicMatcher()},
- match: false,
- },
-}
-
-func TestFilterCompare(t *testing.T) {
- for i, tt := range filterCompareTests {
- if match := tt.matcher.Compare(tt.message); match != tt.match {
- t.Errorf("test %d: match mismatch: have %v, want %v", i, match, tt.match)
- }
- }
-}
diff --git a/whisper/whisperv2/main.go b/whisper/whisperv2/main.go
deleted file mode 100644
index be41604890cf..000000000000
--- a/whisper/whisperv2/main.go
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2014 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// +build none
-
-// Contains a simple whisper peer setup and self messaging to allow playing
-// around with the protocol and API without a fancy client implementation.
-
-package main
-
-import (
- "fmt"
- "log"
- "os"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/logger"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/nat"
- "github.com/ethereum/go-ethereum/whisper"
-)
-
-func main() {
- logger.AddLogSystem(logger.NewStdLogSystem(os.Stdout, log.LstdFlags, logger.InfoLevel))
-
- // Generate the peer identity
- key, err := crypto.GenerateKey()
- if err != nil {
- fmt.Printf("Failed to generate peer key: %v.\n", err)
- os.Exit(-1)
- }
- name := common.MakeName("whisper-go", "1.0")
- shh := whisper.New()
-
- // Create an Ethereum peer to communicate through
- server := p2p.Server{
- PrivateKey: key,
- MaxPeers: 10,
- Name: name,
- Protocols: []p2p.Protocol{shh.Protocol()},
- ListenAddr: ":30300",
- NAT: nat.Any(),
- }
- fmt.Println("Starting Ethereum peer...")
- if err := server.Start(); err != nil {
- fmt.Printf("Failed to start Ethereum peer: %v.\n", err)
- os.Exit(1)
- }
-
- // Send a message to self to check that something works
- payload := fmt.Sprintf("Hello world, this is %v. In case you're wondering, the time is %v", name, time.Now())
- if err := selfSend(shh, []byte(payload)); err != nil {
- fmt.Printf("Failed to self message: %v.\n", err)
- os.Exit(-1)
- }
-}
-
-// SendSelf wraps a payload into a Whisper envelope and forwards it to itself.
-func selfSend(shh *whisper.Whisper, payload []byte) error {
- ok := make(chan struct{})
-
- // Start watching for self messages, output any arrivals
- id := shh.NewIdentity()
- shh.Watch(whisper.Filter{
- To: &id.PublicKey,
- Fn: func(msg *whisper.Message) {
- fmt.Printf("Message received: %s, signed with 0x%x.\n", string(msg.Payload), msg.Signature)
- close(ok)
- },
- })
- // Wrap the payload and encrypt it
- msg := whisper.NewMessage(payload)
- envelope, err := msg.Wrap(whisper.DefaultPoW, whisper.Options{
- From: id,
- To: &id.PublicKey,
- TTL: whisper.DefaultTTL,
- })
- if err != nil {
- return fmt.Errorf("failed to seal message: %v", err)
- }
- // Dump the message into the system and wait for it to pop back out
- if err := shh.Send(envelope); err != nil {
- return fmt.Errorf("failed to send self-message: %v", err)
- }
- select {
- case <-ok:
- case <-time.After(time.Second):
- return fmt.Errorf("failed to receive message in time")
- }
- return nil
-}
diff --git a/whisper/whisperv2/message.go b/whisper/whisperv2/message.go
deleted file mode 100644
index 66648c3be85f..000000000000
--- a/whisper/whisperv2/message.go
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2014 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains the Whisper protocol Message element. For formal details please see
-// the specs at https://github.com/ethereum/wiki/wiki/Whisper-PoC-1-Protocol-Spec#messages.
-
-package whisperv2
-
-import (
- "crypto/ecdsa"
- crand "crypto/rand"
- "fmt"
- "math/rand"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/ecies"
- "github.com/ethereum/go-ethereum/log"
-)
-
-// Message represents an end-user data packet to transmit through the Whisper
-// protocol. These are wrapped into Envelopes that need not be understood by
-// intermediate nodes, just forwarded.
-type Message struct {
- Flags byte // First bit is signature presence, rest reserved and should be random
- Signature []byte
- Payload []byte
-
- Sent time.Time // Time when the message was posted into the network
- TTL time.Duration // Maximum time to live allowed for the message
-
- To *ecdsa.PublicKey // Message recipient (identity used to decode the message)
- Hash common.Hash // Message envelope hash to act as a unique id
-}
-
-// Options specifies the exact way a message should be wrapped into an Envelope.
-type Options struct {
- From *ecdsa.PrivateKey
- To *ecdsa.PublicKey
- TTL time.Duration
- Topics []Topic
-}
-
-// NewMessage creates and initializes a non-signed, non-encrypted Whisper message.
-func NewMessage(payload []byte) *Message {
- // Construct an initial flag set: no signature, rest random
- flags := byte(rand.Intn(256))
- flags &= ^signatureFlag
-
- // Assemble and return the message
- return &Message{
- Flags: flags,
- Payload: payload,
- Sent: time.Now(),
- }
-}
-
-// Wrap bundles the message into an Envelope to transmit over the network.
-//
-// pow (Proof Of Work) controls how much time to spend on hashing the message,
-// inherently controlling its priority through the network (smaller hash, bigger
-// priority).
-//
-// The user can control the amount of identity, privacy and encryption through
-// the options parameter as follows:
-// - options.From == nil && options.To == nil: anonymous broadcast
-// - options.From != nil && options.To == nil: signed broadcast (known sender)
-// - options.From == nil && options.To != nil: encrypted anonymous message
-// - options.From != nil && options.To != nil: encrypted signed message
-func (self *Message) Wrap(pow time.Duration, options Options) (*Envelope, error) {
- // Use the default TTL if non was specified
- if options.TTL == 0 {
- options.TTL = DefaultTTL
- }
- self.TTL = options.TTL
-
- // Sign and encrypt the message if requested
- if options.From != nil {
- if err := self.sign(options.From); err != nil {
- return nil, err
- }
- }
- if options.To != nil {
- if err := self.encrypt(options.To); err != nil {
- return nil, err
- }
- }
- // Wrap the processed message, seal it and return
- envelope := NewEnvelope(options.TTL, options.Topics, self)
- envelope.Seal(pow)
-
- return envelope, nil
-}
-
-// sign calculates and sets the cryptographic signature for the message , also
-// setting the sign flag.
-func (self *Message) sign(key *ecdsa.PrivateKey) (err error) {
- self.Flags |= signatureFlag
- self.Signature, err = crypto.Sign(self.hash(), key)
- return
-}
-
-// Recover retrieves the public key of the message signer.
-func (self *Message) Recover() *ecdsa.PublicKey {
- defer func() { recover() }() // in case of invalid signature
-
- // Short circuit if no signature is present
- if self.Signature == nil {
- return nil
- }
- // Otherwise try and recover the signature
- pub, err := crypto.SigToPub(self.hash(), self.Signature)
- if err != nil {
- log.Error(fmt.Sprintf("Could not get public key from signature: %v", err))
- return nil
- }
- return pub
-}
-
-// encrypt encrypts a message payload with a public key.
-func (self *Message) encrypt(key *ecdsa.PublicKey) (err error) {
- self.Payload, err = ecies.Encrypt(crand.Reader, ecies.ImportECDSAPublic(key), self.Payload, nil, nil)
- return
-}
-
-// decrypt decrypts an encrypted payload with a private key.
-func (self *Message) decrypt(key *ecdsa.PrivateKey) error {
- cleartext, err := ecies.ImportECDSA(key).Decrypt(crand.Reader, self.Payload, nil, nil)
- if err == nil {
- self.Payload = cleartext
- }
- return err
-}
-
-// hash calculates the SHA3 checksum of the message flags and payload.
-func (self *Message) hash() []byte {
- return crypto.Keccak256(append([]byte{self.Flags}, self.Payload...))
-}
-
-// bytes flattens the message contents (flags, signature and payload) into a
-// single binary blob.
-func (self *Message) bytes() []byte {
- return append([]byte{self.Flags}, append(self.Signature, self.Payload...)...)
-}
diff --git a/whisper/whisperv2/message_test.go b/whisper/whisperv2/message_test.go
deleted file mode 100644
index c760ac54c46e..000000000000
--- a/whisper/whisperv2/message_test.go
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2014 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv2
-
-import (
- "bytes"
- "crypto/elliptic"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/crypto"
-)
-
-// Tests whether a message can be wrapped without any identity or encryption.
-func TestMessageSimpleWrap(t *testing.T) {
- payload := []byte("hello world")
-
- msg := NewMessage(payload)
- if _, err := msg.Wrap(DefaultPoW, Options{}); err != nil {
- t.Fatalf("failed to wrap message: %v", err)
- }
- if msg.Flags&signatureFlag != 0 {
- t.Fatalf("signature flag mismatch: have %d, want %d", msg.Flags&signatureFlag, 0)
- }
- if len(msg.Signature) != 0 {
- t.Fatalf("signature found for simple wrapping: 0x%x", msg.Signature)
- }
- if !bytes.Equal(msg.Payload, payload) {
- t.Fatalf("payload mismatch after wrapping: have 0x%x, want 0x%x", msg.Payload, payload)
- }
- if msg.TTL/time.Second != DefaultTTL/time.Second {
- t.Fatalf("message TTL mismatch: have %v, want %v", msg.TTL, DefaultTTL)
- }
-}
-
-// Tests whether a message can be signed, and wrapped in plain-text.
-func TestMessageCleartextSignRecover(t *testing.T) {
- key, err := crypto.GenerateKey()
- if err != nil {
- t.Fatalf("failed to create crypto key: %v", err)
- }
- payload := []byte("hello world")
-
- msg := NewMessage(payload)
- if _, err := msg.Wrap(DefaultPoW, Options{
- From: key,
- }); err != nil {
- t.Fatalf("failed to sign message: %v", err)
- }
- if msg.Flags&signatureFlag != signatureFlag {
- t.Fatalf("signature flag mismatch: have %d, want %d", msg.Flags&signatureFlag, signatureFlag)
- }
- if !bytes.Equal(msg.Payload, payload) {
- t.Fatalf("payload mismatch after signing: have 0x%x, want 0x%x", msg.Payload, payload)
- }
-
- pubKey := msg.Recover()
- if pubKey == nil {
- t.Fatalf("failed to recover public key")
- }
- p1 := elliptic.Marshal(crypto.S256(), key.PublicKey.X, key.PublicKey.Y)
- p2 := elliptic.Marshal(crypto.S256(), pubKey.X, pubKey.Y)
- if !bytes.Equal(p1, p2) {
- t.Fatalf("public key mismatch: have 0x%x, want 0x%x", p2, p1)
- }
-}
-
-// Tests whether a message can be encrypted and decrypted using an anonymous
-// sender (i.e. no signature).
-func TestMessageAnonymousEncryptDecrypt(t *testing.T) {
- key, err := crypto.GenerateKey()
- if err != nil {
- t.Fatalf("failed to create recipient crypto key: %v", err)
- }
- payload := []byte("hello world")
-
- msg := NewMessage(payload)
- envelope, err := msg.Wrap(DefaultPoW, Options{
- To: &key.PublicKey,
- })
- if err != nil {
- t.Fatalf("failed to encrypt message: %v", err)
- }
- if msg.Flags&signatureFlag != 0 {
- t.Fatalf("signature flag mismatch: have %d, want %d", msg.Flags&signatureFlag, 0)
- }
- if len(msg.Signature) != 0 {
- t.Fatalf("signature found for anonymous message: 0x%x", msg.Signature)
- }
-
- out, err := envelope.Open(key)
- if err != nil {
- t.Fatalf("failed to open encrypted message: %v", err)
- }
- if !bytes.Equal(out.Payload, payload) {
- t.Errorf("payload mismatch: have 0x%x, want 0x%x", out.Payload, payload)
- }
-}
-
-// Tests whether a message can be properly signed and encrypted.
-func TestMessageFullCrypto(t *testing.T) {
- fromKey, err := crypto.GenerateKey()
- if err != nil {
- t.Fatalf("failed to create sender crypto key: %v", err)
- }
- toKey, err := crypto.GenerateKey()
- if err != nil {
- t.Fatalf("failed to create recipient crypto key: %v", err)
- }
-
- payload := []byte("hello world")
- msg := NewMessage(payload)
- envelope, err := msg.Wrap(DefaultPoW, Options{
- From: fromKey,
- To: &toKey.PublicKey,
- })
- if err != nil {
- t.Fatalf("failed to encrypt message: %v", err)
- }
- if msg.Flags&signatureFlag != signatureFlag {
- t.Fatalf("signature flag mismatch: have %d, want %d", msg.Flags&signatureFlag, signatureFlag)
- }
- if len(msg.Signature) == 0 {
- t.Fatalf("no signature found for signed message")
- }
-
- out, err := envelope.Open(toKey)
- if err != nil {
- t.Fatalf("failed to open encrypted message: %v", err)
- }
- if !bytes.Equal(out.Payload, payload) {
- t.Errorf("payload mismatch: have 0x%x, want 0x%x", out.Payload, payload)
- }
-
- pubKey := out.Recover()
- if pubKey == nil {
- t.Fatalf("failed to recover public key")
- }
- p1 := elliptic.Marshal(crypto.S256(), fromKey.PublicKey.X, fromKey.PublicKey.Y)
- p2 := elliptic.Marshal(crypto.S256(), pubKey.X, pubKey.Y)
- if !bytes.Equal(p1, p2) {
- t.Fatalf("public key mismatch: have 0x%x, want 0x%x", p2, p1)
- }
-}
diff --git a/whisper/whisperv2/peer.go b/whisper/whisperv2/peer.go
deleted file mode 100644
index 71798408b928..000000000000
--- a/whisper/whisperv2/peer.go
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright 2014 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv2
-
-import (
- "fmt"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/rlp"
- "gopkg.in/fatih/set.v0"
-)
-
-// peer represents a whisper protocol peer connection.
-type peer struct {
- host *Whisper
- peer *p2p.Peer
- ws p2p.MsgReadWriter
-
- known *set.Set // Messages already known by the peer to avoid wasting bandwidth
-
- quit chan struct{}
-}
-
-// newPeer creates a new whisper peer object, but does not run the handshake itself.
-func newPeer(host *Whisper, remote *p2p.Peer, rw p2p.MsgReadWriter) *peer {
- return &peer{
- host: host,
- peer: remote,
- ws: rw,
- known: set.New(),
- quit: make(chan struct{}),
- }
-}
-
-// start initiates the peer updater, periodically broadcasting the whisper packets
-// into the network.
-func (self *peer) start() {
- go self.update()
- log.Debug(fmt.Sprintf("%v: whisper started", self.peer))
-}
-
-// stop terminates the peer updater, stopping message forwarding to it.
-func (self *peer) stop() {
- close(self.quit)
- log.Debug(fmt.Sprintf("%v: whisper stopped", self.peer))
-}
-
-// handshake sends the protocol initiation status message to the remote peer and
-// verifies the remote status too.
-func (self *peer) handshake() error {
- // Send the handshake status message asynchronously
- errc := make(chan error, 1)
- go func() {
- errc <- p2p.SendItems(self.ws, statusCode, protocolVersion)
- }()
- // Fetch the remote status packet and verify protocol match
- packet, err := self.ws.ReadMsg()
- if err != nil {
- return err
- }
- if packet.Code != statusCode {
- return fmt.Errorf("peer sent %x before status packet", packet.Code)
- }
- s := rlp.NewStream(packet.Payload, uint64(packet.Size))
- if _, err := s.List(); err != nil {
- return fmt.Errorf("bad status message: %v", err)
- }
- peerVersion, err := s.Uint()
- if err != nil {
- return fmt.Errorf("bad status message: %v", err)
- }
- if peerVersion != protocolVersion {
- return fmt.Errorf("protocol version mismatch %d != %d", peerVersion, protocolVersion)
- }
- // Wait until out own status is consumed too
- if err := <-errc; err != nil {
- return fmt.Errorf("failed to send status packet: %v", err)
- }
- return nil
-}
-
-// update executes periodic operations on the peer, including message transmission
-// and expiration.
-func (self *peer) update() {
- // Start the tickers for the updates
- expire := time.NewTicker(expirationCycle)
- transmit := time.NewTicker(transmissionCycle)
-
- // Loop and transmit until termination is requested
- for {
- select {
- case <-expire.C:
- self.expire()
-
- case <-transmit.C:
- if err := self.broadcast(); err != nil {
- log.Info(fmt.Sprintf("%v: broadcast failed: %v", self.peer, err))
- return
- }
-
- case <-self.quit:
- return
- }
- }
-}
-
-// mark marks an envelope known to the peer so that it won't be sent back.
-func (self *peer) mark(envelope *Envelope) {
- self.known.Add(envelope.Hash())
-}
-
-// marked checks if an envelope is already known to the remote peer.
-func (self *peer) marked(envelope *Envelope) bool {
- return self.known.Has(envelope.Hash())
-}
-
-// expire iterates over all the known envelopes in the host and removes all
-// expired (unknown) ones from the known list.
-func (self *peer) expire() {
- // Assemble the list of available envelopes
- available := set.NewNonTS()
- for _, envelope := range self.host.envelopes() {
- available.Add(envelope.Hash())
- }
- // Cross reference availability with known status
- unmark := make(map[common.Hash]struct{})
- self.known.Each(func(v interface{}) bool {
- if !available.Has(v.(common.Hash)) {
- unmark[v.(common.Hash)] = struct{}{}
- }
- return true
- })
- // Dump all known but unavailable
- for hash := range unmark {
- self.known.Remove(hash)
- }
-}
-
-// broadcast iterates over the collection of envelopes and transmits yet unknown
-// ones over the network.
-func (self *peer) broadcast() error {
- // Fetch the envelopes and collect the unknown ones
- envelopes := self.host.envelopes()
- transmit := make([]*Envelope, 0, len(envelopes))
- for _, envelope := range envelopes {
- if !self.marked(envelope) {
- transmit = append(transmit, envelope)
- self.mark(envelope)
- }
- }
- // Transmit the unknown batch (potentially empty)
- if err := p2p.Send(self.ws, messagesCode, transmit); err != nil {
- return err
- }
- log.Trace(fmt.Sprint(self.peer, "broadcasted", len(transmit), "message(s)"))
- return nil
-}
diff --git a/whisper/whisperv2/peer_test.go b/whisper/whisperv2/peer_test.go
deleted file mode 100644
index 87ca5063dfcc..000000000000
--- a/whisper/whisperv2/peer_test.go
+++ /dev/null
@@ -1,261 +0,0 @@
-// Copyright 2015 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv2
-
-import (
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
-)
-
-type testPeer struct {
- client *Whisper
- stream *p2p.MsgPipeRW
- termed chan struct{}
-}
-
-func startTestPeer() *testPeer {
- // Create a simulated P2P remote peer and data streams to it
- remote := p2p.NewPeer(discover.NodeID{}, "", nil)
- tester, tested := p2p.MsgPipe()
-
- // Create a whisper client and connect with it to the tester peer
- client := New()
- client.Start(nil)
-
- termed := make(chan struct{})
- go func() {
- defer client.Stop()
- defer close(termed)
- defer tested.Close()
-
- client.handlePeer(remote, tested)
- }()
-
- return &testPeer{
- client: client,
- stream: tester,
- termed: termed,
- }
-}
-
-func startTestPeerInited() (*testPeer, error) {
- peer := startTestPeer()
-
- if err := p2p.ExpectMsg(peer.stream, statusCode, []uint64{protocolVersion}); err != nil {
- peer.stream.Close()
- return nil, err
- }
- if err := p2p.SendItems(peer.stream, statusCode, protocolVersion); err != nil {
- peer.stream.Close()
- return nil, err
- }
- return peer, nil
-}
-
-func TestPeerStatusMessage(t *testing.T) {
- tester := startTestPeer()
-
- // Wait for the handshake status message and check it
- if err := p2p.ExpectMsg(tester.stream, statusCode, []uint64{protocolVersion}); err != nil {
- t.Fatalf("status message mismatch: %v", err)
- }
- // Terminate the node
- tester.stream.Close()
-
- select {
- case <-tester.termed:
- case <-time.After(time.Second):
- t.Fatalf("local close timed out")
- }
-}
-
-func TestPeerHandshakeFail(t *testing.T) {
- tester := startTestPeer()
-
- // Wait for and check the handshake
- if err := p2p.ExpectMsg(tester.stream, statusCode, []uint64{protocolVersion}); err != nil {
- t.Fatalf("status message mismatch: %v", err)
- }
- // Send an invalid handshake status and verify disconnect
- if err := p2p.SendItems(tester.stream, messagesCode); err != nil {
- t.Fatalf("failed to send malformed status: %v", err)
- }
- select {
- case <-tester.termed:
- case <-time.After(time.Second):
- t.Fatalf("remote close timed out")
- }
-}
-
-func TestPeerHandshakeSuccess(t *testing.T) {
- tester := startTestPeer()
-
- // Wait for and check the handshake
- if err := p2p.ExpectMsg(tester.stream, statusCode, []uint64{protocolVersion}); err != nil {
- t.Fatalf("status message mismatch: %v", err)
- }
- // Send a valid handshake status and make sure connection stays live
- if err := p2p.SendItems(tester.stream, statusCode, protocolVersion); err != nil {
- t.Fatalf("failed to send status: %v", err)
- }
- select {
- case <-tester.termed:
- t.Fatalf("valid handshake disconnected")
-
- case <-time.After(100 * time.Millisecond):
- }
- // Clean up the test
- tester.stream.Close()
-
- select {
- case <-tester.termed:
- case <-time.After(time.Second):
- t.Fatalf("local close timed out")
- }
-}
-
-func TestPeerSend(t *testing.T) {
- // Start a tester and execute the handshake
- tester, err := startTestPeerInited()
- if err != nil {
- t.Fatalf("failed to start initialized peer: %v", err)
- }
- defer tester.stream.Close()
-
- // Construct a message and inject into the tester
- message := NewMessage([]byte("peer broadcast test message"))
- envelope, err := message.Wrap(DefaultPoW, Options{
- TTL: DefaultTTL,
- })
- if err != nil {
- t.Fatalf("failed to wrap message: %v", err)
- }
- if err := tester.client.Send(envelope); err != nil {
- t.Fatalf("failed to send message: %v", err)
- }
- // Check that the message is eventually forwarded
- payload := []interface{}{envelope}
- if err := p2p.ExpectMsg(tester.stream, messagesCode, payload); err != nil {
- t.Fatalf("message mismatch: %v", err)
- }
- // Make sure that even with a re-insert, an empty batch is received
- if err := tester.client.Send(envelope); err != nil {
- t.Fatalf("failed to send message: %v", err)
- }
- if err := p2p.ExpectMsg(tester.stream, messagesCode, []interface{}{}); err != nil {
- t.Fatalf("message mismatch: %v", err)
- }
-}
-
-func TestPeerDeliver(t *testing.T) {
- // Start a tester and execute the handshake
- tester, err := startTestPeerInited()
- if err != nil {
- t.Fatalf("failed to start initialized peer: %v", err)
- }
- defer tester.stream.Close()
-
- // Watch for all inbound messages
- arrived := make(chan struct{}, 1)
- tester.client.Watch(Filter{
- Fn: func(message *Message) {
- arrived <- struct{}{}
- },
- })
- // Construct a message and deliver it to the tester peer
- message := NewMessage([]byte("peer broadcast test message"))
- envelope, err := message.Wrap(DefaultPoW, Options{
- TTL: DefaultTTL,
- })
- if err != nil {
- t.Fatalf("failed to wrap message: %v", err)
- }
- if err := p2p.Send(tester.stream, messagesCode, []*Envelope{envelope}); err != nil {
- t.Fatalf("failed to transfer message: %v", err)
- }
- // Check that the message is delivered upstream
- select {
- case <-arrived:
- case <-time.After(time.Second):
- t.Fatalf("message delivery timeout")
- }
- // Check that a resend is not delivered
- if err := p2p.Send(tester.stream, messagesCode, []*Envelope{envelope}); err != nil {
- t.Fatalf("failed to transfer message: %v", err)
- }
- select {
- case <-time.After(2 * transmissionCycle):
- case <-arrived:
- t.Fatalf("repeating message arrived")
- }
-}
-
-func TestPeerMessageExpiration(t *testing.T) {
- // Start a tester and execute the handshake
- tester, err := startTestPeerInited()
- if err != nil {
- t.Fatalf("failed to start initialized peer: %v", err)
- }
- defer tester.stream.Close()
-
- // Fetch the peer instance for later inspection
- tester.client.peerMu.RLock()
- if peers := len(tester.client.peers); peers != 1 {
- t.Fatalf("peer pool size mismatch: have %v, want %v", peers, 1)
- }
- var peer *peer
- for peer = range tester.client.peers {
- break
- }
- tester.client.peerMu.RUnlock()
-
- // Construct a message and pass it through the tester
- message := NewMessage([]byte("peer test message"))
- envelope, err := message.Wrap(DefaultPoW, Options{
- TTL: time.Second,
- })
- if err != nil {
- t.Fatalf("failed to wrap message: %v", err)
- }
- if err := tester.client.Send(envelope); err != nil {
- t.Fatalf("failed to send message: %v", err)
- }
- payload := []interface{}{envelope}
- if err := p2p.ExpectMsg(tester.stream, messagesCode, payload); err != nil {
- // A premature empty message may have been broadcast, check the next too
- if err := p2p.ExpectMsg(tester.stream, messagesCode, payload); err != nil {
- t.Fatalf("message mismatch: %v", err)
- }
- }
- // Check that the message is inside the cache
- if !peer.known.Has(envelope.Hash()) {
- t.Fatalf("message not found in cache")
- }
- // Discard messages until expiration and check cache again
- exp := time.Now().Add(time.Second + 2*expirationCycle + 100*time.Millisecond)
- for time.Now().Before(exp) {
- if err := p2p.ExpectMsg(tester.stream, messagesCode, []interface{}{}); err != nil {
- t.Fatalf("message mismatch: %v", err)
- }
- }
- if peer.known.Has(envelope.Hash()) {
- t.Fatalf("message not expired from cache")
- }
-}
diff --git a/whisper/whisperv2/topic.go b/whisper/whisperv2/topic.go
deleted file mode 100644
index 3e2b47bd3f00..000000000000
--- a/whisper/whisperv2/topic.go
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2015 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains the Whisper protocol Topic element. For formal details please see
-// the specs at https://github.com/ethereum/wiki/wiki/Whisper-PoC-1-Protocol-Spec#topics.
-
-package whisperv2
-
-import "github.com/ethereum/go-ethereum/crypto"
-
-// Topic represents a cryptographically secure, probabilistic partial
-// classifications of a message, determined as the first (left) 4 bytes of the
-// SHA3 hash of some arbitrary data given by the original author of the message.
-type Topic [4]byte
-
-// NewTopic creates a topic from the 4 byte prefix of the SHA3 hash of the data.
-//
-// Note, empty topics are considered the wildcard, and cannot be used in messages.
-func NewTopic(data []byte) Topic {
- prefix := [4]byte{}
- copy(prefix[:], crypto.Keccak256(data)[:4])
- return Topic(prefix)
-}
-
-// NewTopics creates a list of topics from a list of binary data elements, by
-// iteratively calling NewTopic on each of them.
-func NewTopics(data ...[]byte) []Topic {
- topics := make([]Topic, len(data))
- for i, element := range data {
- topics[i] = NewTopic(element)
- }
- return topics
-}
-
-// NewTopicFromString creates a topic using the binary data contents of the
-// specified string.
-func NewTopicFromString(data string) Topic {
- return NewTopic([]byte(data))
-}
-
-// NewTopicsFromStrings creates a list of topics from a list of textual data
-// elements, by iteratively calling NewTopicFromString on each of them.
-func NewTopicsFromStrings(data ...string) []Topic {
- topics := make([]Topic, len(data))
- for i, element := range data {
- topics[i] = NewTopicFromString(element)
- }
- return topics
-}
-
-// String converts a topic byte array to a string representation.
-func (self *Topic) String() string {
- return string(self[:])
-}
-
-// topicMatcher is a filter expression to verify if a list of topics contained
-// in an arriving message matches some topic conditions. The topic matcher is
-// built up of a list of conditions, each of which must be satisfied by the
-// corresponding topic in the message. Each condition may require: a) an exact
-// topic match; b) a match from a set of topics; or c) a wild-card matching all.
-//
-// If a message contains more topics than required by the matcher, those beyond
-// the condition count are ignored and assumed to match.
-//
-// Consider the following sample topic matcher:
-// sample := {
-// {TopicA1, TopicA2, TopicA3},
-// {TopicB},
-// nil,
-// {TopicD1, TopicD2}
-// }
-// In order for a message to pass this filter, it should enumerate at least 4
-// topics, the first any of [TopicA1, TopicA2, TopicA3], the second mandatory
-// "TopicB", the third is ignored by the filter and the fourth either "TopicD1"
-// or "TopicD2". If the message contains further topics, the filter will match
-// them too.
-type topicMatcher struct {
- conditions []map[Topic]struct{}
-}
-
-// newTopicMatcher create a topic matcher from a list of topic conditions.
-func newTopicMatcher(topics ...[]Topic) *topicMatcher {
- matcher := make([]map[Topic]struct{}, len(topics))
- for i, condition := range topics {
- matcher[i] = make(map[Topic]struct{})
- for _, topic := range condition {
- matcher[i][topic] = struct{}{}
- }
- }
- return &topicMatcher{conditions: matcher}
-}
-
-// newTopicMatcherFromBinary create a topic matcher from a list of binary conditions.
-func newTopicMatcherFromBinary(data ...[][]byte) *topicMatcher {
- topics := make([][]Topic, len(data))
- for i, condition := range data {
- topics[i] = NewTopics(condition...)
- }
- return newTopicMatcher(topics...)
-}
-
-// newTopicMatcherFromStrings creates a topic matcher from a list of textual
-// conditions.
-func newTopicMatcherFromStrings(data ...[]string) *topicMatcher {
- topics := make([][]Topic, len(data))
- for i, condition := range data {
- topics[i] = NewTopicsFromStrings(condition...)
- }
- return newTopicMatcher(topics...)
-}
-
-// Matches checks if a list of topics matches this particular condition set.
-func (self *topicMatcher) Matches(topics []Topic) bool {
- // Mismatch if there aren't enough topics
- if len(self.conditions) > len(topics) {
- return false
- }
- // Check each topic condition for existence (skip wild-cards)
- for i := 0; i < len(topics) && i < len(self.conditions); i++ {
- if len(self.conditions[i]) > 0 {
- if _, ok := self.conditions[i][topics[i]]; !ok {
- return false
- }
- }
- }
- return true
-}
diff --git a/whisper/whisperv2/topic_test.go b/whisper/whisperv2/topic_test.go
deleted file mode 100644
index bb656899637a..000000000000
--- a/whisper/whisperv2/topic_test.go
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright 2015 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv2
-
-import (
- "bytes"
- "testing"
-)
-
-var topicCreationTests = []struct {
- data []byte
- hash [4]byte
-}{
- {hash: [4]byte{0x8f, 0x9a, 0x2b, 0x7d}, data: []byte("test name")},
- {hash: [4]byte{0xf2, 0x6e, 0x77, 0x79}, data: []byte("some other test")},
-}
-
-func TestTopicCreation(t *testing.T) {
- // Create the topics individually
- for i, tt := range topicCreationTests {
- topic := NewTopic(tt.data)
- if !bytes.Equal(topic[:], tt.hash[:]) {
- t.Errorf("binary test %d: hash mismatch: have %v, want %v.", i, topic, tt.hash)
- }
- }
- for i, tt := range topicCreationTests {
- topic := NewTopicFromString(string(tt.data))
- if !bytes.Equal(topic[:], tt.hash[:]) {
- t.Errorf("textual test %d: hash mismatch: have %v, want %v.", i, topic, tt.hash)
- }
- }
- // Create the topics in batches
- binaryData := make([][]byte, len(topicCreationTests))
- for i, tt := range topicCreationTests {
- binaryData[i] = tt.data
- }
- textualData := make([]string, len(topicCreationTests))
- for i, tt := range topicCreationTests {
- textualData[i] = string(tt.data)
- }
-
- topics := NewTopics(binaryData...)
- for i, tt := range topicCreationTests {
- if !bytes.Equal(topics[i][:], tt.hash[:]) {
- t.Errorf("binary batch test %d: hash mismatch: have %v, want %v.", i, topics[i], tt.hash)
- }
- }
- topics = NewTopicsFromStrings(textualData...)
- for i, tt := range topicCreationTests {
- if !bytes.Equal(topics[i][:], tt.hash[:]) {
- t.Errorf("textual batch test %d: hash mismatch: have %v, want %v.", i, topics[i], tt.hash)
- }
- }
-}
-
-var topicMatcherCreationTest = struct {
- binary [][][]byte
- textual [][]string
- matcher []map[[4]byte]struct{}
-}{
- binary: [][][]byte{
- {},
- {
- []byte("Topic A"),
- },
- {
- []byte("Topic B1"),
- []byte("Topic B2"),
- []byte("Topic B3"),
- },
- },
- textual: [][]string{
- {},
- {"Topic A"},
- {"Topic B1", "Topic B2", "Topic B3"},
- },
- matcher: []map[[4]byte]struct{}{
- {},
- {
- {0x25, 0xfc, 0x95, 0x66}: {},
- },
- {
- {0x93, 0x6d, 0xec, 0x09}: {},
- {0x25, 0x23, 0x34, 0xd3}: {},
- {0x6b, 0xc2, 0x73, 0xd1}: {},
- },
- },
-}
-
-func TestTopicMatcherCreation(t *testing.T) {
- test := topicMatcherCreationTest
-
- matcher := newTopicMatcherFromBinary(test.binary...)
- for i, cond := range matcher.conditions {
- for topic := range cond {
- if _, ok := test.matcher[i][topic]; !ok {
- t.Errorf("condition %d; extra topic found: 0x%x", i, topic[:])
- }
- }
- }
- for i, cond := range test.matcher {
- for topic := range cond {
- if _, ok := matcher.conditions[i][topic]; !ok {
- t.Errorf("condition %d; topic not found: 0x%x", i, topic[:])
- }
- }
- }
-
- matcher = newTopicMatcherFromStrings(test.textual...)
- for i, cond := range matcher.conditions {
- for topic := range cond {
- if _, ok := test.matcher[i][topic]; !ok {
- t.Errorf("condition %d; extra topic found: 0x%x", i, topic[:])
- }
- }
- }
- for i, cond := range test.matcher {
- for topic := range cond {
- if _, ok := matcher.conditions[i][topic]; !ok {
- t.Errorf("condition %d; topic not found: 0x%x", i, topic[:])
- }
- }
- }
-}
-
-var topicMatcherTests = []struct {
- filter [][]string
- topics []string
- match bool
-}{
- // Empty topic matcher should match everything
- {
- filter: [][]string{},
- topics: []string{},
- match: true,
- },
- {
- filter: [][]string{},
- topics: []string{"a", "b", "c"},
- match: true,
- },
- // Fixed topic matcher should match strictly, but only prefix
- {
- filter: [][]string{{"a"}, {"b"}},
- topics: []string{"a"},
- match: false,
- },
- {
- filter: [][]string{{"a"}, {"b"}},
- topics: []string{"a", "b"},
- match: true,
- },
- {
- filter: [][]string{{"a"}, {"b"}},
- topics: []string{"a", "b", "c"},
- match: true,
- },
- // Multi-matcher should match any from a sub-group
- {
- filter: [][]string{{"a1", "a2"}},
- topics: []string{"a"},
- match: false,
- },
- {
- filter: [][]string{{"a1", "a2"}},
- topics: []string{"a1"},
- match: true,
- },
- {
- filter: [][]string{{"a1", "a2"}},
- topics: []string{"a2"},
- match: true,
- },
- // Wild-card condition should match anything
- {
- filter: [][]string{{}, {"b"}},
- topics: []string{"a"},
- match: false,
- },
- {
- filter: [][]string{{}, {"b"}},
- topics: []string{"a", "b"},
- match: true,
- },
- {
- filter: [][]string{{}, {"b"}},
- topics: []string{"b", "b"},
- match: true,
- },
-}
-
-func TestTopicMatcher(t *testing.T) {
- for i, tt := range topicMatcherTests {
- topics := NewTopicsFromStrings(tt.topics...)
-
- matcher := newTopicMatcherFromStrings(tt.filter...)
- if match := matcher.Matches(topics); match != tt.match {
- t.Errorf("test %d: match mismatch: have %v, want %v", i, match, tt.match)
- }
- }
-}
diff --git a/whisper/whisperv2/whisper.go b/whisper/whisperv2/whisper.go
deleted file mode 100644
index 61c36918d486..000000000000
--- a/whisper/whisperv2/whisper.go
+++ /dev/null
@@ -1,378 +0,0 @@
-// Copyright 2014 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv2
-
-import (
- "crypto/ecdsa"
- "fmt"
- "sync"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/ecies"
- "github.com/ethereum/go-ethereum/event/filter"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/rpc"
-
- "gopkg.in/fatih/set.v0"
-)
-
-const (
- statusCode = 0x00
- messagesCode = 0x01
-
- protocolVersion uint64 = 0x02
- protocolName = "shh"
-
- signatureFlag = byte(1 << 7)
- signatureLength = 65
-
- expirationCycle = 800 * time.Millisecond
- transmissionCycle = 300 * time.Millisecond
-)
-
-const (
- DefaultTTL = 50 * time.Second
- DefaultPoW = 50 * time.Millisecond
-)
-
-type MessageEvent struct {
- To *ecdsa.PrivateKey
- From *ecdsa.PublicKey
- Message *Message
-}
-
-// Whisper represents a dark communication interface through the Ethereum
-// network, using its very own P2P communication layer.
-type Whisper struct {
- protocol p2p.Protocol
- filters *filter.Filters
-
- keys map[string]*ecdsa.PrivateKey
-
- messages map[common.Hash]*Envelope // Pool of messages currently tracked by this node
- expirations map[uint32]*set.SetNonTS // Message expiration pool (TODO: something lighter)
- poolMu sync.RWMutex // Mutex to sync the message and expiration pools
-
- peers map[*peer]struct{} // Set of currently active peers
- peerMu sync.RWMutex // Mutex to sync the active peer set
-
- quit chan struct{}
-}
-
-// New creates a Whisper client ready to communicate through the Ethereum P2P
-// network.
-func New() *Whisper {
- whisper := &Whisper{
- filters: filter.New(),
- keys: make(map[string]*ecdsa.PrivateKey),
- messages: make(map[common.Hash]*Envelope),
- expirations: make(map[uint32]*set.SetNonTS),
- peers: make(map[*peer]struct{}),
- quit: make(chan struct{}),
- }
- whisper.filters.Start()
-
- // p2p whisper sub protocol handler
- whisper.protocol = p2p.Protocol{
- Name: protocolName,
- Version: uint(protocolVersion),
- Length: 2,
- Run: whisper.handlePeer,
- }
-
- return whisper
-}
-
-// APIs returns the RPC descriptors the Whisper implementation offers
-func (s *Whisper) APIs() []rpc.API {
- return []rpc.API{
- {
- Namespace: "shh",
- Version: "1.0",
- Service: NewPublicWhisperAPI(s),
- Public: true,
- },
- }
-}
-
-// Protocols returns the whisper sub-protocols ran by this particular client.
-func (self *Whisper) Protocols() []p2p.Protocol {
- return []p2p.Protocol{self.protocol}
-}
-
-// Version returns the whisper sub-protocols version number.
-func (self *Whisper) Version() uint {
- return self.protocol.Version
-}
-
-// NewIdentity generates a new cryptographic identity for the client, and injects
-// it into the known identities for message decryption.
-func (self *Whisper) NewIdentity() *ecdsa.PrivateKey {
- key, err := crypto.GenerateKey()
- if err != nil {
- panic(err)
- }
- self.keys[string(crypto.FromECDSAPub(&key.PublicKey))] = key
-
- return key
-}
-
-// HasIdentity checks if the the whisper node is configured with the private key
-// of the specified public pair.
-func (self *Whisper) HasIdentity(key *ecdsa.PublicKey) bool {
- return self.keys[string(crypto.FromECDSAPub(key))] != nil
-}
-
-// GetIdentity retrieves the private key of the specified public identity.
-func (self *Whisper) GetIdentity(key *ecdsa.PublicKey) *ecdsa.PrivateKey {
- return self.keys[string(crypto.FromECDSAPub(key))]
-}
-
-// Watch installs a new message handler to run in case a matching packet arrives
-// from the whisper network.
-func (self *Whisper) Watch(options Filter) int {
- filter := filterer{
- to: string(crypto.FromECDSAPub(options.To)),
- from: string(crypto.FromECDSAPub(options.From)),
- matcher: newTopicMatcher(options.Topics...),
- fn: func(data interface{}) {
- options.Fn(data.(*Message))
- },
- }
- return self.filters.Install(filter)
-}
-
-// Unwatch removes an installed message handler.
-func (self *Whisper) Unwatch(id int) {
- self.filters.Uninstall(id)
-}
-
-// Send injects a message into the whisper send queue, to be distributed in the
-// network in the coming cycles.
-func (self *Whisper) Send(envelope *Envelope) error {
- return self.add(envelope)
-}
-
-// Start implements node.Service, starting the background data propagation thread
-// of the Whisper protocol.
-func (self *Whisper) Start(*p2p.Server) error {
- log.Info("Whisper started")
- go self.update()
- return nil
-}
-
-// Stop implements node.Service, stopping the background data propagation thread
-// of the Whisper protocol.
-func (self *Whisper) Stop() error {
- close(self.quit)
- log.Info("Whisper stopped")
- return nil
-}
-
-// Messages retrieves all the currently pooled messages matching a filter id.
-func (self *Whisper) Messages(id int) []*Message {
- messages := make([]*Message, 0)
- if filter := self.filters.Get(id); filter != nil {
- for _, envelope := range self.messages {
- if message := self.open(envelope); message != nil {
- if self.filters.Match(filter, createFilter(message, envelope.Topics)) {
- messages = append(messages, message)
- }
- }
- }
- }
- return messages
-}
-
-// handlePeer is called by the underlying P2P layer when the whisper sub-protocol
-// connection is negotiated.
-func (self *Whisper) handlePeer(peer *p2p.Peer, rw p2p.MsgReadWriter) error {
- // Create the new peer and start tracking it
- whisperPeer := newPeer(self, peer, rw)
-
- self.peerMu.Lock()
- self.peers[whisperPeer] = struct{}{}
- self.peerMu.Unlock()
-
- defer func() {
- self.peerMu.Lock()
- delete(self.peers, whisperPeer)
- self.peerMu.Unlock()
- }()
-
- // Run the peer handshake and state updates
- if err := whisperPeer.handshake(); err != nil {
- return err
- }
- whisperPeer.start()
- defer whisperPeer.stop()
-
- // Read and process inbound messages directly to merge into client-global state
- for {
- // Fetch the next packet and decode the contained envelopes
- packet, err := rw.ReadMsg()
- if err != nil {
- return err
- }
- var envelopes []*Envelope
- if err := packet.Decode(&envelopes); err != nil {
- log.Info(fmt.Sprintf("%v: failed to decode envelope: %v", peer, err))
- continue
- }
- // Inject all envelopes into the internal pool
- for _, envelope := range envelopes {
- if err := self.add(envelope); err != nil {
- // TODO Punish peer here. Invalid envelope.
- log.Debug(fmt.Sprintf("%v: failed to pool envelope: %v", peer, err))
- }
- whisperPeer.mark(envelope)
- }
- }
-}
-
-// add inserts a new envelope into the message pool to be distributed within the
-// whisper network. It also inserts the envelope into the expiration pool at the
-// appropriate time-stamp.
-func (self *Whisper) add(envelope *Envelope) error {
- self.poolMu.Lock()
- defer self.poolMu.Unlock()
-
- // short circuit when a received envelope has already expired
- if envelope.Expiry < uint32(time.Now().Unix()) {
- return nil
- }
-
- // Insert the message into the tracked pool
- hash := envelope.Hash()
- if _, ok := self.messages[hash]; ok {
- log.Trace(fmt.Sprintf("whisper envelope already cached: %x\n", envelope))
- return nil
- }
- self.messages[hash] = envelope
-
- // Insert the message into the expiration pool for later removal
- if self.expirations[envelope.Expiry] == nil {
- self.expirations[envelope.Expiry] = set.NewNonTS()
- }
- if !self.expirations[envelope.Expiry].Has(hash) {
- self.expirations[envelope.Expiry].Add(hash)
-
- // Notify the local node of a message arrival
- go self.postEvent(envelope)
- }
- log.Trace(fmt.Sprintf("cached whisper envelope %x\n", envelope))
- return nil
-}
-
-// postEvent opens an envelope with the configured identities and delivers the
-// message upstream from application processing.
-func (self *Whisper) postEvent(envelope *Envelope) {
- if message := self.open(envelope); message != nil {
- self.filters.Notify(createFilter(message, envelope.Topics), message)
- }
-}
-
-// open tries to decrypt a whisper envelope with all the configured identities,
-// returning the decrypted message and the key used to achieve it. If not keys
-// are configured, open will return the payload as if non encrypted.
-func (self *Whisper) open(envelope *Envelope) *Message {
- // Short circuit if no identity is set, and assume clear-text
- if len(self.keys) == 0 {
- if message, err := envelope.Open(nil); err == nil {
- return message
- }
- }
- // Iterate over the keys and try to decrypt the message
- for _, key := range self.keys {
- message, err := envelope.Open(key)
- if err == nil {
- message.To = &key.PublicKey
- return message
- } else if err == ecies.ErrInvalidPublicKey {
- return message
- }
- }
- // Failed to decrypt, don't return anything
- return nil
-}
-
-// createFilter creates a message filter to check against installed handlers.
-func createFilter(message *Message, topics []Topic) filter.Filter {
- matcher := make([][]Topic, len(topics))
- for i, topic := range topics {
- matcher[i] = []Topic{topic}
- }
- return filterer{
- to: string(crypto.FromECDSAPub(message.To)),
- from: string(crypto.FromECDSAPub(message.Recover())),
- matcher: newTopicMatcher(matcher...),
- }
-}
-
-// update loops until the lifetime of the whisper node, updating its internal
-// state by expiring stale messages from the pool.
-func (self *Whisper) update() {
- // Start a ticker to check for expirations
- expire := time.NewTicker(expirationCycle)
-
- // Repeat updates until termination is requested
- for {
- select {
- case <-expire.C:
- self.expire()
-
- case <-self.quit:
- return
- }
- }
-}
-
-// expire iterates over all the expiration timestamps, removing all stale
-// messages from the pools.
-func (self *Whisper) expire() {
- self.poolMu.Lock()
- defer self.poolMu.Unlock()
-
- now := uint32(time.Now().Unix())
- for then, hashSet := range self.expirations {
- // Short circuit if a future time
- if then > now {
- continue
- }
- // Dump all expired messages and remove timestamp
- hashSet.Each(func(v interface{}) bool {
- delete(self.messages, v.(common.Hash))
- return true
- })
- self.expirations[then].Clear()
- }
-}
-
-// envelopes retrieves all the messages currently pooled by the node.
-func (self *Whisper) envelopes() []*Envelope {
- self.poolMu.RLock()
- defer self.poolMu.RUnlock()
-
- envelopes := make([]*Envelope, 0, len(self.messages))
- for _, envelope := range self.messages {
- envelopes = append(envelopes, envelope)
- }
- return envelopes
-}
diff --git a/whisper/whisperv2/whisper_test.go b/whisper/whisperv2/whisper_test.go
deleted file mode 100644
index 1e0d3f85d444..000000000000
--- a/whisper/whisperv2/whisper_test.go
+++ /dev/null
@@ -1,216 +0,0 @@
-// Copyright 2014 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv2
-
-import (
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
-)
-
-func startTestCluster(n int) []*Whisper {
- // Create the batch of simulated peers
- nodes := make([]*p2p.Peer, n)
- for i := 0; i < n; i++ {
- nodes[i] = p2p.NewPeer(discover.NodeID{}, "", nil)
- }
- whispers := make([]*Whisper, n)
- for i := 0; i < n; i++ {
- whispers[i] = New()
- whispers[i].Start(nil)
- }
- // Wire all the peers to the root one
- for i := 1; i < n; i++ {
- src, dst := p2p.MsgPipe()
-
- go whispers[0].handlePeer(nodes[i], src)
- go whispers[i].handlePeer(nodes[0], dst)
- }
- return whispers
-}
-
-func TestSelfMessage(t *testing.T) {
- // Start the single node cluster
- client := startTestCluster(1)[0]
-
- // Start watching for self messages, signal any arrivals
- self := client.NewIdentity()
- done := make(chan struct{})
-
- client.Watch(Filter{
- To: &self.PublicKey,
- Fn: func(msg *Message) {
- close(done)
- },
- })
- // Send a dummy message to oneself
- msg := NewMessage([]byte("self whisper"))
- envelope, err := msg.Wrap(DefaultPoW, Options{
- From: self,
- To: &self.PublicKey,
- TTL: DefaultTTL,
- })
- if err != nil {
- t.Fatalf("failed to wrap message: %v", err)
- }
- // Dump the message into the system and wait for it to pop back out
- if err := client.Send(envelope); err != nil {
- t.Fatalf("failed to send self-message: %v", err)
- }
- select {
- case <-done:
- case <-time.After(time.Second):
- t.Fatalf("self-message receive timeout")
- }
-}
-
-func TestDirectMessage(t *testing.T) {
- // Start the sender-recipient cluster
- cluster := startTestCluster(2)
-
- sender := cluster[0]
- senderId := sender.NewIdentity()
-
- recipient := cluster[1]
- recipientId := recipient.NewIdentity()
-
- // Watch for arriving messages on the recipient
- done := make(chan struct{})
- recipient.Watch(Filter{
- To: &recipientId.PublicKey,
- Fn: func(msg *Message) {
- close(done)
- },
- })
- // Send a dummy message from the sender
- msg := NewMessage([]byte("direct whisper"))
- envelope, err := msg.Wrap(DefaultPoW, Options{
- From: senderId,
- To: &recipientId.PublicKey,
- TTL: DefaultTTL,
- })
- if err != nil {
- t.Fatalf("failed to wrap message: %v", err)
- }
- if err := sender.Send(envelope); err != nil {
- t.Fatalf("failed to send direct message: %v", err)
- }
- // Wait for an arrival or a timeout
- select {
- case <-done:
- case <-time.After(time.Second):
- t.Fatalf("direct message receive timeout")
- }
-}
-
-func TestAnonymousBroadcast(t *testing.T) {
- testBroadcast(true, t)
-}
-
-func TestIdentifiedBroadcast(t *testing.T) {
- testBroadcast(false, t)
-}
-
-func testBroadcast(anonymous bool, t *testing.T) {
- // Start the single sender multi recipient cluster
- cluster := startTestCluster(3)
-
- sender := cluster[1]
- targets := cluster[1:]
- for _, target := range targets {
- if !anonymous {
- target.NewIdentity()
- }
- }
- // Watch for arriving messages on the recipients
- dones := make([]chan struct{}, len(targets))
- for i := 0; i < len(targets); i++ {
- done := make(chan struct{}) // need for the closure
- dones[i] = done
-
- targets[i].Watch(Filter{
- Topics: NewFilterTopicsFromStringsFlat("broadcast topic"),
- Fn: func(msg *Message) {
- close(done)
- },
- })
- }
- // Send a dummy message from the sender
- msg := NewMessage([]byte("broadcast whisper"))
- envelope, err := msg.Wrap(DefaultPoW, Options{
- Topics: NewTopicsFromStrings("broadcast topic"),
- TTL: DefaultTTL,
- })
- if err != nil {
- t.Fatalf("failed to wrap message: %v", err)
- }
- if err := sender.Send(envelope); err != nil {
- t.Fatalf("failed to send broadcast message: %v", err)
- }
- // Wait for an arrival on each recipient, or timeouts
- timeout := time.After(time.Second)
- for _, done := range dones {
- select {
- case <-done:
- case <-timeout:
- t.Fatalf("broadcast message receive timeout")
- }
- }
-}
-
-func TestMessageExpiration(t *testing.T) {
- // Start the single node cluster and inject a dummy message
- node := startTestCluster(1)[0]
-
- message := NewMessage([]byte("expiring message"))
- envelope, err := message.Wrap(DefaultPoW, Options{TTL: time.Second})
- if err != nil {
- t.Fatalf("failed to wrap message: %v", err)
- }
- if err := node.Send(envelope); err != nil {
- t.Fatalf("failed to inject message: %v", err)
- }
- // Check that the message is inside the cache
- node.poolMu.RLock()
- _, found := node.messages[envelope.Hash()]
- node.poolMu.RUnlock()
-
- if !found {
- t.Fatalf("message not found in cache")
- }
- // Wait for expiration and check cache again
- time.Sleep(time.Second) // wait for expiration
- time.Sleep(2 * expirationCycle) // wait for cleanup cycle
-
- node.poolMu.RLock()
- _, found = node.messages[envelope.Hash()]
- node.poolMu.RUnlock()
- if found {
- t.Fatalf("message not expired from cache")
- }
-
- // Check that adding an expired envelope doesn't do anything.
- node.add(envelope)
- node.poolMu.RLock()
- _, found = node.messages[envelope.Hash()]
- node.poolMu.RUnlock()
- if found {
- t.Fatalf("message was added to cache")
- }
-}
diff --git a/whisper/whisperv5/api.go b/whisper/whisperv5/api.go
deleted file mode 100644
index 96c4b0e6c492..000000000000
--- a/whisper/whisperv5/api.go
+++ /dev/null
@@ -1,591 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv5
-
-import (
- "context"
- "crypto/ecdsa"
- "errors"
- "fmt"
- "sync"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/rpc"
-)
-
-const (
- filterTimeout = 300 // filters are considered timeout out after filterTimeout seconds
-)
-
-var (
- ErrSymAsym = errors.New("specify either a symmetric or an asymmetric key")
- ErrInvalidSymmetricKey = errors.New("invalid symmetric key")
- ErrInvalidPublicKey = errors.New("invalid public key")
- ErrInvalidSigningPubKey = errors.New("invalid signing public key")
- ErrTooLowPoW = errors.New("message rejected, PoW too low")
- ErrNoTopics = errors.New("missing topic(s)")
-)
-
-// PublicWhisperAPI provides the whisper RPC service that can be
-// use publicly without security implications.
-type PublicWhisperAPI struct {
- w *Whisper
-
- mu sync.Mutex
- lastUsed map[string]time.Time // keeps track when a filter was polled for the last time.
-}
-
-// NewPublicWhisperAPI create a new RPC whisper service.
-func NewPublicWhisperAPI(w *Whisper) *PublicWhisperAPI {
- api := &PublicWhisperAPI{
- w: w,
- lastUsed: make(map[string]time.Time),
- }
-
- go api.run()
- return api
-}
-
-// run the api event loop.
-// this loop deletes filter that have not been used within filterTimeout
-func (api *PublicWhisperAPI) run() {
- timeout := time.NewTicker(2 * time.Minute)
- for {
- <-timeout.C
-
- api.mu.Lock()
- for id, lastUsed := range api.lastUsed {
- if time.Since(lastUsed).Seconds() >= filterTimeout {
- delete(api.lastUsed, id)
- if err := api.w.Unsubscribe(id); err != nil {
- log.Error("could not unsubscribe whisper filter", "error", err)
- }
- log.Debug("delete whisper filter (timeout)", "id", id)
- }
- }
- api.mu.Unlock()
- }
-}
-
-// Version returns the Whisper sub-protocol version.
-func (api *PublicWhisperAPI) Version(ctx context.Context) string {
- return ProtocolVersionStr
-}
-
-// Info contains diagnostic information.
-type Info struct {
- Memory int `json:"memory"` // Memory size of the floating messages in bytes.
- Messages int `json:"messages"` // Number of floating messages.
- MinPow float64 `json:"minPow"` // Minimal accepted PoW
- MaxMessageSize uint32 `json:"maxMessageSize"` // Maximum accepted message size
-}
-
-// Info returns diagnostic information about the whisper node.
-func (api *PublicWhisperAPI) Info(ctx context.Context) Info {
- stats := api.w.Stats()
- return Info{
- Memory: stats.memoryUsed,
- Messages: len(api.w.messageQueue) + len(api.w.p2pMsgQueue),
- MinPow: api.w.MinPow(),
- MaxMessageSize: api.w.MaxMessageSize(),
- }
-}
-
-// SetMaxMessageSize sets the maximum message size that is accepted.
-// Upper limit is defined in whisperv5.MaxMessageSize.
-func (api *PublicWhisperAPI) SetMaxMessageSize(ctx context.Context, size uint32) (bool, error) {
- return true, api.w.SetMaxMessageSize(size)
-}
-
-// SetMinPow sets the minimum PoW for a message before it is accepted.
-func (api *PublicWhisperAPI) SetMinPoW(ctx context.Context, pow float64) (bool, error) {
- return true, api.w.SetMinimumPoW(pow)
-}
-
-// MarkTrustedPeer marks a peer trusted. , which will allow it to send historic (expired) messages.
-// Note: This function is not adding new nodes, the node needs to exists as a peer.
-func (api *PublicWhisperAPI) MarkTrustedPeer(ctx context.Context, enode string) (bool, error) {
- n, err := discover.ParseNode(enode)
- if err != nil {
- return false, err
- }
- return true, api.w.AllowP2PMessagesFromPeer(n.ID[:])
-}
-
-// NewKeyPair generates a new public and private key pair for message decryption and encryption.
-// It returns an ID that can be used to refer to the keypair.
-func (api *PublicWhisperAPI) NewKeyPair(ctx context.Context) (string, error) {
- return api.w.NewKeyPair()
-}
-
-// AddPrivateKey imports the given private key.
-func (api *PublicWhisperAPI) AddPrivateKey(ctx context.Context, privateKey hexutil.Bytes) (string, error) {
- key, err := crypto.ToECDSA(privateKey)
- if err != nil {
- return "", err
- }
- return api.w.AddKeyPair(key)
-}
-
-// DeleteKeyPair removes the key with the given key if it exists.
-func (api *PublicWhisperAPI) DeleteKeyPair(ctx context.Context, key string) (bool, error) {
- if ok := api.w.DeleteKeyPair(key); ok {
- return true, nil
- }
- return false, fmt.Errorf("key pair %s not found", key)
-}
-
-// HasKeyPair returns an indication if the node has a key pair that is associated with the given id.
-func (api *PublicWhisperAPI) HasKeyPair(ctx context.Context, id string) bool {
- return api.w.HasKeyPair(id)
-}
-
-// GetPublicKey returns the public key associated with the given key. The key is the hex
-// encoded representation of a key in the form specified in section 4.3.6 of ANSI X9.62.
-func (api *PublicWhisperAPI) GetPublicKey(ctx context.Context, id string) (hexutil.Bytes, error) {
- key, err := api.w.GetPrivateKey(id)
- if err != nil {
- return hexutil.Bytes{}, err
- }
- return crypto.FromECDSAPub(&key.PublicKey), nil
-}
-
-// GetPublicKey returns the private key associated with the given key. The key is the hex
-// encoded representation of a key in the form specified in section 4.3.6 of ANSI X9.62.
-func (api *PublicWhisperAPI) GetPrivateKey(ctx context.Context, id string) (hexutil.Bytes, error) {
- key, err := api.w.GetPrivateKey(id)
- if err != nil {
- return hexutil.Bytes{}, err
- }
- return crypto.FromECDSA(key), nil
-}
-
-// NewSymKey generate a random symmetric key.
-// It returns an ID that can be used to refer to the key.
-// Can be used encrypting and decrypting messages where the key is known to both parties.
-func (api *PublicWhisperAPI) NewSymKey(ctx context.Context) (string, error) {
- return api.w.GenerateSymKey()
-}
-
-// AddSymKey import a symmetric key.
-// It returns an ID that can be used to refer to the key.
-// Can be used encrypting and decrypting messages where the key is known to both parties.
-func (api *PublicWhisperAPI) AddSymKey(ctx context.Context, key hexutil.Bytes) (string, error) {
- return api.w.AddSymKeyDirect([]byte(key))
-}
-
-// GenerateSymKeyFromPassword derive a key from the given password, stores it, and returns its ID.
-func (api *PublicWhisperAPI) GenerateSymKeyFromPassword(ctx context.Context, passwd string) (string, error) {
- return api.w.AddSymKeyFromPassword(passwd)
-}
-
-// HasSymKey returns an indication if the node has a symmetric key associated with the given key.
-func (api *PublicWhisperAPI) HasSymKey(ctx context.Context, id string) bool {
- return api.w.HasSymKey(id)
-}
-
-// GetSymKey returns the symmetric key associated with the given id.
-func (api *PublicWhisperAPI) GetSymKey(ctx context.Context, id string) (hexutil.Bytes, error) {
- return api.w.GetSymKey(id)
-}
-
-// DeleteSymKey deletes the symmetric key that is associated with the given id.
-func (api *PublicWhisperAPI) DeleteSymKey(ctx context.Context, id string) bool {
- return api.w.DeleteSymKey(id)
-}
-
-//go:generate gencodec -type NewMessage -field-override newMessageOverride -out gen_newmessage_json.go
-
-// NewMessage represents a new whisper message that is posted through the RPC.
-type NewMessage struct {
- SymKeyID string `json:"symKeyID"`
- PublicKey []byte `json:"pubKey"`
- Sig string `json:"sig"`
- TTL uint32 `json:"ttl"`
- Topic TopicType `json:"topic"`
- Payload []byte `json:"payload"`
- Padding []byte `json:"padding"`
- PowTime uint32 `json:"powTime"`
- PowTarget float64 `json:"powTarget"`
- TargetPeer string `json:"targetPeer"`
-}
-
-type newMessageOverride struct {
- PublicKey hexutil.Bytes
- Payload hexutil.Bytes
- Padding hexutil.Bytes
-}
-
-// Post a message on the Whisper network.
-func (api *PublicWhisperAPI) Post(ctx context.Context, req NewMessage) (bool, error) {
- var (
- symKeyGiven = len(req.SymKeyID) > 0
- pubKeyGiven = len(req.PublicKey) > 0
- err error
- )
-
- // user must specify either a symmetric or an asymmetric key
- if (symKeyGiven && pubKeyGiven) || (!symKeyGiven && !pubKeyGiven) {
- return false, ErrSymAsym
- }
-
- params := &MessageParams{
- TTL: req.TTL,
- Payload: req.Payload,
- Padding: req.Padding,
- WorkTime: req.PowTime,
- PoW: req.PowTarget,
- Topic: req.Topic,
- }
-
- // Set key that is used to sign the message
- if len(req.Sig) > 0 {
- if params.Src, err = api.w.GetPrivateKey(req.Sig); err != nil {
- return false, err
- }
- }
-
- // Set symmetric key that is used to encrypt the message
- if symKeyGiven {
- if params.Topic == (TopicType{}) { // topics are mandatory with symmetric encryption
- return false, ErrNoTopics
- }
- if params.KeySym, err = api.w.GetSymKey(req.SymKeyID); err != nil {
- return false, err
- }
- if !validateSymmetricKey(params.KeySym) {
- return false, ErrInvalidSymmetricKey
- }
- }
-
- // Set asymmetric key that is used to encrypt the message
- if pubKeyGiven {
- params.Dst = crypto.ToECDSAPub(req.PublicKey)
- if !ValidatePublicKey(params.Dst) {
- return false, ErrInvalidPublicKey
- }
- }
-
- // encrypt and sent message
- whisperMsg, err := NewSentMessage(params)
- if err != nil {
- return false, err
- }
-
- env, err := whisperMsg.Wrap(params)
- if err != nil {
- return false, err
- }
-
- // send to specific node (skip PoW check)
- if len(req.TargetPeer) > 0 {
- n, err := discover.ParseNode(req.TargetPeer)
- if err != nil {
- return false, fmt.Errorf("failed to parse target peer: %s", err)
- }
- return true, api.w.SendP2PMessage(n.ID[:], env)
- }
-
- // ensure that the message PoW meets the node's minimum accepted PoW
- if req.PowTarget < api.w.MinPow() {
- return false, ErrTooLowPoW
- }
-
- return true, api.w.Send(env)
-}
-
-//go:generate gencodec -type Criteria -field-override criteriaOverride -out gen_criteria_json.go
-
-// Criteria holds various filter options for inbound messages.
-type Criteria struct {
- SymKeyID string `json:"symKeyID"`
- PrivateKeyID string `json:"privateKeyID"`
- Sig []byte `json:"sig"`
- MinPow float64 `json:"minPow"`
- Topics []TopicType `json:"topics"`
- AllowP2P bool `json:"allowP2P"`
-}
-
-type criteriaOverride struct {
- Sig hexutil.Bytes
-}
-
-// Messages set up a subscription that fires events when messages arrive that match
-// the given set of criteria.
-func (api *PublicWhisperAPI) Messages(ctx context.Context, crit Criteria) (*rpc.Subscription, error) {
- var (
- symKeyGiven = len(crit.SymKeyID) > 0
- pubKeyGiven = len(crit.PrivateKeyID) > 0
- err error
- )
-
- // ensure that the RPC connection supports subscriptions
- notifier, supported := rpc.NotifierFromContext(ctx)
- if !supported {
- return nil, rpc.ErrNotificationsUnsupported
- }
-
- // user must specify either a symmetric or an asymmetric key
- if (symKeyGiven && pubKeyGiven) || (!symKeyGiven && !pubKeyGiven) {
- return nil, ErrSymAsym
- }
-
- filter := Filter{
- PoW: crit.MinPow,
- Messages: make(map[common.Hash]*ReceivedMessage),
- AllowP2P: crit.AllowP2P,
- }
-
- if len(crit.Sig) > 0 {
- filter.Src = crypto.ToECDSAPub(crit.Sig)
- if !ValidatePublicKey(filter.Src) {
- return nil, ErrInvalidSigningPubKey
- }
- }
-
- for i, bt := range crit.Topics {
- if len(bt) == 0 || len(bt) > 4 {
- return nil, fmt.Errorf("subscribe: topic %d has wrong size: %d", i, len(bt))
- }
- filter.Topics = append(filter.Topics, bt[:])
- }
-
- // listen for message that are encrypted with the given symmetric key
- if symKeyGiven {
- if len(filter.Topics) == 0 {
- return nil, ErrNoTopics
- }
- key, err := api.w.GetSymKey(crit.SymKeyID)
- if err != nil {
- return nil, err
- }
- if !validateSymmetricKey(key) {
- return nil, ErrInvalidSymmetricKey
- }
- filter.KeySym = key
- filter.SymKeyHash = crypto.Keccak256Hash(filter.KeySym)
- }
-
- // listen for messages that are encrypted with the given public key
- if pubKeyGiven {
- filter.KeyAsym, err = api.w.GetPrivateKey(crit.PrivateKeyID)
- if err != nil || filter.KeyAsym == nil {
- return nil, ErrInvalidPublicKey
- }
- }
-
- id, err := api.w.Subscribe(&filter)
- if err != nil {
- return nil, err
- }
-
- // create subscription and start waiting for message events
- rpcSub := notifier.CreateSubscription()
- go func() {
- // for now poll internally, refactor whisper internal for channel support
- ticker := time.NewTicker(250 * time.Millisecond)
- defer ticker.Stop()
-
- for {
- select {
- case <-ticker.C:
- if filter := api.w.GetFilter(id); filter != nil {
- for _, rpcMessage := range toMessage(filter.Retrieve()) {
- if err := notifier.Notify(rpcSub.ID, rpcMessage); err != nil {
- log.Error("Failed to send notification", "err", err)
- }
- }
- }
- case <-rpcSub.Err():
- api.w.Unsubscribe(id)
- return
- case <-notifier.Closed():
- api.w.Unsubscribe(id)
- return
- }
- }
- }()
-
- return rpcSub, nil
-}
-
-//go:generate gencodec -type Message -field-override messageOverride -out gen_message_json.go
-
-// Message is the RPC representation of a whisper message.
-type Message struct {
- Sig []byte `json:"sig,omitempty"`
- TTL uint32 `json:"ttl"`
- Timestamp uint32 `json:"timestamp"`
- Topic TopicType `json:"topic"`
- Payload []byte `json:"payload"`
- Padding []byte `json:"padding"`
- PoW float64 `json:"pow"`
- Hash []byte `json:"hash"`
- Dst []byte `json:"recipientPublicKey,omitempty"`
-}
-
-type messageOverride struct {
- Sig hexutil.Bytes
- Payload hexutil.Bytes
- Padding hexutil.Bytes
- Hash hexutil.Bytes
- Dst hexutil.Bytes
-}
-
-// ToWhisperMessage converts an internal message into an API version.
-func ToWhisperMessage(message *ReceivedMessage) *Message {
- msg := Message{
- Payload: message.Payload,
- Padding: message.Padding,
- Timestamp: message.Sent,
- TTL: message.TTL,
- PoW: message.PoW,
- Hash: message.EnvelopeHash.Bytes(),
- Topic: message.Topic,
- }
-
- if message.Dst != nil {
- b := crypto.FromECDSAPub(message.Dst)
- if b != nil {
- msg.Dst = b
- }
- }
-
- if isMessageSigned(message.Raw[0]) {
- b := crypto.FromECDSAPub(message.SigToPubKey())
- if b != nil {
- msg.Sig = b
- }
- }
-
- return &msg
-}
-
-// toMessage converts a set of messages to its RPC representation.
-func toMessage(messages []*ReceivedMessage) []*Message {
- msgs := make([]*Message, len(messages))
- for i, msg := range messages {
- msgs[i] = ToWhisperMessage(msg)
- }
- return msgs
-}
-
-// GetFilterMessages returns the messages that match the filter criteria and
-// are received between the last poll and now.
-func (api *PublicWhisperAPI) GetFilterMessages(id string) ([]*Message, error) {
- api.mu.Lock()
- f := api.w.GetFilter(id)
- if f == nil {
- api.mu.Unlock()
- return nil, fmt.Errorf("filter not found")
- }
- api.lastUsed[id] = time.Now()
- api.mu.Unlock()
-
- receivedMessages := f.Retrieve()
- messages := make([]*Message, 0, len(receivedMessages))
- for _, msg := range receivedMessages {
- messages = append(messages, ToWhisperMessage(msg))
- }
-
- return messages, nil
-}
-
-// DeleteMessageFilter deletes a filter.
-func (api *PublicWhisperAPI) DeleteMessageFilter(id string) (bool, error) {
- api.mu.Lock()
- defer api.mu.Unlock()
-
- delete(api.lastUsed, id)
- return true, api.w.Unsubscribe(id)
-}
-
-// NewMessageFilter creates a new filter that can be used to poll for
-// (new) messages that satisfy the given criteria.
-func (api *PublicWhisperAPI) NewMessageFilter(req Criteria) (string, error) {
- var (
- src *ecdsa.PublicKey
- keySym []byte
- keyAsym *ecdsa.PrivateKey
- topics [][]byte
-
- symKeyGiven = len(req.SymKeyID) > 0
- asymKeyGiven = len(req.PrivateKeyID) > 0
-
- err error
- )
-
- // user must specify either a symmetric or an asymmetric key
- if (symKeyGiven && asymKeyGiven) || (!symKeyGiven && !asymKeyGiven) {
- return "", ErrSymAsym
- }
-
- if len(req.Sig) > 0 {
- src = crypto.ToECDSAPub(req.Sig)
- if !ValidatePublicKey(src) {
- return "", ErrInvalidSigningPubKey
- }
- }
-
- if symKeyGiven {
- if keySym, err = api.w.GetSymKey(req.SymKeyID); err != nil {
- return "", err
- }
- if !validateSymmetricKey(keySym) {
- return "", ErrInvalidSymmetricKey
- }
- }
-
- if asymKeyGiven {
- if keyAsym, err = api.w.GetPrivateKey(req.PrivateKeyID); err != nil {
- return "", err
- }
- }
-
- if len(req.Topics) > 0 {
- topics = make([][]byte, 1)
- for _, topic := range req.Topics {
- topics = append(topics, topic[:])
- }
- }
-
- f := &Filter{
- Src: src,
- KeySym: keySym,
- KeyAsym: keyAsym,
- PoW: req.MinPow,
- AllowP2P: req.AllowP2P,
- Topics: topics,
- Messages: make(map[common.Hash]*ReceivedMessage),
- }
-
- id, err := api.w.Subscribe(f)
- if err != nil {
- return "", err
- }
-
- api.mu.Lock()
- api.lastUsed[id] = time.Now()
- api.mu.Unlock()
-
- return id, nil
-}
diff --git a/whisper/whisperv5/benchmarks_test.go b/whisper/whisperv5/benchmarks_test.go
deleted file mode 100644
index dcfbcb56d847..000000000000
--- a/whisper/whisperv5/benchmarks_test.go
+++ /dev/null
@@ -1,206 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv5
-
-import (
- "testing"
-
- "github.com/ethereum/go-ethereum/crypto"
-)
-
-func BenchmarkDeriveKeyMaterial(b *testing.B) {
- for i := 0; i < b.N; i++ {
- deriveKeyMaterial([]byte("test"), 0)
- }
-}
-
-func BenchmarkEncryptionSym(b *testing.B) {
- InitSingleTest()
-
- params, err := generateMessageParams()
- if err != nil {
- b.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- for i := 0; i < b.N; i++ {
- msg, _ := NewSentMessage(params)
- _, err := msg.Wrap(params)
- if err != nil {
- b.Errorf("failed Wrap with seed %d: %s.", seed, err)
- b.Errorf("i = %d, len(msg.Raw) = %d, params.Payload = %d.", i, len(msg.Raw), len(params.Payload))
- return
- }
- }
-}
-
-func BenchmarkEncryptionAsym(b *testing.B) {
- InitSingleTest()
-
- params, err := generateMessageParams()
- if err != nil {
- b.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- key, err := crypto.GenerateKey()
- if err != nil {
- b.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
- }
- params.KeySym = nil
- params.Dst = &key.PublicKey
-
- for i := 0; i < b.N; i++ {
- msg, _ := NewSentMessage(params)
- _, err := msg.Wrap(params)
- if err != nil {
- b.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
- }
-}
-
-func BenchmarkDecryptionSymValid(b *testing.B) {
- InitSingleTest()
-
- params, err := generateMessageParams()
- if err != nil {
- b.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- msg, _ := NewSentMessage(params)
- env, err := msg.Wrap(params)
- if err != nil {
- b.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
- f := Filter{KeySym: params.KeySym}
-
- for i := 0; i < b.N; i++ {
- msg := env.Open(&f)
- if msg == nil {
- b.Fatalf("failed to open with seed %d.", seed)
- }
- }
-}
-
-func BenchmarkDecryptionSymInvalid(b *testing.B) {
- InitSingleTest()
-
- params, err := generateMessageParams()
- if err != nil {
- b.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- msg, _ := NewSentMessage(params)
- env, err := msg.Wrap(params)
- if err != nil {
- b.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
- f := Filter{KeySym: []byte("arbitrary stuff here")}
-
- for i := 0; i < b.N; i++ {
- msg := env.Open(&f)
- if msg != nil {
- b.Fatalf("opened envelope with invalid key, seed: %d.", seed)
- }
- }
-}
-
-func BenchmarkDecryptionAsymValid(b *testing.B) {
- InitSingleTest()
-
- params, err := generateMessageParams()
- if err != nil {
- b.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- key, err := crypto.GenerateKey()
- if err != nil {
- b.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
- }
- f := Filter{KeyAsym: key}
- params.KeySym = nil
- params.Dst = &key.PublicKey
- msg, _ := NewSentMessage(params)
- env, err := msg.Wrap(params)
- if err != nil {
- b.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- for i := 0; i < b.N; i++ {
- msg := env.Open(&f)
- if msg == nil {
- b.Fatalf("fail to open, seed: %d.", seed)
- }
- }
-}
-
-func BenchmarkDecryptionAsymInvalid(b *testing.B) {
- InitSingleTest()
-
- params, err := generateMessageParams()
- if err != nil {
- b.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- key, err := crypto.GenerateKey()
- if err != nil {
- b.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
- }
- params.KeySym = nil
- params.Dst = &key.PublicKey
- msg, _ := NewSentMessage(params)
- env, err := msg.Wrap(params)
- if err != nil {
- b.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- key, err = crypto.GenerateKey()
- if err != nil {
- b.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
- }
- f := Filter{KeyAsym: key}
-
- for i := 0; i < b.N; i++ {
- msg := env.Open(&f)
- if msg != nil {
- b.Fatalf("opened envelope with invalid key, seed: %d.", seed)
- }
- }
-}
-
-func increment(x []byte) {
- for i := 0; i < len(x); i++ {
- x[i]++
- if x[i] != 0 {
- break
- }
- }
-}
-
-func BenchmarkPoW(b *testing.B) {
- InitSingleTest()
-
- params, err := generateMessageParams()
- if err != nil {
- b.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- params.Payload = make([]byte, 32)
- params.PoW = 10.0
- params.TTL = 1
-
- for i := 0; i < b.N; i++ {
- increment(params.Payload)
- msg, _ := NewSentMessage(params)
- _, err := msg.Wrap(params)
- if err != nil {
- b.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
- }
-}
diff --git a/whisper/whisperv5/config.go b/whisper/whisperv5/config.go
deleted file mode 100644
index fcc2307046aa..000000000000
--- a/whisper/whisperv5/config.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2017 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv5
-
-type Config struct {
- MaxMessageSize uint32 `toml:",omitempty"`
- MinimumAcceptedPOW float64 `toml:",omitempty"`
-}
-
-var DefaultConfig = Config{
- MaxMessageSize: DefaultMaxMessageSize,
- MinimumAcceptedPOW: DefaultMinimumPoW,
-}
diff --git a/whisper/whisperv5/doc.go b/whisper/whisperv5/doc.go
deleted file mode 100644
index 7a57488bd7a3..000000000000
--- a/whisper/whisperv5/doc.go
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-/*
-Package whisper implements the Whisper protocol (version 5).
-
-Whisper combines aspects of both DHTs and datagram messaging systems (e.g. UDP).
-As such it may be likened and compared to both, not dissimilar to the
-matter/energy duality (apologies to physicists for the blatant abuse of a
-fundamental and beautiful natural principle).
-
-Whisper is a pure identity-based messaging system. Whisper provides a low-level
-(non-application-specific) but easily-accessible API without being based upon
-or prejudiced by the low-level hardware attributes and characteristics,
-particularly the notion of singular endpoints.
-*/
-package whisperv5
-
-import (
- "fmt"
- "time"
-)
-
-const (
- EnvelopeVersion = uint64(0)
- ProtocolVersion = uint64(5)
- ProtocolVersionStr = "5.0"
- ProtocolName = "shh"
-
- statusCode = 0 // used by whisper protocol
- messagesCode = 1 // normal whisper message
- p2pCode = 2 // peer-to-peer message (to be consumed by the peer, but not forwarded any further)
- p2pRequestCode = 3 // peer-to-peer message, used by Dapp protocol
- NumberOfMessageCodes = 64
-
- paddingMask = byte(3)
- signatureFlag = byte(4)
-
- TopicLength = 4
- signatureLength = 65
- aesKeyLength = 32
- AESNonceLength = 12
- keyIdSize = 32
-
- MaxMessageSize = uint32(10 * 1024 * 1024) // maximum accepted size of a message.
- DefaultMaxMessageSize = uint32(1024 * 1024)
- DefaultMinimumPoW = 0.2
-
- padSizeLimit = 256 // just an arbitrary number, could be changed without breaking the protocol (must not exceed 2^24)
- messageQueueLimit = 1024
-
- expirationCycle = time.Second
- transmissionCycle = 300 * time.Millisecond
-
- DefaultTTL = 50 // seconds
- SynchAllowance = 10 // seconds
-)
-
-type unknownVersionError uint64
-
-func (e unknownVersionError) Error() string {
- return fmt.Sprintf("invalid envelope version %d", uint64(e))
-}
-
-// MailServer represents a mail server, capable of
-// archiving the old messages for subsequent delivery
-// to the peers. Any implementation must ensure that both
-// functions are thread-safe. Also, they must return ASAP.
-// DeliverMail should use directMessagesCode for delivery,
-// in order to bypass the expiry checks.
-type MailServer interface {
- Archive(env *Envelope)
- DeliverMail(whisperPeer *Peer, request *Envelope)
-}
diff --git a/whisper/whisperv5/envelope.go b/whisper/whisperv5/envelope.go
deleted file mode 100644
index 169cbba9dde6..000000000000
--- a/whisper/whisperv5/envelope.go
+++ /dev/null
@@ -1,246 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains the Whisper protocol Envelope element.
-
-package whisperv5
-
-import (
- "crypto/ecdsa"
- "encoding/binary"
- "fmt"
- gmath "math"
- "math/big"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/ecies"
- "github.com/ethereum/go-ethereum/rlp"
-)
-
-// Envelope represents a clear-text data packet to transmit through the Whisper
-// network. Its contents may or may not be encrypted and signed.
-type Envelope struct {
- Version []byte
- Expiry uint32
- TTL uint32
- Topic TopicType
- AESNonce []byte
- Data []byte
- EnvNonce uint64
-
- pow float64 // Message-specific PoW as described in the Whisper specification.
- hash common.Hash // Cached hash of the envelope to avoid rehashing every time.
- // Don't access hash directly, use Hash() function instead.
-}
-
-// size returns the size of envelope as it is sent (i.e. public fields only)
-func (e *Envelope) size() int {
- return 20 + len(e.Version) + len(e.AESNonce) + len(e.Data)
-}
-
-// rlpWithoutNonce returns the RLP encoded envelope contents, except the nonce.
-func (e *Envelope) rlpWithoutNonce() []byte {
- res, _ := rlp.EncodeToBytes([]interface{}{e.Version, e.Expiry, e.TTL, e.Topic, e.AESNonce, e.Data})
- return res
-}
-
-// NewEnvelope wraps a Whisper message with expiration and destination data
-// included into an envelope for network forwarding.
-func NewEnvelope(ttl uint32, topic TopicType, aesNonce []byte, msg *sentMessage) *Envelope {
- env := Envelope{
- Version: make([]byte, 1),
- Expiry: uint32(time.Now().Add(time.Second * time.Duration(ttl)).Unix()),
- TTL: ttl,
- Topic: topic,
- AESNonce: aesNonce,
- Data: msg.Raw,
- EnvNonce: 0,
- }
-
- if EnvelopeVersion < 256 {
- env.Version[0] = byte(EnvelopeVersion)
- } else {
- panic("please increase the size of Envelope.Version before releasing this version")
- }
-
- return &env
-}
-
-func (e *Envelope) IsSymmetric() bool {
- return len(e.AESNonce) > 0
-}
-
-func (e *Envelope) isAsymmetric() bool {
- return !e.IsSymmetric()
-}
-
-func (e *Envelope) Ver() uint64 {
- return bytesToUintLittleEndian(e.Version)
-}
-
-// Seal closes the envelope by spending the requested amount of time as a proof
-// of work on hashing the data.
-func (e *Envelope) Seal(options *MessageParams) error {
- var target, bestBit int
- if options.PoW == 0 {
- // adjust for the duration of Seal() execution only if execution time is predefined unconditionally
- e.Expiry += options.WorkTime
- } else {
- target = e.powToFirstBit(options.PoW)
- if target < 1 {
- target = 1
- }
- }
-
- buf := make([]byte, 64)
- h := crypto.Keccak256(e.rlpWithoutNonce())
- copy(buf[:32], h)
-
- finish := time.Now().Add(time.Duration(options.WorkTime) * time.Second).UnixNano()
- for nonce := uint64(0); time.Now().UnixNano() < finish; {
- for i := 0; i < 1024; i++ {
- binary.BigEndian.PutUint64(buf[56:], nonce)
- d := new(big.Int).SetBytes(crypto.Keccak256(buf))
- firstBit := math.FirstBitSet(d)
- if firstBit > bestBit {
- e.EnvNonce, bestBit = nonce, firstBit
- if target > 0 && bestBit >= target {
- return nil
- }
- }
- nonce++
- }
- }
-
- if target > 0 && bestBit < target {
- return fmt.Errorf("failed to reach the PoW target, specified pow time (%d seconds) was insufficient", options.WorkTime)
- }
-
- return nil
-}
-
-func (e *Envelope) PoW() float64 {
- if e.pow == 0 {
- e.calculatePoW(0)
- }
- return e.pow
-}
-
-func (e *Envelope) calculatePoW(diff uint32) {
- buf := make([]byte, 64)
- h := crypto.Keccak256(e.rlpWithoutNonce())
- copy(buf[:32], h)
- binary.BigEndian.PutUint64(buf[56:], e.EnvNonce)
- d := new(big.Int).SetBytes(crypto.Keccak256(buf))
- firstBit := math.FirstBitSet(d)
- x := gmath.Pow(2, float64(firstBit))
- x /= float64(e.size())
- x /= float64(e.TTL + diff)
- e.pow = x
-}
-
-func (e *Envelope) powToFirstBit(pow float64) int {
- x := pow
- x *= float64(e.size())
- x *= float64(e.TTL)
- bits := gmath.Log2(x)
- bits = gmath.Ceil(bits)
- return int(bits)
-}
-
-// Hash returns the SHA3 hash of the envelope, calculating it if not yet done.
-func (e *Envelope) Hash() common.Hash {
- if (e.hash == common.Hash{}) {
- encoded, _ := rlp.EncodeToBytes(e)
- e.hash = crypto.Keccak256Hash(encoded)
- }
- return e.hash
-}
-
-// DecodeRLP decodes an Envelope from an RLP data stream.
-func (e *Envelope) DecodeRLP(s *rlp.Stream) error {
- raw, err := s.Raw()
- if err != nil {
- return err
- }
- // The decoding of Envelope uses the struct fields but also needs
- // to compute the hash of the whole RLP-encoded envelope. This
- // type has the same structure as Envelope but is not an
- // rlp.Decoder (does not implement DecodeRLP function).
- // Only public members will be encoded.
- type rlpenv Envelope
- if err := rlp.DecodeBytes(raw, (*rlpenv)(e)); err != nil {
- return err
- }
- e.hash = crypto.Keccak256Hash(raw)
- return nil
-}
-
-// OpenAsymmetric tries to decrypt an envelope, potentially encrypted with a particular key.
-func (e *Envelope) OpenAsymmetric(key *ecdsa.PrivateKey) (*ReceivedMessage, error) {
- message := &ReceivedMessage{Raw: e.Data}
- err := message.decryptAsymmetric(key)
- switch err {
- case nil:
- return message, nil
- case ecies.ErrInvalidPublicKey: // addressed to somebody else
- return nil, err
- default:
- return nil, fmt.Errorf("unable to open envelope, decrypt failed: %v", err)
- }
-}
-
-// OpenSymmetric tries to decrypt an envelope, potentially encrypted with a particular key.
-func (e *Envelope) OpenSymmetric(key []byte) (msg *ReceivedMessage, err error) {
- msg = &ReceivedMessage{Raw: e.Data}
- err = msg.decryptSymmetric(key, e.AESNonce)
- if err != nil {
- msg = nil
- }
- return msg, err
-}
-
-// Open tries to decrypt an envelope, and populates the message fields in case of success.
-func (e *Envelope) Open(watcher *Filter) (msg *ReceivedMessage) {
- if e.isAsymmetric() {
- msg, _ = e.OpenAsymmetric(watcher.KeyAsym)
- if msg != nil {
- msg.Dst = &watcher.KeyAsym.PublicKey
- }
- } else if e.IsSymmetric() {
- msg, _ = e.OpenSymmetric(watcher.KeySym)
- if msg != nil {
- msg.SymKeyHash = crypto.Keccak256Hash(watcher.KeySym)
- }
- }
-
- if msg != nil {
- ok := msg.Validate()
- if !ok {
- return nil
- }
- msg.Topic = e.Topic
- msg.PoW = e.PoW()
- msg.TTL = e.TTL
- msg.Sent = e.Expiry - e.TTL
- msg.EnvelopeHash = e.Hash()
- msg.EnvelopeVersion = e.Ver()
- }
- return msg
-}
diff --git a/whisper/whisperv5/filter.go b/whisper/whisperv5/filter.go
deleted file mode 100644
index b5e893e0ff5c..000000000000
--- a/whisper/whisperv5/filter.go
+++ /dev/null
@@ -1,239 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv5
-
-import (
- "crypto/ecdsa"
- "fmt"
- "sync"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
-)
-
-type Filter struct {
- Src *ecdsa.PublicKey // Sender of the message
- KeyAsym *ecdsa.PrivateKey // Private Key of recipient
- KeySym []byte // Key associated with the Topic
- Topics [][]byte // Topics to filter messages with
- PoW float64 // Proof of work as described in the Whisper spec
- AllowP2P bool // Indicates whether this filter is interested in direct peer-to-peer messages
- SymKeyHash common.Hash // The Keccak256Hash of the symmetric key, needed for optimization
-
- Messages map[common.Hash]*ReceivedMessage
- mutex sync.RWMutex
-}
-
-type Filters struct {
- watchers map[string]*Filter
- whisper *Whisper
- mutex sync.RWMutex
-}
-
-func NewFilters(w *Whisper) *Filters {
- return &Filters{
- watchers: make(map[string]*Filter),
- whisper: w,
- }
-}
-
-func (fs *Filters) Install(watcher *Filter) (string, error) {
- if watcher.Messages == nil {
- watcher.Messages = make(map[common.Hash]*ReceivedMessage)
- }
-
- id, err := GenerateRandomID()
- if err != nil {
- return "", err
- }
-
- fs.mutex.Lock()
- defer fs.mutex.Unlock()
-
- if fs.watchers[id] != nil {
- return "", fmt.Errorf("failed to generate unique ID")
- }
-
- if watcher.expectsSymmetricEncryption() {
- watcher.SymKeyHash = crypto.Keccak256Hash(watcher.KeySym)
- }
-
- fs.watchers[id] = watcher
- return id, err
-}
-
-func (fs *Filters) Uninstall(id string) bool {
- fs.mutex.Lock()
- defer fs.mutex.Unlock()
- if fs.watchers[id] != nil {
- delete(fs.watchers, id)
- return true
- }
- return false
-}
-
-func (fs *Filters) Get(id string) *Filter {
- fs.mutex.RLock()
- defer fs.mutex.RUnlock()
- return fs.watchers[id]
-}
-
-func (fs *Filters) NotifyWatchers(env *Envelope, p2pMessage bool) {
- var msg *ReceivedMessage
-
- fs.mutex.RLock()
- defer fs.mutex.RUnlock()
-
- i := -1 // only used for logging info
- for _, watcher := range fs.watchers {
- i++
- if p2pMessage && !watcher.AllowP2P {
- log.Trace(fmt.Sprintf("msg [%x], filter [%d]: p2p messages are not allowed", env.Hash(), i))
- continue
- }
-
- var match bool
- if msg != nil {
- match = watcher.MatchMessage(msg)
- } else {
- match = watcher.MatchEnvelope(env)
- if match {
- msg = env.Open(watcher)
- if msg == nil {
- log.Trace("processing message: failed to open", "message", env.Hash().Hex(), "filter", i)
- }
- } else {
- log.Trace("processing message: does not match", "message", env.Hash().Hex(), "filter", i)
- }
- }
-
- if match && msg != nil {
- log.Trace("processing message: decrypted", "hash", env.Hash().Hex())
- if watcher.Src == nil || IsPubKeyEqual(msg.Src, watcher.Src) {
- watcher.Trigger(msg)
- }
- }
- }
-}
-
-func (f *Filter) processEnvelope(env *Envelope) *ReceivedMessage {
- if f.MatchEnvelope(env) {
- msg := env.Open(f)
- if msg != nil {
- return msg
- } else {
- log.Trace("processing envelope: failed to open", "hash", env.Hash().Hex())
- }
- } else {
- log.Trace("processing envelope: does not match", "hash", env.Hash().Hex())
- }
- return nil
-}
-
-func (f *Filter) expectsAsymmetricEncryption() bool {
- return f.KeyAsym != nil
-}
-
-func (f *Filter) expectsSymmetricEncryption() bool {
- return f.KeySym != nil
-}
-
-func (f *Filter) Trigger(msg *ReceivedMessage) {
- f.mutex.Lock()
- defer f.mutex.Unlock()
-
- if _, exist := f.Messages[msg.EnvelopeHash]; !exist {
- f.Messages[msg.EnvelopeHash] = msg
- }
-}
-
-func (f *Filter) Retrieve() (all []*ReceivedMessage) {
- f.mutex.Lock()
- defer f.mutex.Unlock()
-
- all = make([]*ReceivedMessage, 0, len(f.Messages))
- for _, msg := range f.Messages {
- all = append(all, msg)
- }
-
- f.Messages = make(map[common.Hash]*ReceivedMessage) // delete old messages
- return all
-}
-
-func (f *Filter) MatchMessage(msg *ReceivedMessage) bool {
- if f.PoW > 0 && msg.PoW < f.PoW {
- return false
- }
-
- if f.expectsAsymmetricEncryption() && msg.isAsymmetricEncryption() {
- return IsPubKeyEqual(&f.KeyAsym.PublicKey, msg.Dst) && f.MatchTopic(msg.Topic)
- } else if f.expectsSymmetricEncryption() && msg.isSymmetricEncryption() {
- return f.SymKeyHash == msg.SymKeyHash && f.MatchTopic(msg.Topic)
- }
- return false
-}
-
-func (f *Filter) MatchEnvelope(envelope *Envelope) bool {
- if f.PoW > 0 && envelope.pow < f.PoW {
- return false
- }
-
- if f.expectsAsymmetricEncryption() && envelope.isAsymmetric() {
- return f.MatchTopic(envelope.Topic)
- } else if f.expectsSymmetricEncryption() && envelope.IsSymmetric() {
- return f.MatchTopic(envelope.Topic)
- }
- return false
-}
-
-func (f *Filter) MatchTopic(topic TopicType) bool {
- if len(f.Topics) == 0 {
- // any topic matches
- return true
- }
-
- for _, bt := range f.Topics {
- if matchSingleTopic(topic, bt) {
- return true
- }
- }
- return false
-}
-
-func matchSingleTopic(topic TopicType, bt []byte) bool {
- if len(bt) > 4 {
- bt = bt[:4]
- }
-
- for j, b := range bt {
- if topic[j] != b {
- return false
- }
- }
- return true
-}
-
-func IsPubKeyEqual(a, b *ecdsa.PublicKey) bool {
- if !ValidatePublicKey(a) {
- return false
- } else if !ValidatePublicKey(b) {
- return false
- }
- // the curve is always the same, just compare the points
- return a.X.Cmp(b.X) == 0 && a.Y.Cmp(b.Y) == 0
-}
diff --git a/whisper/whisperv5/filter_test.go b/whisper/whisperv5/filter_test.go
deleted file mode 100644
index bd35e7f20f58..000000000000
--- a/whisper/whisperv5/filter_test.go
+++ /dev/null
@@ -1,814 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv5
-
-import (
- "math/big"
- mrand "math/rand"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
-)
-
-var seed int64
-
-// InitSingleTest should be called in the beginning of every
-// test, which uses RNG, in order to make the tests
-// reproduciblity independent of their sequence.
-func InitSingleTest() {
- seed = time.Now().Unix()
- mrand.Seed(seed)
-}
-
-func InitDebugTest(i int64) {
- seed = i
- mrand.Seed(seed)
-}
-
-type FilterTestCase struct {
- f *Filter
- id string
- alive bool
- msgCnt int
-}
-
-func generateFilter(t *testing.T, symmetric bool) (*Filter, error) {
- var f Filter
- f.Messages = make(map[common.Hash]*ReceivedMessage)
-
- const topicNum = 8
- f.Topics = make([][]byte, topicNum)
- for i := 0; i < topicNum; i++ {
- f.Topics[i] = make([]byte, 4)
- mrand.Read(f.Topics[i][:])
- f.Topics[i][0] = 0x01
- }
-
- key, err := crypto.GenerateKey()
- if err != nil {
- t.Fatalf("generateFilter 1 failed with seed %d.", seed)
- return nil, err
- }
- f.Src = &key.PublicKey
-
- if symmetric {
- f.KeySym = make([]byte, aesKeyLength)
- mrand.Read(f.KeySym)
- f.SymKeyHash = crypto.Keccak256Hash(f.KeySym)
- } else {
- f.KeyAsym, err = crypto.GenerateKey()
- if err != nil {
- t.Fatalf("generateFilter 2 failed with seed %d.", seed)
- return nil, err
- }
- }
-
- // AcceptP2P & PoW are not set
- return &f, nil
-}
-
-func generateTestCases(t *testing.T, SizeTestFilters int) []FilterTestCase {
- cases := make([]FilterTestCase, SizeTestFilters)
- for i := 0; i < SizeTestFilters; i++ {
- f, _ := generateFilter(t, true)
- cases[i].f = f
- cases[i].alive = (mrand.Int()&int(1) == 0)
- }
- return cases
-}
-
-func TestInstallFilters(t *testing.T) {
- InitSingleTest()
-
- const SizeTestFilters = 256
- w := New(&Config{})
- filters := NewFilters(w)
- tst := generateTestCases(t, SizeTestFilters)
-
- var err error
- var j string
- for i := 0; i < SizeTestFilters; i++ {
- j, err = filters.Install(tst[i].f)
- if err != nil {
- t.Fatalf("seed %d: failed to install filter: %s", seed, err)
- }
- tst[i].id = j
- if len(j) != keyIdSize*2 {
- t.Fatalf("seed %d: wrong filter id size [%d]", seed, len(j))
- }
- }
-
- for _, testCase := range tst {
- if !testCase.alive {
- filters.Uninstall(testCase.id)
- }
- }
-
- for i, testCase := range tst {
- fil := filters.Get(testCase.id)
- exist := (fil != nil)
- if exist != testCase.alive {
- t.Fatalf("seed %d: failed alive: %d, %v, %v", seed, i, exist, testCase.alive)
- }
- if exist && fil.PoW != testCase.f.PoW {
- t.Fatalf("seed %d: failed Get: %d, %v, %v", seed, i, exist, testCase.alive)
- }
- }
-}
-
-func TestInstallSymKeyGeneratesHash(t *testing.T) {
- InitSingleTest()
-
- w := New(&Config{})
- filters := NewFilters(w)
- filter, _ := generateFilter(t, true)
-
- // save the current SymKeyHash for comparison
- initialSymKeyHash := filter.SymKeyHash
-
- // ensure the SymKeyHash is invalid, for Install to recreate it
- var invalid common.Hash
- filter.SymKeyHash = invalid
-
- _, err := filters.Install(filter)
-
- if err != nil {
- t.Fatalf("Error installing the filter: %s", err)
- }
-
- for i, b := range filter.SymKeyHash {
- if b != initialSymKeyHash[i] {
- t.Fatalf("The filter's symmetric key hash was not properly generated by Install")
- }
- }
-}
-
-func TestInstallIdenticalFilters(t *testing.T) {
- InitSingleTest()
-
- w := New(&Config{})
- filters := NewFilters(w)
- filter1, _ := generateFilter(t, true)
-
- // Copy the first filter since some of its fields
- // are randomly gnerated.
- filter2 := &Filter{
- KeySym: filter1.KeySym,
- Topics: filter1.Topics,
- PoW: filter1.PoW,
- AllowP2P: filter1.AllowP2P,
- Messages: make(map[common.Hash]*ReceivedMessage),
- }
-
- _, err := filters.Install(filter1)
-
- if err != nil {
- t.Fatalf("Error installing the first filter with seed %d: %s", seed, err)
- }
-
- _, err = filters.Install(filter2)
-
- if err != nil {
- t.Fatalf("Error installing the second filter with seed %d: %s", seed, err)
- }
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("Error generating message parameters with seed %d: %s", seed, err)
- }
-
- params.KeySym = filter1.KeySym
- params.Topic = BytesToTopic(filter1.Topics[0])
-
- filter1.Src = ¶ms.Src.PublicKey
- filter2.Src = ¶ms.Src.PublicKey
-
- sentMessage, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := sentMessage.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
- msg := env.Open(filter1)
- if msg == nil {
- t.Fatalf("failed to Open with filter1")
- }
-
- if !filter1.MatchEnvelope(env) {
- t.Fatalf("failed matching with the first filter")
- }
-
- if !filter2.MatchEnvelope(env) {
- t.Fatalf("failed matching with the first filter")
- }
-
- if !filter1.MatchMessage(msg) {
- t.Fatalf("failed matching with the second filter")
- }
-
- if !filter2.MatchMessage(msg) {
- t.Fatalf("failed matching with the second filter")
- }
-}
-
-func TestComparePubKey(t *testing.T) {
- InitSingleTest()
-
- key1, err := crypto.GenerateKey()
- if err != nil {
- t.Fatalf("failed to generate first key with seed %d: %s.", seed, err)
- }
- key2, err := crypto.GenerateKey()
- if err != nil {
- t.Fatalf("failed to generate second key with seed %d: %s.", seed, err)
- }
- if IsPubKeyEqual(&key1.PublicKey, &key2.PublicKey) {
- t.Fatalf("public keys are equal, seed %d.", seed)
- }
-
- // generate key3 == key1
- mrand.Seed(seed)
- key3, err := crypto.GenerateKey()
- if err != nil {
- t.Fatalf("failed to generate third key with seed %d: %s.", seed, err)
- }
- if IsPubKeyEqual(&key1.PublicKey, &key3.PublicKey) {
- t.Fatalf("key1 == key3, seed %d.", seed)
- }
-}
-
-func TestMatchEnvelope(t *testing.T) {
- InitSingleTest()
-
- fsym, err := generateFilter(t, true)
- if err != nil {
- t.Fatalf("failed generateFilter with seed %d: %s.", seed, err)
- }
-
- fasym, err := generateFilter(t, false)
- if err != nil {
- t.Fatalf("failed generateFilter() with seed %d: %s.", seed, err)
- }
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- params.Topic[0] = 0xFF // ensure mismatch
-
- // mismatch with pseudo-random data
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
- match := fsym.MatchEnvelope(env)
- if match {
- t.Fatalf("failed MatchEnvelope symmetric with seed %d.", seed)
- }
- match = fasym.MatchEnvelope(env)
- if match {
- t.Fatalf("failed MatchEnvelope asymmetric with seed %d.", seed)
- }
-
- // encrypt symmetrically
- i := mrand.Int() % 4
- fsym.Topics[i] = params.Topic[:]
- fasym.Topics[i] = params.Topic[:]
- msg, err = NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err = msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap() with seed %d: %s.", seed, err)
- }
-
- // symmetric + matching topic: match
- match = fsym.MatchEnvelope(env)
- if !match {
- t.Fatalf("failed MatchEnvelope() symmetric with seed %d.", seed)
- }
-
- // asymmetric + matching topic: mismatch
- match = fasym.MatchEnvelope(env)
- if match {
- t.Fatalf("failed MatchEnvelope() asymmetric with seed %d.", seed)
- }
-
- // symmetric + matching topic + insufficient PoW: mismatch
- fsym.PoW = env.PoW() + 1.0
- match = fsym.MatchEnvelope(env)
- if match {
- t.Fatalf("failed MatchEnvelope(symmetric + matching topic + insufficient PoW) asymmetric with seed %d.", seed)
- }
-
- // symmetric + matching topic + sufficient PoW: match
- fsym.PoW = env.PoW() / 2
- match = fsym.MatchEnvelope(env)
- if !match {
- t.Fatalf("failed MatchEnvelope(symmetric + matching topic + sufficient PoW) with seed %d.", seed)
- }
-
- // symmetric + topics are nil (wildcard): match
- prevTopics := fsym.Topics
- fsym.Topics = nil
- match = fsym.MatchEnvelope(env)
- if !match {
- t.Fatalf("failed MatchEnvelope(symmetric + topics are nil) with seed %d.", seed)
- }
- fsym.Topics = prevTopics
-
- // encrypt asymmetrically
- key, err := crypto.GenerateKey()
- if err != nil {
- t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
- }
- params.KeySym = nil
- params.Dst = &key.PublicKey
- msg, err = NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err = msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap() with seed %d: %s.", seed, err)
- }
-
- // encryption method mismatch
- match = fsym.MatchEnvelope(env)
- if match {
- t.Fatalf("failed MatchEnvelope(encryption method mismatch) with seed %d.", seed)
- }
-
- // asymmetric + mismatching topic: mismatch
- match = fasym.MatchEnvelope(env)
- if !match {
- t.Fatalf("failed MatchEnvelope(asymmetric + mismatching topic) with seed %d.", seed)
- }
-
- // asymmetric + matching topic: match
- fasym.Topics[i] = fasym.Topics[i+1]
- match = fasym.MatchEnvelope(env)
- if match {
- t.Fatalf("failed MatchEnvelope(asymmetric + matching topic) with seed %d.", seed)
- }
-
- // asymmetric + filter without topic (wildcard): match
- fasym.Topics = nil
- match = fasym.MatchEnvelope(env)
- if !match {
- t.Fatalf("failed MatchEnvelope(asymmetric + filter without topic) with seed %d.", seed)
- }
-
- // asymmetric + insufficient PoW: mismatch
- fasym.PoW = env.PoW() + 1.0
- match = fasym.MatchEnvelope(env)
- if match {
- t.Fatalf("failed MatchEnvelope(asymmetric + insufficient PoW) with seed %d.", seed)
- }
-
- // asymmetric + sufficient PoW: match
- fasym.PoW = env.PoW() / 2
- match = fasym.MatchEnvelope(env)
- if !match {
- t.Fatalf("failed MatchEnvelope(asymmetric + sufficient PoW) with seed %d.", seed)
- }
-
- // filter without topic + envelope without topic: match
- env.Topic = TopicType{}
- match = fasym.MatchEnvelope(env)
- if !match {
- t.Fatalf("failed MatchEnvelope(filter without topic + envelope without topic) with seed %d.", seed)
- }
-
- // filter with topic + envelope without topic: mismatch
- fasym.Topics = fsym.Topics
- match = fasym.MatchEnvelope(env)
- if match {
- t.Fatalf("failed MatchEnvelope(filter without topic + envelope without topic) with seed %d.", seed)
- }
-}
-
-func TestMatchMessageSym(t *testing.T) {
- InitSingleTest()
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- f, err := generateFilter(t, true)
- if err != nil {
- t.Fatalf("failed generateFilter with seed %d: %s.", seed, err)
- }
-
- const index = 1
- params.KeySym = f.KeySym
- params.Topic = BytesToTopic(f.Topics[index])
-
- sentMessage, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := sentMessage.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
- msg := env.Open(f)
- if msg == nil {
- t.Fatalf("failed Open with seed %d.", seed)
- }
-
- // Src: match
- *f.Src.X = *params.Src.PublicKey.X
- *f.Src.Y = *params.Src.PublicKey.Y
- if !f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(src match) with seed %d.", seed)
- }
-
- // insufficient PoW: mismatch
- f.PoW = msg.PoW + 1.0
- if f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(insufficient PoW) with seed %d.", seed)
- }
-
- // sufficient PoW: match
- f.PoW = msg.PoW / 2
- if !f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(sufficient PoW) with seed %d.", seed)
- }
-
- // topic mismatch
- f.Topics[index][0]++
- if f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(topic mismatch) with seed %d.", seed)
- }
- f.Topics[index][0]--
-
- // key mismatch
- f.SymKeyHash[0]++
- if f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(key mismatch) with seed %d.", seed)
- }
- f.SymKeyHash[0]--
-
- // Src absent: match
- f.Src = nil
- if !f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(src absent) with seed %d.", seed)
- }
-
- // key hash mismatch
- h := f.SymKeyHash
- f.SymKeyHash = common.Hash{}
- if f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(key hash mismatch) with seed %d.", seed)
- }
- f.SymKeyHash = h
- if !f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(key hash match) with seed %d.", seed)
- }
-
- // encryption method mismatch
- f.KeySym = nil
- f.KeyAsym, err = crypto.GenerateKey()
- if err != nil {
- t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
- }
- if f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(encryption method mismatch) with seed %d.", seed)
- }
-}
-
-func TestMatchMessageAsym(t *testing.T) {
- InitSingleTest()
-
- f, err := generateFilter(t, false)
- if err != nil {
- t.Fatalf("failed generateFilter with seed %d: %s.", seed, err)
- }
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- const index = 1
- params.Topic = BytesToTopic(f.Topics[index])
- params.Dst = &f.KeyAsym.PublicKey
- keySymOrig := params.KeySym
- params.KeySym = nil
-
- sentMessage, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := sentMessage.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
- msg := env.Open(f)
- if msg == nil {
- t.Fatalf("failed to open with seed %d.", seed)
- }
-
- // Src: match
- *f.Src.X = *params.Src.PublicKey.X
- *f.Src.Y = *params.Src.PublicKey.Y
- if !f.MatchMessage(msg) {
- t.Fatalf("failed MatchMessage(src match) with seed %d.", seed)
- }
-
- // insufficient PoW: mismatch
- f.PoW = msg.PoW + 1.0
- if f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(insufficient PoW) with seed %d.", seed)
- }
-
- // sufficient PoW: match
- f.PoW = msg.PoW / 2
- if !f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(sufficient PoW) with seed %d.", seed)
- }
-
- // topic mismatch
- f.Topics[index][0]++
- if f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(topic mismatch) with seed %d.", seed)
- }
- f.Topics[index][0]--
-
- // key mismatch
- prev := *f.KeyAsym.PublicKey.X
- zero := *big.NewInt(0)
- *f.KeyAsym.PublicKey.X = zero
- if f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(key mismatch) with seed %d.", seed)
- }
- *f.KeyAsym.PublicKey.X = prev
-
- // Src absent: match
- f.Src = nil
- if !f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(src absent) with seed %d.", seed)
- }
-
- // encryption method mismatch
- f.KeySym = keySymOrig
- f.KeyAsym = nil
- if f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(encryption method mismatch) with seed %d.", seed)
- }
-}
-
-func cloneFilter(orig *Filter) *Filter {
- var clone Filter
- clone.Messages = make(map[common.Hash]*ReceivedMessage)
- clone.Src = orig.Src
- clone.KeyAsym = orig.KeyAsym
- clone.KeySym = orig.KeySym
- clone.Topics = orig.Topics
- clone.PoW = orig.PoW
- clone.AllowP2P = orig.AllowP2P
- clone.SymKeyHash = orig.SymKeyHash
- return &clone
-}
-
-func generateCompatibeEnvelope(t *testing.T, f *Filter) *Envelope {
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- return nil
- }
-
- params.KeySym = f.KeySym
- params.Topic = BytesToTopic(f.Topics[2])
- sentMessage, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := sentMessage.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- return nil
- }
- return env
-}
-
-func TestWatchers(t *testing.T) {
- InitSingleTest()
-
- const NumFilters = 16
- const NumMessages = 256
- var i int
- var j uint32
- var e *Envelope
- var x, firstID string
- var err error
-
- w := New(&Config{})
- filters := NewFilters(w)
- tst := generateTestCases(t, NumFilters)
- for i = 0; i < NumFilters; i++ {
- tst[i].f.Src = nil
- x, err = filters.Install(tst[i].f)
- if err != nil {
- t.Fatalf("failed to install filter with seed %d: %s.", seed, err)
- }
- tst[i].id = x
- if len(firstID) == 0 {
- firstID = x
- }
- }
-
- lastID := x
-
- var envelopes [NumMessages]*Envelope
- for i = 0; i < NumMessages; i++ {
- j = mrand.Uint32() % NumFilters
- e = generateCompatibeEnvelope(t, tst[j].f)
- envelopes[i] = e
- tst[j].msgCnt++
- }
-
- for i = 0; i < NumMessages; i++ {
- filters.NotifyWatchers(envelopes[i], false)
- }
-
- var total int
- var mail []*ReceivedMessage
- var count [NumFilters]int
-
- for i = 0; i < NumFilters; i++ {
- mail = tst[i].f.Retrieve()
- count[i] = len(mail)
- total += len(mail)
- }
-
- if total != NumMessages {
- t.Fatalf("failed with seed %d: total = %d, want: %d.", seed, total, NumMessages)
- }
-
- for i = 0; i < NumFilters; i++ {
- mail = tst[i].f.Retrieve()
- if len(mail) != 0 {
- t.Fatalf("failed with seed %d: i = %d.", seed, i)
- }
-
- if tst[i].msgCnt != count[i] {
- t.Fatalf("failed with seed %d: count[%d]: get %d, want %d.", seed, i, tst[i].msgCnt, count[i])
- }
- }
-
- // another round with a cloned filter
-
- clone := cloneFilter(tst[0].f)
- filters.Uninstall(lastID)
- total = 0
- last := NumFilters - 1
- tst[last].f = clone
- filters.Install(clone)
- for i = 0; i < NumFilters; i++ {
- tst[i].msgCnt = 0
- count[i] = 0
- }
-
- // make sure that the first watcher receives at least one message
- e = generateCompatibeEnvelope(t, tst[0].f)
- envelopes[0] = e
- tst[0].msgCnt++
- for i = 1; i < NumMessages; i++ {
- j = mrand.Uint32() % NumFilters
- e = generateCompatibeEnvelope(t, tst[j].f)
- envelopes[i] = e
- tst[j].msgCnt++
- }
-
- for i = 0; i < NumMessages; i++ {
- filters.NotifyWatchers(envelopes[i], false)
- }
-
- for i = 0; i < NumFilters; i++ {
- mail = tst[i].f.Retrieve()
- count[i] = len(mail)
- total += len(mail)
- }
-
- combined := tst[0].msgCnt + tst[last].msgCnt
- if total != NumMessages+count[0] {
- t.Fatalf("failed with seed %d: total = %d, count[0] = %d.", seed, total, count[0])
- }
-
- if combined != count[0] {
- t.Fatalf("failed with seed %d: combined = %d, count[0] = %d.", seed, combined, count[0])
- }
-
- if combined != count[last] {
- t.Fatalf("failed with seed %d: combined = %d, count[last] = %d.", seed, combined, count[last])
- }
-
- for i = 1; i < NumFilters-1; i++ {
- mail = tst[i].f.Retrieve()
- if len(mail) != 0 {
- t.Fatalf("failed with seed %d: i = %d.", seed, i)
- }
-
- if tst[i].msgCnt != count[i] {
- t.Fatalf("failed with seed %d: i = %d, get %d, want %d.", seed, i, tst[i].msgCnt, count[i])
- }
- }
-
- // test AcceptP2P
-
- total = 0
- filters.NotifyWatchers(envelopes[0], true)
-
- for i = 0; i < NumFilters; i++ {
- mail = tst[i].f.Retrieve()
- total += len(mail)
- }
-
- if total != 0 {
- t.Fatalf("failed with seed %d: total: got %d, want 0.", seed, total)
- }
-
- f := filters.Get(firstID)
- if f == nil {
- t.Fatalf("failed to get the filter with seed %d.", seed)
- }
- f.AllowP2P = true
- total = 0
- filters.NotifyWatchers(envelopes[0], true)
-
- for i = 0; i < NumFilters; i++ {
- mail = tst[i].f.Retrieve()
- total += len(mail)
- }
-
- if total != 1 {
- t.Fatalf("failed with seed %d: total: got %d, want 1.", seed, total)
- }
-}
-
-func TestVariableTopics(t *testing.T) {
- InitSingleTest()
-
- var match bool
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- f, err := generateFilter(t, true)
- if err != nil {
- t.Fatalf("failed generateFilter with seed %d: %s.", seed, err)
- }
-
- for i := 0; i < 4; i++ {
- arr := make([]byte, i+1, 4)
- copy(arr, env.Topic[:i+1])
-
- f.Topics[4] = arr
- match = f.MatchEnvelope(env)
- if !match {
- t.Fatalf("failed MatchEnvelope symmetric with seed %d, step %d.", seed, i)
- }
-
- f.Topics[4][i]++
- match = f.MatchEnvelope(env)
- if match {
- t.Fatalf("MatchEnvelope symmetric with seed %d, step %d: false positive.", seed, i)
- }
- }
-}
diff --git a/whisper/whisperv5/gen_criteria_json.go b/whisper/whisperv5/gen_criteria_json.go
deleted file mode 100644
index df0de85dfa43..000000000000
--- a/whisper/whisperv5/gen_criteria_json.go
+++ /dev/null
@@ -1,64 +0,0 @@
-// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
-
-package whisperv5
-
-import (
- "encoding/json"
-
- "github.com/ethereum/go-ethereum/common/hexutil"
-)
-
-var _ = (*criteriaOverride)(nil)
-
-func (c Criteria) MarshalJSON() ([]byte, error) {
- type Criteria struct {
- SymKeyID string `json:"symKeyID"`
- PrivateKeyID string `json:"privateKeyID"`
- Sig hexutil.Bytes `json:"sig"`
- MinPow float64 `json:"minPow"`
- Topics []TopicType `json:"topics"`
- AllowP2P bool `json:"allowP2P"`
- }
- var enc Criteria
- enc.SymKeyID = c.SymKeyID
- enc.PrivateKeyID = c.PrivateKeyID
- enc.Sig = c.Sig
- enc.MinPow = c.MinPow
- enc.Topics = c.Topics
- enc.AllowP2P = c.AllowP2P
- return json.Marshal(&enc)
-}
-
-func (c *Criteria) UnmarshalJSON(input []byte) error {
- type Criteria struct {
- SymKeyID *string `json:"symKeyID"`
- PrivateKeyID *string `json:"privateKeyID"`
- Sig hexutil.Bytes `json:"sig"`
- MinPow *float64 `json:"minPow"`
- Topics []TopicType `json:"topics"`
- AllowP2P *bool `json:"allowP2P"`
- }
- var dec Criteria
- if err := json.Unmarshal(input, &dec); err != nil {
- return err
- }
- if dec.SymKeyID != nil {
- c.SymKeyID = *dec.SymKeyID
- }
- if dec.PrivateKeyID != nil {
- c.PrivateKeyID = *dec.PrivateKeyID
- }
- if dec.Sig != nil {
- c.Sig = dec.Sig
- }
- if dec.MinPow != nil {
- c.MinPow = *dec.MinPow
- }
- if dec.Topics != nil {
- c.Topics = dec.Topics
- }
- if dec.AllowP2P != nil {
- c.AllowP2P = *dec.AllowP2P
- }
- return nil
-}
diff --git a/whisper/whisperv5/gen_message_json.go b/whisper/whisperv5/gen_message_json.go
deleted file mode 100644
index 1855573317c2..000000000000
--- a/whisper/whisperv5/gen_message_json.go
+++ /dev/null
@@ -1,82 +0,0 @@
-// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
-
-package whisperv5
-
-import (
- "encoding/json"
-
- "github.com/ethereum/go-ethereum/common/hexutil"
-)
-
-var _ = (*messageOverride)(nil)
-
-func (m Message) MarshalJSON() ([]byte, error) {
- type Message struct {
- Sig hexutil.Bytes `json:"sig,omitempty"`
- TTL uint32 `json:"ttl"`
- Timestamp uint32 `json:"timestamp"`
- Topic TopicType `json:"topic"`
- Payload hexutil.Bytes `json:"payload"`
- Padding hexutil.Bytes `json:"padding"`
- PoW float64 `json:"pow"`
- Hash hexutil.Bytes `json:"hash"`
- Dst hexutil.Bytes `json:"recipientPublicKey,omitempty"`
- }
- var enc Message
- enc.Sig = m.Sig
- enc.TTL = m.TTL
- enc.Timestamp = m.Timestamp
- enc.Topic = m.Topic
- enc.Payload = m.Payload
- enc.Padding = m.Padding
- enc.PoW = m.PoW
- enc.Hash = m.Hash
- enc.Dst = m.Dst
- return json.Marshal(&enc)
-}
-
-func (m *Message) UnmarshalJSON(input []byte) error {
- type Message struct {
- Sig hexutil.Bytes `json:"sig,omitempty"`
- TTL *uint32 `json:"ttl"`
- Timestamp *uint32 `json:"timestamp"`
- Topic *TopicType `json:"topic"`
- Payload hexutil.Bytes `json:"payload"`
- Padding hexutil.Bytes `json:"padding"`
- PoW *float64 `json:"pow"`
- Hash hexutil.Bytes `json:"hash"`
- Dst hexutil.Bytes `json:"recipientPublicKey,omitempty"`
- }
- var dec Message
- if err := json.Unmarshal(input, &dec); err != nil {
- return err
- }
- if dec.Sig != nil {
- m.Sig = dec.Sig
- }
- if dec.TTL != nil {
- m.TTL = *dec.TTL
- }
- if dec.Timestamp != nil {
- m.Timestamp = *dec.Timestamp
- }
- if dec.Topic != nil {
- m.Topic = *dec.Topic
- }
- if dec.Payload != nil {
- m.Payload = dec.Payload
- }
- if dec.Padding != nil {
- m.Padding = dec.Padding
- }
- if dec.PoW != nil {
- m.PoW = *dec.PoW
- }
- if dec.Hash != nil {
- m.Hash = dec.Hash
- }
- if dec.Dst != nil {
- m.Dst = dec.Dst
- }
- return nil
-}
diff --git a/whisper/whisperv5/gen_newmessage_json.go b/whisper/whisperv5/gen_newmessage_json.go
deleted file mode 100644
index d0a47185ea65..000000000000
--- a/whisper/whisperv5/gen_newmessage_json.go
+++ /dev/null
@@ -1,88 +0,0 @@
-// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
-
-package whisperv5
-
-import (
- "encoding/json"
-
- "github.com/ethereum/go-ethereum/common/hexutil"
-)
-
-var _ = (*newMessageOverride)(nil)
-
-func (n NewMessage) MarshalJSON() ([]byte, error) {
- type NewMessage struct {
- SymKeyID string `json:"symKeyID"`
- PublicKey hexutil.Bytes `json:"pubKey"`
- Sig string `json:"sig"`
- TTL uint32 `json:"ttl"`
- Topic TopicType `json:"topic"`
- Payload hexutil.Bytes `json:"payload"`
- Padding hexutil.Bytes `json:"padding"`
- PowTime uint32 `json:"powTime"`
- PowTarget float64 `json:"powTarget"`
- TargetPeer string `json:"targetPeer"`
- }
- var enc NewMessage
- enc.SymKeyID = n.SymKeyID
- enc.PublicKey = n.PublicKey
- enc.Sig = n.Sig
- enc.TTL = n.TTL
- enc.Topic = n.Topic
- enc.Payload = n.Payload
- enc.Padding = n.Padding
- enc.PowTime = n.PowTime
- enc.PowTarget = n.PowTarget
- enc.TargetPeer = n.TargetPeer
- return json.Marshal(&enc)
-}
-
-func (n *NewMessage) UnmarshalJSON(input []byte) error {
- type NewMessage struct {
- SymKeyID *string `json:"symKeyID"`
- PublicKey hexutil.Bytes `json:"pubKey"`
- Sig *string `json:"sig"`
- TTL *uint32 `json:"ttl"`
- Topic *TopicType `json:"topic"`
- Payload hexutil.Bytes `json:"payload"`
- Padding hexutil.Bytes `json:"padding"`
- PowTime *uint32 `json:"powTime"`
- PowTarget *float64 `json:"powTarget"`
- TargetPeer *string `json:"targetPeer"`
- }
- var dec NewMessage
- if err := json.Unmarshal(input, &dec); err != nil {
- return err
- }
- if dec.SymKeyID != nil {
- n.SymKeyID = *dec.SymKeyID
- }
- if dec.PublicKey != nil {
- n.PublicKey = dec.PublicKey
- }
- if dec.Sig != nil {
- n.Sig = *dec.Sig
- }
- if dec.TTL != nil {
- n.TTL = *dec.TTL
- }
- if dec.Topic != nil {
- n.Topic = *dec.Topic
- }
- if dec.Payload != nil {
- n.Payload = dec.Payload
- }
- if dec.Padding != nil {
- n.Padding = dec.Padding
- }
- if dec.PowTime != nil {
- n.PowTime = *dec.PowTime
- }
- if dec.PowTarget != nil {
- n.PowTarget = *dec.PowTarget
- }
- if dec.TargetPeer != nil {
- n.TargetPeer = *dec.TargetPeer
- }
- return nil
-}
diff --git a/whisper/whisperv5/message.go b/whisper/whisperv5/message.go
deleted file mode 100644
index c27535cd1aca..000000000000
--- a/whisper/whisperv5/message.go
+++ /dev/null
@@ -1,352 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains the Whisper protocol Message element.
-
-package whisperv5
-
-import (
- "crypto/aes"
- "crypto/cipher"
- "crypto/ecdsa"
- crand "crypto/rand"
- "encoding/binary"
- "errors"
- "strconv"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/ecies"
- "github.com/ethereum/go-ethereum/log"
-)
-
-// Options specifies the exact way a message should be wrapped into an Envelope.
-type MessageParams struct {
- TTL uint32
- Src *ecdsa.PrivateKey
- Dst *ecdsa.PublicKey
- KeySym []byte
- Topic TopicType
- WorkTime uint32
- PoW float64
- Payload []byte
- Padding []byte
-}
-
-// SentMessage represents an end-user data packet to transmit through the
-// Whisper protocol. These are wrapped into Envelopes that need not be
-// understood by intermediate nodes, just forwarded.
-type sentMessage struct {
- Raw []byte
-}
-
-// ReceivedMessage represents a data packet to be received through the
-// Whisper protocol.
-type ReceivedMessage struct {
- Raw []byte
-
- Payload []byte
- Padding []byte
- Signature []byte
-
- PoW float64 // Proof of work as described in the Whisper spec
- Sent uint32 // Time when the message was posted into the network
- TTL uint32 // Maximum time to live allowed for the message
- Src *ecdsa.PublicKey // Message recipient (identity used to decode the message)
- Dst *ecdsa.PublicKey // Message recipient (identity used to decode the message)
- Topic TopicType
-
- SymKeyHash common.Hash // The Keccak256Hash of the key, associated with the Topic
- EnvelopeHash common.Hash // Message envelope hash to act as a unique id
- EnvelopeVersion uint64
-}
-
-func isMessageSigned(flags byte) bool {
- return (flags & signatureFlag) != 0
-}
-
-func (msg *ReceivedMessage) isSymmetricEncryption() bool {
- return msg.SymKeyHash != common.Hash{}
-}
-
-func (msg *ReceivedMessage) isAsymmetricEncryption() bool {
- return msg.Dst != nil
-}
-
-// NewMessage creates and initializes a non-signed, non-encrypted Whisper message.
-func NewSentMessage(params *MessageParams) (*sentMessage, error) {
- msg := sentMessage{}
- msg.Raw = make([]byte, 1, len(params.Payload)+len(params.Padding)+signatureLength+padSizeLimit)
- msg.Raw[0] = 0 // set all the flags to zero
- err := msg.appendPadding(params)
- if err != nil {
- return nil, err
- }
- msg.Raw = append(msg.Raw, params.Payload...)
- return &msg, nil
-}
-
-// getSizeOfLength returns the number of bytes necessary to encode the entire size padding (including these bytes)
-func getSizeOfLength(b []byte) (sz int, err error) {
- sz = intSize(len(b)) // first iteration
- sz = intSize(len(b) + sz) // second iteration
- if sz > 3 {
- err = errors.New("oversized padding parameter")
- }
- return sz, err
-}
-
-// sizeOfIntSize returns minimal number of bytes necessary to encode an integer value
-func intSize(i int) (s int) {
- for s = 1; i >= 256; s++ {
- i /= 256
- }
- return s
-}
-
-// appendPadding appends the pseudorandom padding bytes and sets the padding flag.
-// The last byte contains the size of padding (thus, its size must not exceed 256).
-func (msg *sentMessage) appendPadding(params *MessageParams) error {
- rawSize := len(params.Payload) + 1
- if params.Src != nil {
- rawSize += signatureLength
- }
- odd := rawSize % padSizeLimit
-
- if len(params.Padding) != 0 {
- padSize := len(params.Padding)
- padLengthSize, err := getSizeOfLength(params.Padding)
- if err != nil {
- return err
- }
- totalPadSize := padSize + padLengthSize
- buf := make([]byte, 8)
- binary.LittleEndian.PutUint32(buf, uint32(totalPadSize))
- buf = buf[:padLengthSize]
- msg.Raw = append(msg.Raw, buf...)
- msg.Raw = append(msg.Raw, params.Padding...)
- msg.Raw[0] |= byte(padLengthSize) // number of bytes indicating the padding size
- } else if odd != 0 {
- totalPadSize := padSizeLimit - odd
- if totalPadSize > 255 {
- // this algorithm is only valid if padSizeLimit < 256.
- // if padSizeLimit will ever change, please fix the algorithm
- // (please see also ReceivedMessage.extractPadding() function).
- panic("please fix the padding algorithm before releasing new version")
- }
- buf := make([]byte, totalPadSize)
- _, err := crand.Read(buf[1:])
- if err != nil {
- return err
- }
- if totalPadSize > 6 && !validateSymmetricKey(buf) {
- return errors.New("failed to generate random padding of size " + strconv.Itoa(totalPadSize))
- }
- buf[0] = byte(totalPadSize)
- msg.Raw = append(msg.Raw, buf...)
- msg.Raw[0] |= byte(0x1) // number of bytes indicating the padding size
- }
- return nil
-}
-
-// sign calculates and sets the cryptographic signature for the message,
-// also setting the sign flag.
-func (msg *sentMessage) sign(key *ecdsa.PrivateKey) error {
- if isMessageSigned(msg.Raw[0]) {
- // this should not happen, but no reason to panic
- log.Error("failed to sign the message: already signed")
- return nil
- }
-
- msg.Raw[0] |= signatureFlag
- hash := crypto.Keccak256(msg.Raw)
- signature, err := crypto.Sign(hash, key)
- if err != nil {
- msg.Raw[0] &= ^signatureFlag // clear the flag
- return err
- }
- msg.Raw = append(msg.Raw, signature...)
- return nil
-}
-
-// encryptAsymmetric encrypts a message with a public key.
-func (msg *sentMessage) encryptAsymmetric(key *ecdsa.PublicKey) error {
- if !ValidatePublicKey(key) {
- return errors.New("invalid public key provided for asymmetric encryption")
- }
- encrypted, err := ecies.Encrypt(crand.Reader, ecies.ImportECDSAPublic(key), msg.Raw, nil, nil)
- if err == nil {
- msg.Raw = encrypted
- }
- return err
-}
-
-// encryptSymmetric encrypts a message with a topic key, using AES-GCM-256.
-// nonce size should be 12 bytes (see cipher.gcmStandardNonceSize).
-func (msg *sentMessage) encryptSymmetric(key []byte) (nonce []byte, err error) {
- if !validateSymmetricKey(key) {
- return nil, errors.New("invalid key provided for symmetric encryption")
- }
-
- block, err := aes.NewCipher(key)
- if err != nil {
- return nil, err
- }
- aesgcm, err := cipher.NewGCM(block)
- if err != nil {
- return nil, err
- }
-
- // never use more than 2^32 random nonces with a given key
- nonce = make([]byte, aesgcm.NonceSize())
- _, err = crand.Read(nonce)
- if err != nil {
- return nil, err
- } else if !validateSymmetricKey(nonce) {
- return nil, errors.New("crypto/rand failed to generate nonce")
- }
-
- msg.Raw = aesgcm.Seal(nil, nonce, msg.Raw, nil)
- return nonce, nil
-}
-
-// Wrap bundles the message into an Envelope to transmit over the network.
-func (msg *sentMessage) Wrap(options *MessageParams) (envelope *Envelope, err error) {
- if options.TTL == 0 {
- options.TTL = DefaultTTL
- }
- if options.Src != nil {
- if err = msg.sign(options.Src); err != nil {
- return nil, err
- }
- }
- var nonce []byte
- if options.Dst != nil {
- err = msg.encryptAsymmetric(options.Dst)
- } else if options.KeySym != nil {
- nonce, err = msg.encryptSymmetric(options.KeySym)
- } else {
- err = errors.New("unable to encrypt the message: neither symmetric nor assymmetric key provided")
- }
- if err != nil {
- return nil, err
- }
-
- envelope = NewEnvelope(options.TTL, options.Topic, nonce, msg)
- if err = envelope.Seal(options); err != nil {
- return nil, err
- }
- return envelope, nil
-}
-
-// decryptSymmetric decrypts a message with a topic key, using AES-GCM-256.
-// nonce size should be 12 bytes (see cipher.gcmStandardNonceSize).
-func (msg *ReceivedMessage) decryptSymmetric(key []byte, nonce []byte) error {
- block, err := aes.NewCipher(key)
- if err != nil {
- return err
- }
- aesgcm, err := cipher.NewGCM(block)
- if err != nil {
- return err
- }
- if len(nonce) != aesgcm.NonceSize() {
- log.Error("decrypting the message", "AES nonce size", len(nonce))
- return errors.New("wrong AES nonce size")
- }
- decrypted, err := aesgcm.Open(nil, nonce, msg.Raw, nil)
- if err != nil {
- return err
- }
- msg.Raw = decrypted
- return nil
-}
-
-// decryptAsymmetric decrypts an encrypted payload with a private key.
-func (msg *ReceivedMessage) decryptAsymmetric(key *ecdsa.PrivateKey) error {
- decrypted, err := ecies.ImportECDSA(key).Decrypt(crand.Reader, msg.Raw, nil, nil)
- if err == nil {
- msg.Raw = decrypted
- }
- return err
-}
-
-// Validate checks the validity and extracts the fields in case of success
-func (msg *ReceivedMessage) Validate() bool {
- end := len(msg.Raw)
- if end < 1 {
- return false
- }
-
- if isMessageSigned(msg.Raw[0]) {
- end -= signatureLength
- if end <= 1 {
- return false
- }
- msg.Signature = msg.Raw[end:]
- msg.Src = msg.SigToPubKey()
- if msg.Src == nil {
- return false
- }
- }
-
- padSize, ok := msg.extractPadding(end)
- if !ok {
- return false
- }
-
- msg.Payload = msg.Raw[1+padSize : end]
- return true
-}
-
-// extractPadding extracts the padding from raw message.
-// although we don't support sending messages with padding size
-// exceeding 255 bytes, such messages are perfectly valid, and
-// can be successfully decrypted.
-func (msg *ReceivedMessage) extractPadding(end int) (int, bool) {
- paddingSize := 0
- sz := int(msg.Raw[0] & paddingMask) // number of bytes indicating the entire size of padding (including these bytes)
- // could be zero -- it means no padding
- if sz != 0 {
- paddingSize = int(bytesToUintLittleEndian(msg.Raw[1 : 1+sz]))
- if paddingSize < sz || paddingSize+1 > end {
- return 0, false
- }
- msg.Padding = msg.Raw[1+sz : 1+paddingSize]
- }
- return paddingSize, true
-}
-
-// Recover retrieves the public key of the message signer.
-func (msg *ReceivedMessage) SigToPubKey() *ecdsa.PublicKey {
- defer func() { recover() }() // in case of invalid signature
-
- pub, err := crypto.SigToPub(msg.hash(), msg.Signature)
- if err != nil {
- log.Error("failed to recover public key from signature", "err", err)
- return nil
- }
- return pub
-}
-
-// hash calculates the SHA3 checksum of the message flags, payload and padding.
-func (msg *ReceivedMessage) hash() []byte {
- if isMessageSigned(msg.Raw[0]) {
- sz := len(msg.Raw) - signatureLength
- return crypto.Keccak256(msg.Raw[:sz])
- }
- return crypto.Keccak256(msg.Raw)
-}
diff --git a/whisper/whisperv5/message_test.go b/whisper/whisperv5/message_test.go
deleted file mode 100644
index 2edf945df018..000000000000
--- a/whisper/whisperv5/message_test.go
+++ /dev/null
@@ -1,415 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv5
-
-import (
- "bytes"
- mrand "math/rand"
- "testing"
-
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/rlp"
-)
-
-func generateMessageParams() (*MessageParams, error) {
- // set all the parameters except p.Dst and p.Padding
-
- buf := make([]byte, 4)
- mrand.Read(buf)
- sz := mrand.Intn(400)
-
- var p MessageParams
- p.PoW = 0.01
- p.WorkTime = 1
- p.TTL = uint32(mrand.Intn(1024))
- p.Payload = make([]byte, sz)
- p.KeySym = make([]byte, aesKeyLength)
- mrand.Read(p.Payload)
- mrand.Read(p.KeySym)
- p.Topic = BytesToTopic(buf)
-
- var err error
- p.Src, err = crypto.GenerateKey()
- if err != nil {
- return nil, err
- }
-
- return &p, nil
-}
-
-func singleMessageTest(t *testing.T, symmetric bool) {
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- key, err := crypto.GenerateKey()
- if err != nil {
- t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
- }
-
- if !symmetric {
- params.KeySym = nil
- params.Dst = &key.PublicKey
- }
-
- text := make([]byte, 0, 512)
- text = append(text, params.Payload...)
-
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- var decrypted *ReceivedMessage
- if symmetric {
- decrypted, err = env.OpenSymmetric(params.KeySym)
- } else {
- decrypted, err = env.OpenAsymmetric(key)
- }
-
- if err != nil {
- t.Fatalf("failed to encrypt with seed %d: %s.", seed, err)
- }
-
- if !decrypted.Validate() {
- t.Fatalf("failed to validate with seed %d.", seed)
- }
-
- if !bytes.Equal(text, decrypted.Payload) {
- t.Fatalf("failed with seed %d: compare payload.", seed)
- }
- if !isMessageSigned(decrypted.Raw[0]) {
- t.Fatalf("failed with seed %d: unsigned.", seed)
- }
- if len(decrypted.Signature) != signatureLength {
- t.Fatalf("failed with seed %d: signature len %d.", seed, len(decrypted.Signature))
- }
- if !IsPubKeyEqual(decrypted.Src, ¶ms.Src.PublicKey) {
- t.Fatalf("failed with seed %d: signature mismatch.", seed)
- }
-}
-
-func TestMessageEncryption(t *testing.T) {
- InitSingleTest()
-
- var symmetric bool
- for i := 0; i < 256; i++ {
- singleMessageTest(t, symmetric)
- symmetric = !symmetric
- }
-}
-
-func TestMessageWrap(t *testing.T) {
- seed = int64(1777444222)
- mrand.Seed(seed)
- target := 128.0
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- params.TTL = 1
- params.WorkTime = 12
- params.PoW = target
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- pow := env.PoW()
- if pow < target {
- t.Fatalf("failed Wrap with seed %d: pow < target (%f vs. %f).", seed, pow, target)
- }
-
- // set PoW target too high, expect error
- msg2, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- params.TTL = 1000000
- params.WorkTime = 1
- params.PoW = 10000000.0
- _, err = msg2.Wrap(params)
- if err == nil {
- t.Fatalf("unexpectedly reached the PoW target with seed %d.", seed)
- }
-}
-
-func TestMessageSeal(t *testing.T) {
- // this test depends on deterministic choice of seed (1976726903)
- seed = int64(1976726903)
- mrand.Seed(seed)
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- params.TTL = 1
- aesnonce := make([]byte, 12)
- mrand.Read(aesnonce)
-
- env := NewEnvelope(params.TTL, params.Topic, aesnonce, msg)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- env.Expiry = uint32(seed) // make it deterministic
- target := 32.0
- params.WorkTime = 4
- params.PoW = target
- env.Seal(params)
-
- env.calculatePoW(0)
- pow := env.PoW()
- if pow < target {
- t.Fatalf("failed Wrap with seed %d: pow < target (%f vs. %f).", seed, pow, target)
- }
-
- params.WorkTime = 1
- params.PoW = 1000000000.0
- env.Seal(params)
- env.calculatePoW(0)
- pow = env.PoW()
- if pow < 2*target {
- t.Fatalf("failed Wrap with seed %d: pow too small %f.", seed, pow)
- }
-}
-
-func TestEnvelopeOpen(t *testing.T) {
- InitSingleTest()
-
- var symmetric bool
- for i := 0; i < 256; i++ {
- singleEnvelopeOpenTest(t, symmetric)
- symmetric = !symmetric
- }
-}
-
-func singleEnvelopeOpenTest(t *testing.T, symmetric bool) {
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- key, err := crypto.GenerateKey()
- if err != nil {
- t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
- }
-
- if !symmetric {
- params.KeySym = nil
- params.Dst = &key.PublicKey
- }
-
- text := make([]byte, 0, 512)
- text = append(text, params.Payload...)
-
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- f := Filter{KeyAsym: key, KeySym: params.KeySym}
- decrypted := env.Open(&f)
- if decrypted == nil {
- t.Fatalf("failed to open with seed %d.", seed)
- }
-
- if !bytes.Equal(text, decrypted.Payload) {
- t.Fatalf("failed with seed %d: compare payload.", seed)
- }
- if !isMessageSigned(decrypted.Raw[0]) {
- t.Fatalf("failed with seed %d: unsigned.", seed)
- }
- if len(decrypted.Signature) != signatureLength {
- t.Fatalf("failed with seed %d: signature len %d.", seed, len(decrypted.Signature))
- }
- if !IsPubKeyEqual(decrypted.Src, ¶ms.Src.PublicKey) {
- t.Fatalf("failed with seed %d: signature mismatch.", seed)
- }
- if decrypted.isAsymmetricEncryption() == symmetric {
- t.Fatalf("failed with seed %d: asymmetric %v vs. %v.", seed, decrypted.isAsymmetricEncryption(), symmetric)
- }
- if decrypted.isSymmetricEncryption() != symmetric {
- t.Fatalf("failed with seed %d: symmetric %v vs. %v.", seed, decrypted.isSymmetricEncryption(), symmetric)
- }
- if !symmetric {
- if decrypted.Dst == nil {
- t.Fatalf("failed with seed %d: dst is nil.", seed)
- }
- if !IsPubKeyEqual(decrypted.Dst, &key.PublicKey) {
- t.Fatalf("failed with seed %d: Dst.", seed)
- }
- }
-}
-
-func TestEncryptWithZeroKey(t *testing.T) {
- InitSingleTest()
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- params.KeySym = make([]byte, aesKeyLength)
- _, err = msg.Wrap(params)
- if err == nil {
- t.Fatalf("wrapped with zero key, seed: %d.", seed)
- }
-
- params, err = generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- msg, err = NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- params.KeySym = make([]byte, 0)
- _, err = msg.Wrap(params)
- if err == nil {
- t.Fatalf("wrapped with empty key, seed: %d.", seed)
- }
-
- params, err = generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- msg, err = NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- params.KeySym = nil
- _, err = msg.Wrap(params)
- if err == nil {
- t.Fatalf("wrapped with nil key, seed: %d.", seed)
- }
-}
-
-func TestRlpEncode(t *testing.T) {
- InitSingleTest()
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("wrapped with zero key, seed: %d.", seed)
- }
-
- raw, err := rlp.EncodeToBytes(env)
- if err != nil {
- t.Fatalf("RLP encode failed: %s.", err)
- }
-
- var decoded Envelope
- rlp.DecodeBytes(raw, &decoded)
- if err != nil {
- t.Fatalf("RLP decode failed: %s.", err)
- }
-
- he := env.Hash()
- hd := decoded.Hash()
-
- if he != hd {
- t.Fatalf("Hashes are not equal: %x vs. %x", he, hd)
- }
-}
-
-func singlePaddingTest(t *testing.T, padSize int) {
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d and sz=%d: %s.", seed, padSize, err)
- }
- params.Padding = make([]byte, padSize)
- params.PoW = 0.0000000001
- pad := make([]byte, padSize)
- _, err = mrand.Read(pad)
- if err != nil {
- t.Fatalf("padding is not generated (seed %d): %s", seed, err)
- }
- n := copy(params.Padding, pad)
- if n != padSize {
- t.Fatalf("padding is not copied (seed %d): %s", seed, err)
- }
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed to wrap, seed: %d and sz=%d.", seed, padSize)
- }
- f := Filter{KeySym: params.KeySym}
- decrypted := env.Open(&f)
- if decrypted == nil {
- t.Fatalf("failed to open, seed and sz=%d: %d.", seed, padSize)
- }
- if !bytes.Equal(pad, decrypted.Padding) {
- t.Fatalf("padding is not retireved as expected with seed %d and sz=%d:\n[%x]\n[%x].", seed, padSize, pad, decrypted.Padding)
- }
-}
-
-func TestPadding(t *testing.T) {
- InitSingleTest()
-
- for i := 1; i < 260; i++ {
- singlePaddingTest(t, i)
- }
-
- lim := 256 * 256
- for i := lim - 5; i < lim+2; i++ {
- singlePaddingTest(t, i)
- }
-
- for i := 0; i < 256; i++ {
- n := mrand.Intn(256*254) + 256
- singlePaddingTest(t, n)
- }
-
- for i := 0; i < 256; i++ {
- n := mrand.Intn(256*1024) + 256*256
- singlePaddingTest(t, n)
- }
-}
diff --git a/whisper/whisperv5/peer.go b/whisper/whisperv5/peer.go
deleted file mode 100644
index 179c93179514..000000000000
--- a/whisper/whisperv5/peer.go
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv5
-
-import (
- "fmt"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/rlp"
- set "gopkg.in/fatih/set.v0"
-)
-
-// peer represents a whisper protocol peer connection.
-type Peer struct {
- host *Whisper
- peer *p2p.Peer
- ws p2p.MsgReadWriter
- trusted bool
-
- known *set.Set // Messages already known by the peer to avoid wasting bandwidth
-
- quit chan struct{}
-}
-
-// newPeer creates a new whisper peer object, but does not run the handshake itself.
-func newPeer(host *Whisper, remote *p2p.Peer, rw p2p.MsgReadWriter) *Peer {
- return &Peer{
- host: host,
- peer: remote,
- ws: rw,
- trusted: false,
- known: set.New(),
- quit: make(chan struct{}),
- }
-}
-
-// start initiates the peer updater, periodically broadcasting the whisper packets
-// into the network.
-func (p *Peer) start() {
- go p.update()
- log.Trace("start", "peer", p.ID())
-}
-
-// stop terminates the peer updater, stopping message forwarding to it.
-func (p *Peer) stop() {
- close(p.quit)
- log.Trace("stop", "peer", p.ID())
-}
-
-// handshake sends the protocol initiation status message to the remote peer and
-// verifies the remote status too.
-func (p *Peer) handshake() error {
- // Send the handshake status message asynchronously
- errc := make(chan error, 1)
- go func() {
- errc <- p2p.Send(p.ws, statusCode, ProtocolVersion)
- }()
- // Fetch the remote status packet and verify protocol match
- packet, err := p.ws.ReadMsg()
- if err != nil {
- return err
- }
- if packet.Code != statusCode {
- return fmt.Errorf("peer [%x] sent packet %x before status packet", p.ID(), packet.Code)
- }
- s := rlp.NewStream(packet.Payload, uint64(packet.Size))
- peerVersion, err := s.Uint()
- if err != nil {
- return fmt.Errorf("peer [%x] sent bad status message: %v", p.ID(), err)
- }
- if peerVersion != ProtocolVersion {
- return fmt.Errorf("peer [%x]: protocol version mismatch %d != %d", p.ID(), peerVersion, ProtocolVersion)
- }
- // Wait until out own status is consumed too
- if err := <-errc; err != nil {
- return fmt.Errorf("peer [%x] failed to send status packet: %v", p.ID(), err)
- }
- return nil
-}
-
-// update executes periodic operations on the peer, including message transmission
-// and expiration.
-func (p *Peer) update() {
- // Start the tickers for the updates
- expire := time.NewTicker(expirationCycle)
- transmit := time.NewTicker(transmissionCycle)
-
- // Loop and transmit until termination is requested
- for {
- select {
- case <-expire.C:
- p.expire()
-
- case <-transmit.C:
- if err := p.broadcast(); err != nil {
- log.Trace("broadcast failed", "reason", err, "peer", p.ID())
- return
- }
-
- case <-p.quit:
- return
- }
- }
-}
-
-// mark marks an envelope known to the peer so that it won't be sent back.
-func (peer *Peer) mark(envelope *Envelope) {
- peer.known.Add(envelope.Hash())
-}
-
-// marked checks if an envelope is already known to the remote peer.
-func (peer *Peer) marked(envelope *Envelope) bool {
- return peer.known.Has(envelope.Hash())
-}
-
-// expire iterates over all the known envelopes in the host and removes all
-// expired (unknown) ones from the known list.
-func (peer *Peer) expire() {
- unmark := make(map[common.Hash]struct{})
- peer.known.Each(func(v interface{}) bool {
- if !peer.host.isEnvelopeCached(v.(common.Hash)) {
- unmark[v.(common.Hash)] = struct{}{}
- }
- return true
- })
- // Dump all known but no longer cached
- for hash := range unmark {
- peer.known.Remove(hash)
- }
-}
-
-// broadcast iterates over the collection of envelopes and transmits yet unknown
-// ones over the network.
-func (p *Peer) broadcast() error {
- var cnt int
- envelopes := p.host.Envelopes()
- for _, envelope := range envelopes {
- if !p.marked(envelope) {
- err := p2p.Send(p.ws, messagesCode, envelope)
- if err != nil {
- return err
- } else {
- p.mark(envelope)
- cnt++
- }
- }
- }
- if cnt > 0 {
- log.Trace("broadcast", "num. messages", cnt)
- }
- return nil
-}
-
-func (p *Peer) ID() []byte {
- id := p.peer.ID()
- return id[:]
-}
diff --git a/whisper/whisperv5/peer_test.go b/whisper/whisperv5/peer_test.go
deleted file mode 100644
index bae2adb6f564..000000000000
--- a/whisper/whisperv5/peer_test.go
+++ /dev/null
@@ -1,306 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv5
-
-import (
- "bytes"
- "crypto/ecdsa"
- "fmt"
- "net"
- "sync"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/p2p/nat"
-)
-
-var keys []string = []string{
- "d49dcf37238dc8a7aac57dc61b9fee68f0a97f062968978b9fafa7d1033d03a9",
- "73fd6143c48e80ed3c56ea159fe7494a0b6b393a392227b422f4c3e8f1b54f98",
- "119dd32adb1daa7a4c7bf77f847fb28730785aa92947edf42fdd997b54de40dc",
- "deeda8709dea935bb772248a3144dea449ffcc13e8e5a1fd4ef20ce4e9c87837",
- "5bd208a079633befa349441bdfdc4d85ba9bd56081525008380a63ac38a407cf",
- "1d27fb4912002d58a2a42a50c97edb05c1b3dffc665dbaa42df1fe8d3d95c9b5",
- "15def52800c9d6b8ca6f3066b7767a76afc7b611786c1276165fbc61636afb68",
- "51be6ab4b2dc89f251ff2ace10f3c1cc65d6855f3e083f91f6ff8efdfd28b48c",
- "ef1ef7441bf3c6419b162f05da6037474664f198b58db7315a6f4de52414b4a0",
- "09bdf6985aabc696dc1fbeb5381aebd7a6421727343872eb2fadfc6d82486fd9",
- "15d811bf2e01f99a224cdc91d0cf76cea08e8c67905c16fee9725c9be71185c4",
- "2f83e45cf1baaea779789f755b7da72d8857aeebff19362dd9af31d3c9d14620",
- "73f04e34ac6532b19c2aae8f8e52f38df1ac8f5cd10369f92325b9b0494b0590",
- "1e2e07b69e5025537fb73770f483dc8d64f84ae3403775ef61cd36e3faf162c1",
- "8963d9bbb3911aac6d30388c786756b1c423c4fbbc95d1f96ddbddf39809e43a",
- "0422da85abc48249270b45d8de38a4cc3c02032ede1fcf0864a51092d58a2f1f",
- "8ae5c15b0e8c7cade201fdc149831aa9b11ff626a7ffd27188886cc108ad0fa8",
- "acd8f5a71d4aecfcb9ad00d32aa4bcf2a602939b6a9dd071bab443154184f805",
- "a285a922125a7481600782ad69debfbcdb0316c1e97c267aff29ef50001ec045",
- "28fd4eee78c6cd4bf78f39f8ab30c32c67c24a6223baa40e6f9c9a0e1de7cef5",
- "c5cca0c9e6f043b288c6f1aef448ab59132dab3e453671af5d0752961f013fc7",
- "46df99b051838cb6f8d1b73f232af516886bd8c4d0ee07af9a0a033c391380fd",
- "c6a06a53cbaadbb432884f36155c8f3244e244881b5ee3e92e974cfa166d793f",
- "783b90c75c63dc72e2f8d11b6f1b4de54d63825330ec76ee8db34f06b38ea211",
- "9450038f10ca2c097a8013e5121b36b422b95b04892232f930a29292d9935611",
- "e215e6246ed1cfdcf7310d4d8cdbe370f0d6a8371e4eb1089e2ae05c0e1bc10f",
- "487110939ed9d64ebbc1f300adeab358bc58875faf4ca64990fbd7fe03b78f2b",
- "824a70ea76ac81366da1d4f4ac39de851c8ac49dca456bb3f0a186ceefa269a5",
- "ba8f34fa40945560d1006a328fe70c42e35cc3d1017e72d26864cd0d1b150f15",
- "30a5dfcfd144997f428901ea88a43c8d176b19c79dde54cc58eea001aa3d246c",
- "de59f7183aca39aa245ce66a05245fecfc7e2c75884184b52b27734a4a58efa2",
- "92629e2ff5f0cb4f5f08fffe0f64492024d36f045b901efb271674b801095c5a",
- "7184c1701569e3a4c4d2ddce691edd983b81e42e09196d332e1ae2f1e062cff4",
-}
-
-const NumNodes = 16 // must not exceed the number of keys (32)
-
-type TestData struct {
- counter [NumNodes]int
- mutex sync.RWMutex
-}
-
-type TestNode struct {
- shh *Whisper
- id *ecdsa.PrivateKey
- server *p2p.Server
- filerId string
-}
-
-var result TestData
-var nodes [NumNodes]*TestNode
-var sharedKey []byte = []byte("some arbitrary data here")
-var sharedTopic TopicType = TopicType{0xF, 0x1, 0x2, 0}
-var expectedMessage []byte = []byte("per rectum ad astra")
-
-// This test does the following:
-// 1. creates a chain of whisper nodes,
-// 2. installs the filters with shared (predefined) parameters,
-// 3. each node sends a number of random (undecryptable) messages,
-// 4. first node sends one expected (decryptable) message,
-// 5. checks if each node have received and decrypted exactly one message.
-func TestSimulation(t *testing.T) {
- initialize(t)
-
- for i := 0; i < NumNodes; i++ {
- sendMsg(t, false, i)
- }
-
- sendMsg(t, true, 0)
- checkPropagation(t)
- stopServers()
-}
-
-func initialize(t *testing.T) {
- var err error
- ip := net.IPv4(127, 0, 0, 1)
- port0 := 30303
-
- for i := 0; i < NumNodes; i++ {
- var node TestNode
- node.shh = New(&DefaultConfig)
- node.shh.SetMinimumPoW(0.00000001)
- node.shh.Start(nil)
- topics := make([]TopicType, 0)
- topics = append(topics, sharedTopic)
- f := Filter{KeySym: sharedKey}
- f.Topics = [][]byte{topics[0][:]}
- node.filerId, err = node.shh.Subscribe(&f)
- if err != nil {
- t.Fatalf("failed to install the filter: %s.", err)
- }
- node.id, err = crypto.HexToECDSA(keys[i])
- if err != nil {
- t.Fatalf("failed convert the key: %s.", keys[i])
- }
- port := port0 + i
- addr := fmt.Sprintf(":%d", port) // e.g. ":30303"
- name := common.MakeName("whisper-go", "2.0")
- var peers []*discover.Node
- if i > 0 {
- peerNodeId := nodes[i-1].id
- peerPort := uint16(port - 1)
- peerNode := discover.PubkeyID(&peerNodeId.PublicKey)
- peer := discover.NewNode(peerNode, ip, peerPort, peerPort)
- peers = append(peers, peer)
- }
-
- node.server = &p2p.Server{
- Config: p2p.Config{
- PrivateKey: node.id,
- MaxPeers: NumNodes/2 + 1,
- Name: name,
- Protocols: node.shh.Protocols(),
- ListenAddr: addr,
- NAT: nat.Any(),
- BootstrapNodes: peers,
- StaticNodes: peers,
- TrustedNodes: peers,
- },
- }
-
- err = node.server.Start()
- if err != nil {
- t.Fatalf("failed to start server %d.", i)
- }
-
- nodes[i] = &node
- }
-}
-
-func stopServers() {
- for i := 0; i < NumNodes; i++ {
- n := nodes[i]
- if n != nil {
- n.shh.Unsubscribe(n.filerId)
- n.shh.Stop()
- n.server.Stop()
- }
- }
-}
-
-func checkPropagation(t *testing.T) {
- if t.Failed() {
- return
- }
-
- const cycle = 100
- const iterations = 100
-
- for j := 0; j < iterations; j++ {
- time.Sleep(cycle * time.Millisecond)
-
- for i := 0; i < NumNodes; i++ {
- f := nodes[i].shh.GetFilter(nodes[i].filerId)
- if f == nil {
- t.Fatalf("failed to get filterId %s from node %d.", nodes[i].filerId, i)
- }
-
- mail := f.Retrieve()
- if !validateMail(t, i, mail) {
- return
- }
-
- if isTestComplete() {
- return
- }
- }
- }
-
- t.Fatalf("Test was not complete: timeout %d seconds.", iterations*cycle/1000)
-}
-
-func validateMail(t *testing.T, index int, mail []*ReceivedMessage) bool {
- var cnt int
- for _, m := range mail {
- if bytes.Equal(m.Payload, expectedMessage) {
- cnt++
- }
- }
-
- if cnt == 0 {
- // no messages received yet: nothing is wrong
- return true
- }
- if cnt > 1 {
- t.Fatalf("node %d received %d.", index, cnt)
- return false
- }
-
- if cnt > 0 {
- result.mutex.Lock()
- defer result.mutex.Unlock()
- result.counter[index] += cnt
- if result.counter[index] > 1 {
- t.Fatalf("node %d accumulated %d.", index, result.counter[index])
- }
- }
- return true
-}
-
-func isTestComplete() bool {
- result.mutex.RLock()
- defer result.mutex.RUnlock()
-
- for i := 0; i < NumNodes; i++ {
- if result.counter[i] < 1 {
- return false
- }
- }
-
- for i := 0; i < NumNodes; i++ {
- envelopes := nodes[i].shh.Envelopes()
- if len(envelopes) < 2 {
- return false
- }
- }
-
- return true
-}
-
-func sendMsg(t *testing.T, expected bool, id int) {
- if t.Failed() {
- return
- }
-
- opt := MessageParams{KeySym: sharedKey, Topic: sharedTopic, Payload: expectedMessage, PoW: 0.00000001, WorkTime: 1}
- if !expected {
- opt.KeySym[0]++
- opt.Topic[0]++
- opt.Payload = opt.Payload[1:]
- }
-
- msg, err := NewSentMessage(&opt)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- envelope, err := msg.Wrap(&opt)
- if err != nil {
- t.Fatalf("failed to seal message: %s", err)
- }
-
- err = nodes[id].shh.Send(envelope)
- if err != nil {
- t.Fatalf("failed to send message: %s", err)
- }
-}
-
-func TestPeerBasic(t *testing.T) {
- InitSingleTest()
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d.", seed)
- }
-
- params.PoW = 0.001
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d.", seed)
- }
-
- p := newPeer(nil, nil, nil)
- p.mark(env)
- if !p.marked(env) {
- t.Fatalf("failed mark with seed %d.", seed)
- }
-}
diff --git a/whisper/whisperv5/topic.go b/whisper/whisperv5/topic.go
deleted file mode 100644
index c4ea67eefa6a..000000000000
--- a/whisper/whisperv5/topic.go
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains the Whisper protocol Topic element.
-
-package whisperv5
-
-import (
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
-)
-
-// Topic represents a cryptographically secure, probabilistic partial
-// classifications of a message, determined as the first (left) 4 bytes of the
-// SHA3 hash of some arbitrary data given by the original author of the message.
-type TopicType [TopicLength]byte
-
-func BytesToTopic(b []byte) (t TopicType) {
- sz := TopicLength
- if x := len(b); x < TopicLength {
- sz = x
- }
- for i := 0; i < sz; i++ {
- t[i] = b[i]
- }
- return t
-}
-
-// String converts a topic byte array to a string representation.
-func (t *TopicType) String() string {
- return common.ToHex(t[:])
-}
-
-// MarshalText returns the hex representation of t.
-func (t TopicType) MarshalText() ([]byte, error) {
- return hexutil.Bytes(t[:]).MarshalText()
-}
-
-// UnmarshalText parses a hex representation to a topic.
-func (t *TopicType) UnmarshalText(input []byte) error {
- return hexutil.UnmarshalFixedText("Topic", input, t[:])
-}
diff --git a/whisper/whisperv5/topic_test.go b/whisper/whisperv5/topic_test.go
deleted file mode 100644
index 54bbeaf85ec2..000000000000
--- a/whisper/whisperv5/topic_test.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv5
-
-import (
- "encoding/json"
- "testing"
-)
-
-var topicStringTests = []struct {
- topic TopicType
- str string
-}{
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, str: "0x00000000"},
- {topic: TopicType{0x00, 0x7f, 0x80, 0xff}, str: "0x007f80ff"},
- {topic: TopicType{0xff, 0x80, 0x7f, 0x00}, str: "0xff807f00"},
- {topic: TopicType{0xf2, 0x6e, 0x77, 0x79}, str: "0xf26e7779"},
-}
-
-func TestTopicString(t *testing.T) {
- for i, tst := range topicStringTests {
- s := tst.topic.String()
- if s != tst.str {
- t.Fatalf("failed test %d: have %s, want %s.", i, s, tst.str)
- }
- }
-}
-
-var bytesToTopicTests = []struct {
- data []byte
- topic TopicType
-}{
- {topic: TopicType{0x8f, 0x9a, 0x2b, 0x7d}, data: []byte{0x8f, 0x9a, 0x2b, 0x7d}},
- {topic: TopicType{0x00, 0x7f, 0x80, 0xff}, data: []byte{0x00, 0x7f, 0x80, 0xff}},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte{0x00, 0x00, 0x00, 0x00}},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte{0x00, 0x00, 0x00}},
- {topic: TopicType{0x01, 0x00, 0x00, 0x00}, data: []byte{0x01}},
- {topic: TopicType{0x00, 0xfe, 0x00, 0x00}, data: []byte{0x00, 0xfe}},
- {topic: TopicType{0xea, 0x1d, 0x43, 0x00}, data: []byte{0xea, 0x1d, 0x43}},
- {topic: TopicType{0x6f, 0x3c, 0xb0, 0xdd}, data: []byte{0x6f, 0x3c, 0xb0, 0xdd, 0x0f, 0x00, 0x90}},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte{}},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: nil},
-}
-
-var unmarshalTestsGood = []struct {
- topic TopicType
- data []byte
-}{
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"0x00000000"`)},
- {topic: TopicType{0x00, 0x7f, 0x80, 0xff}, data: []byte(`"0x007f80ff"`)},
- {topic: TopicType{0xff, 0x80, 0x7f, 0x00}, data: []byte(`"0xff807f00"`)},
- {topic: TopicType{0xf2, 0x6e, 0x77, 0x79}, data: []byte(`"0xf26e7779"`)},
-}
-
-var unmarshalTestsBad = []struct {
- topic TopicType
- data []byte
-}{
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"0x000000"`)},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"0x0000000"`)},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"0x000000000"`)},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"0x0000000000"`)},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"000000"`)},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"0000000"`)},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"000000000"`)},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"0000000000"`)},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"abcdefg0"`)},
-}
-
-var unmarshalTestsUgly = []struct {
- topic TopicType
- data []byte
-}{
- {topic: TopicType{0x01, 0x00, 0x00, 0x00}, data: []byte(`"0x00000001"`)},
-}
-
-func TestBytesToTopic(t *testing.T) {
- for i, tst := range bytesToTopicTests {
- top := BytesToTopic(tst.data)
- if top != tst.topic {
- t.Fatalf("failed test %d: have %v, want %v.", i, t, tst.topic)
- }
- }
-}
-
-func TestUnmarshalTestsGood(t *testing.T) {
- for i, tst := range unmarshalTestsGood {
- var top TopicType
- err := json.Unmarshal(tst.data, &top)
- if err != nil {
- t.Errorf("failed test %d. input: %v. err: %v", i, tst.data, err)
- } else if top != tst.topic {
- t.Errorf("failed test %d: have %v, want %v.", i, t, tst.topic)
- }
- }
-}
-
-func TestUnmarshalTestsBad(t *testing.T) {
- // in this test UnmarshalJSON() is supposed to fail
- for i, tst := range unmarshalTestsBad {
- var top TopicType
- err := json.Unmarshal(tst.data, &top)
- if err == nil {
- t.Fatalf("failed test %d. input: %v.", i, tst.data)
- }
- }
-}
-
-func TestUnmarshalTestsUgly(t *testing.T) {
- // in this test UnmarshalJSON() is NOT supposed to fail, but result should be wrong
- for i, tst := range unmarshalTestsUgly {
- var top TopicType
- err := json.Unmarshal(tst.data, &top)
- if err != nil {
- t.Errorf("failed test %d. input: %v.", i, tst.data)
- } else if top == tst.topic {
- t.Errorf("failed test %d: have %v, want %v.", i, top, tst.topic)
- }
- }
-}
diff --git a/whisper/whisperv5/whisper.go b/whisper/whisperv5/whisper.go
deleted file mode 100644
index 85849ccce493..000000000000
--- a/whisper/whisperv5/whisper.go
+++ /dev/null
@@ -1,858 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv5
-
-import (
- "bytes"
- "crypto/ecdsa"
- crand "crypto/rand"
- "crypto/sha256"
- "fmt"
- "runtime"
- "sync"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/rpc"
- "github.com/syndtr/goleveldb/leveldb/errors"
- "golang.org/x/crypto/pbkdf2"
- "golang.org/x/sync/syncmap"
- set "gopkg.in/fatih/set.v0"
-)
-
-type Statistics struct {
- messagesCleared int
- memoryCleared int
- memoryUsed int
- cycles int
- totalMessagesCleared int
-}
-
-const (
- minPowIdx = iota // Minimal PoW required by the whisper node
- maxMsgSizeIdx = iota // Maximal message length allowed by the whisper node
- overflowIdx = iota // Indicator of message queue overflow
-)
-
-// Whisper represents a dark communication interface through the Ethereum
-// network, using its very own P2P communication layer.
-type Whisper struct {
- protocol p2p.Protocol // Protocol description and parameters
- filters *Filters // Message filters installed with Subscribe function
-
- privateKeys map[string]*ecdsa.PrivateKey // Private key storage
- symKeys map[string][]byte // Symmetric key storage
- keyMu sync.RWMutex // Mutex associated with key storages
-
- poolMu sync.RWMutex // Mutex to sync the message and expiration pools
- envelopes map[common.Hash]*Envelope // Pool of envelopes currently tracked by this node
- expirations map[uint32]*set.SetNonTS // Message expiration pool
-
- peerMu sync.RWMutex // Mutex to sync the active peer set
- peers map[*Peer]struct{} // Set of currently active peers
-
- messageQueue chan *Envelope // Message queue for normal whisper messages
- p2pMsgQueue chan *Envelope // Message queue for peer-to-peer messages (not to be forwarded any further)
- quit chan struct{} // Channel used for graceful exit
-
- settings syncmap.Map // holds configuration settings that can be dynamically changed
-
- statsMu sync.Mutex // guard stats
- stats Statistics // Statistics of whisper node
-
- mailServer MailServer // MailServer interface
-}
-
-// New creates a Whisper client ready to communicate through the Ethereum P2P network.
-func New(cfg *Config) *Whisper {
- if cfg == nil {
- cfg = &DefaultConfig
- }
-
- whisper := &Whisper{
- privateKeys: make(map[string]*ecdsa.PrivateKey),
- symKeys: make(map[string][]byte),
- envelopes: make(map[common.Hash]*Envelope),
- expirations: make(map[uint32]*set.SetNonTS),
- peers: make(map[*Peer]struct{}),
- messageQueue: make(chan *Envelope, messageQueueLimit),
- p2pMsgQueue: make(chan *Envelope, messageQueueLimit),
- quit: make(chan struct{}),
- }
-
- whisper.filters = NewFilters(whisper)
-
- whisper.settings.Store(minPowIdx, cfg.MinimumAcceptedPOW)
- whisper.settings.Store(maxMsgSizeIdx, cfg.MaxMessageSize)
- whisper.settings.Store(overflowIdx, false)
-
- // p2p whisper sub protocol handler
- whisper.protocol = p2p.Protocol{
- Name: ProtocolName,
- Version: uint(ProtocolVersion),
- Length: NumberOfMessageCodes,
- Run: whisper.HandlePeer,
- NodeInfo: func() interface{} {
- return map[string]interface{}{
- "version": ProtocolVersionStr,
- "maxMessageSize": whisper.MaxMessageSize(),
- "minimumPoW": whisper.MinPow(),
- }
- },
- }
-
- return whisper
-}
-
-func (w *Whisper) MinPow() float64 {
- val, _ := w.settings.Load(minPowIdx)
- return val.(float64)
-}
-
-// MaxMessageSize returns the maximum accepted message size.
-func (w *Whisper) MaxMessageSize() uint32 {
- val, _ := w.settings.Load(maxMsgSizeIdx)
- return val.(uint32)
-}
-
-// Overflow returns an indication if the message queue is full.
-func (w *Whisper) Overflow() bool {
- val, _ := w.settings.Load(overflowIdx)
- return val.(bool)
-}
-
-// APIs returns the RPC descriptors the Whisper implementation offers
-func (w *Whisper) APIs() []rpc.API {
- return []rpc.API{
- {
- Namespace: ProtocolName,
- Version: ProtocolVersionStr,
- Service: NewPublicWhisperAPI(w),
- Public: true,
- },
- }
-}
-
-// RegisterServer registers MailServer interface.
-// MailServer will process all the incoming messages with p2pRequestCode.
-func (w *Whisper) RegisterServer(server MailServer) {
- w.mailServer = server
-}
-
-// Protocols returns the whisper sub-protocols ran by this particular client.
-func (w *Whisper) Protocols() []p2p.Protocol {
- return []p2p.Protocol{w.protocol}
-}
-
-// Version returns the whisper sub-protocols version number.
-func (w *Whisper) Version() uint {
- return w.protocol.Version
-}
-
-// SetMaxMessageSize sets the maximal message size allowed by this node
-func (w *Whisper) SetMaxMessageSize(size uint32) error {
- if size > MaxMessageSize {
- return fmt.Errorf("message size too large [%d>%d]", size, MaxMessageSize)
- }
- w.settings.Store(maxMsgSizeIdx, size)
- return nil
-}
-
-// SetMinimumPoW sets the minimal PoW required by this node
-func (w *Whisper) SetMinimumPoW(val float64) error {
- if val <= 0.0 {
- return fmt.Errorf("invalid PoW: %f", val)
- }
- w.settings.Store(minPowIdx, val)
- return nil
-}
-
-// getPeer retrieves peer by ID
-func (w *Whisper) getPeer(peerID []byte) (*Peer, error) {
- w.peerMu.Lock()
- defer w.peerMu.Unlock()
- for p := range w.peers {
- id := p.peer.ID()
- if bytes.Equal(peerID, id[:]) {
- return p, nil
- }
- }
- return nil, fmt.Errorf("Could not find peer with ID: %x", peerID)
-}
-
-// AllowP2PMessagesFromPeer marks specific peer trusted,
-// which will allow it to send historic (expired) messages.
-func (w *Whisper) AllowP2PMessagesFromPeer(peerID []byte) error {
- p, err := w.getPeer(peerID)
- if err != nil {
- return err
- }
- p.trusted = true
- return nil
-}
-
-// RequestHistoricMessages sends a message with p2pRequestCode to a specific peer,
-// which is known to implement MailServer interface, and is supposed to process this
-// request and respond with a number of peer-to-peer messages (possibly expired),
-// which are not supposed to be forwarded any further.
-// The whisper protocol is agnostic of the format and contents of envelope.
-func (w *Whisper) RequestHistoricMessages(peerID []byte, envelope *Envelope) error {
- p, err := w.getPeer(peerID)
- if err != nil {
- return err
- }
- p.trusted = true
- return p2p.Send(p.ws, p2pRequestCode, envelope)
-}
-
-// SendP2PMessage sends a peer-to-peer message to a specific peer.
-func (w *Whisper) SendP2PMessage(peerID []byte, envelope *Envelope) error {
- p, err := w.getPeer(peerID)
- if err != nil {
- return err
- }
- return w.SendP2PDirect(p, envelope)
-}
-
-// SendP2PDirect sends a peer-to-peer message to a specific peer.
-func (w *Whisper) SendP2PDirect(peer *Peer, envelope *Envelope) error {
- return p2p.Send(peer.ws, p2pCode, envelope)
-}
-
-// NewKeyPair generates a new cryptographic identity for the client, and injects
-// it into the known identities for message decryption. Returns ID of the new key pair.
-func (w *Whisper) NewKeyPair() (string, error) {
- key, err := crypto.GenerateKey()
- if err != nil || !validatePrivateKey(key) {
- key, err = crypto.GenerateKey() // retry once
- }
- if err != nil {
- return "", err
- }
- if !validatePrivateKey(key) {
- return "", fmt.Errorf("failed to generate valid key")
- }
-
- id, err := GenerateRandomID()
- if err != nil {
- return "", fmt.Errorf("failed to generate ID: %s", err)
- }
-
- w.keyMu.Lock()
- defer w.keyMu.Unlock()
-
- if w.privateKeys[id] != nil {
- return "", fmt.Errorf("failed to generate unique ID")
- }
- w.privateKeys[id] = key
- return id, nil
-}
-
-// DeleteKeyPair deletes the specified key if it exists.
-func (w *Whisper) DeleteKeyPair(key string) bool {
- w.keyMu.Lock()
- defer w.keyMu.Unlock()
-
- if w.privateKeys[key] != nil {
- delete(w.privateKeys, key)
- return true
- }
- return false
-}
-
-// AddKeyPair imports a asymmetric private key and returns it identifier.
-func (w *Whisper) AddKeyPair(key *ecdsa.PrivateKey) (string, error) {
- id, err := GenerateRandomID()
- if err != nil {
- return "", fmt.Errorf("failed to generate ID: %s", err)
- }
-
- w.keyMu.Lock()
- w.privateKeys[id] = key
- w.keyMu.Unlock()
-
- return id, nil
-}
-
-// HasKeyPair checks if the the whisper node is configured with the private key
-// of the specified public pair.
-func (w *Whisper) HasKeyPair(id string) bool {
- w.keyMu.RLock()
- defer w.keyMu.RUnlock()
- return w.privateKeys[id] != nil
-}
-
-// GetPrivateKey retrieves the private key of the specified identity.
-func (w *Whisper) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) {
- w.keyMu.RLock()
- defer w.keyMu.RUnlock()
- key := w.privateKeys[id]
- if key == nil {
- return nil, fmt.Errorf("invalid id")
- }
- return key, nil
-}
-
-// GenerateSymKey generates a random symmetric key and stores it under id,
-// which is then returned. Will be used in the future for session key exchange.
-func (w *Whisper) GenerateSymKey() (string, error) {
- key := make([]byte, aesKeyLength)
- _, err := crand.Read(key)
- if err != nil {
- return "", err
- } else if !validateSymmetricKey(key) {
- return "", fmt.Errorf("error in GenerateSymKey: crypto/rand failed to generate random data")
- }
-
- id, err := GenerateRandomID()
- if err != nil {
- return "", fmt.Errorf("failed to generate ID: %s", err)
- }
-
- w.keyMu.Lock()
- defer w.keyMu.Unlock()
-
- if w.symKeys[id] != nil {
- return "", fmt.Errorf("failed to generate unique ID")
- }
- w.symKeys[id] = key
- return id, nil
-}
-
-// AddSymKeyDirect stores the key, and returns its id.
-func (w *Whisper) AddSymKeyDirect(key []byte) (string, error) {
- if len(key) != aesKeyLength {
- return "", fmt.Errorf("wrong key size: %d", len(key))
- }
-
- id, err := GenerateRandomID()
- if err != nil {
- return "", fmt.Errorf("failed to generate ID: %s", err)
- }
-
- w.keyMu.Lock()
- defer w.keyMu.Unlock()
-
- if w.symKeys[id] != nil {
- return "", fmt.Errorf("failed to generate unique ID")
- }
- w.symKeys[id] = key
- return id, nil
-}
-
-// AddSymKeyFromPassword generates the key from password, stores it, and returns its id.
-func (w *Whisper) AddSymKeyFromPassword(password string) (string, error) {
- id, err := GenerateRandomID()
- if err != nil {
- return "", fmt.Errorf("failed to generate ID: %s", err)
- }
- if w.HasSymKey(id) {
- return "", fmt.Errorf("failed to generate unique ID")
- }
-
- derived, err := deriveKeyMaterial([]byte(password), EnvelopeVersion)
- if err != nil {
- return "", err
- }
-
- w.keyMu.Lock()
- defer w.keyMu.Unlock()
-
- // double check is necessary, because deriveKeyMaterial() is very slow
- if w.symKeys[id] != nil {
- return "", fmt.Errorf("critical error: failed to generate unique ID")
- }
- w.symKeys[id] = derived
- return id, nil
-}
-
-// HasSymKey returns true if there is a key associated with the given id.
-// Otherwise returns false.
-func (w *Whisper) HasSymKey(id string) bool {
- w.keyMu.RLock()
- defer w.keyMu.RUnlock()
- return w.symKeys[id] != nil
-}
-
-// DeleteSymKey deletes the key associated with the name string if it exists.
-func (w *Whisper) DeleteSymKey(id string) bool {
- w.keyMu.Lock()
- defer w.keyMu.Unlock()
- if w.symKeys[id] != nil {
- delete(w.symKeys, id)
- return true
- }
- return false
-}
-
-// GetSymKey returns the symmetric key associated with the given id.
-func (w *Whisper) GetSymKey(id string) ([]byte, error) {
- w.keyMu.RLock()
- defer w.keyMu.RUnlock()
- if w.symKeys[id] != nil {
- return w.symKeys[id], nil
- }
- return nil, fmt.Errorf("non-existent key ID")
-}
-
-// Subscribe installs a new message handler used for filtering, decrypting
-// and subsequent storing of incoming messages.
-func (w *Whisper) Subscribe(f *Filter) (string, error) {
- return w.filters.Install(f)
-}
-
-// GetFilter returns the filter by id.
-func (w *Whisper) GetFilter(id string) *Filter {
- return w.filters.Get(id)
-}
-
-// Unsubscribe removes an installed message handler.
-func (w *Whisper) Unsubscribe(id string) error {
- ok := w.filters.Uninstall(id)
- if !ok {
- return fmt.Errorf("Unsubscribe: Invalid ID")
- }
- return nil
-}
-
-// Send injects a message into the whisper send queue, to be distributed in the
-// network in the coming cycles.
-func (w *Whisper) Send(envelope *Envelope) error {
- ok, err := w.add(envelope)
- if err != nil {
- return err
- }
- if !ok {
- return fmt.Errorf("failed to add envelope")
- }
- return err
-}
-
-// Start implements node.Service, starting the background data propagation thread
-// of the Whisper protocol.
-func (w *Whisper) Start(*p2p.Server) error {
- log.Info("started whisper v." + ProtocolVersionStr)
- go w.update()
-
- numCPU := runtime.NumCPU()
- for i := 0; i < numCPU; i++ {
- go w.processQueue()
- }
-
- return nil
-}
-
-// Stop implements node.Service, stopping the background data propagation thread
-// of the Whisper protocol.
-func (w *Whisper) Stop() error {
- close(w.quit)
- log.Info("whisper stopped")
- return nil
-}
-
-// HandlePeer is called by the underlying P2P layer when the whisper sub-protocol
-// connection is negotiated.
-func (wh *Whisper) HandlePeer(peer *p2p.Peer, rw p2p.MsgReadWriter) error {
- // Create the new peer and start tracking it
- whisperPeer := newPeer(wh, peer, rw)
-
- wh.peerMu.Lock()
- wh.peers[whisperPeer] = struct{}{}
- wh.peerMu.Unlock()
-
- defer func() {
- wh.peerMu.Lock()
- delete(wh.peers, whisperPeer)
- wh.peerMu.Unlock()
- }()
-
- // Run the peer handshake and state updates
- if err := whisperPeer.handshake(); err != nil {
- return err
- }
- whisperPeer.start()
- defer whisperPeer.stop()
-
- return wh.runMessageLoop(whisperPeer, rw)
-}
-
-// runMessageLoop reads and processes inbound messages directly to merge into client-global state.
-func (wh *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error {
- for {
- // fetch the next packet
- packet, err := rw.ReadMsg()
- if err != nil {
- log.Warn("message loop", "peer", p.peer.ID(), "err", err)
- return err
- }
- if packet.Size > wh.MaxMessageSize() {
- log.Warn("oversized message received", "peer", p.peer.ID())
- return errors.New("oversized message received")
- }
-
- switch packet.Code {
- case statusCode:
- // this should not happen, but no need to panic; just ignore this message.
- log.Warn("unxepected status message received", "peer", p.peer.ID())
- case messagesCode:
- // decode the contained envelopes
- var envelope Envelope
- if err := packet.Decode(&envelope); err != nil {
- log.Warn("failed to decode envelope, peer will be disconnected", "peer", p.peer.ID(), "err", err)
- return errors.New("invalid envelope")
- }
- cached, err := wh.add(&envelope)
- if err != nil {
- log.Warn("bad envelope received, peer will be disconnected", "peer", p.peer.ID(), "err", err)
- return errors.New("invalid envelope")
- }
- if cached {
- p.mark(&envelope)
- }
- case p2pCode:
- // peer-to-peer message, sent directly to peer bypassing PoW checks, etc.
- // this message is not supposed to be forwarded to other peers, and
- // therefore might not satisfy the PoW, expiry and other requirements.
- // these messages are only accepted from the trusted peer.
- if p.trusted {
- var envelope Envelope
- if err := packet.Decode(&envelope); err != nil {
- log.Warn("failed to decode direct message, peer will be disconnected", "peer", p.peer.ID(), "err", err)
- return errors.New("invalid direct message")
- }
- wh.postEvent(&envelope, true)
- }
- case p2pRequestCode:
- // Must be processed if mail server is implemented. Otherwise ignore.
- if wh.mailServer != nil {
- var request Envelope
- if err := packet.Decode(&request); err != nil {
- log.Warn("failed to decode p2p request message, peer will be disconnected", "peer", p.peer.ID(), "err", err)
- return errors.New("invalid p2p request")
- }
- wh.mailServer.DeliverMail(p, &request)
- }
- default:
- // New message types might be implemented in the future versions of Whisper.
- // For forward compatibility, just ignore.
- }
-
- packet.Discard()
- }
-}
-
-// add inserts a new envelope into the message pool to be distributed within the
-// whisper network. It also inserts the envelope into the expiration pool at the
-// appropriate time-stamp. In case of error, connection should be dropped.
-func (wh *Whisper) add(envelope *Envelope) (bool, error) {
- now := uint32(time.Now().Unix())
- sent := envelope.Expiry - envelope.TTL
-
- if sent > now {
- if sent-SynchAllowance > now {
- return false, fmt.Errorf("envelope created in the future [%x]", envelope.Hash())
- } else {
- // recalculate PoW, adjusted for the time difference, plus one second for latency
- envelope.calculatePoW(sent - now + 1)
- }
- }
-
- if envelope.Expiry < now {
- if envelope.Expiry+SynchAllowance*2 < now {
- return false, fmt.Errorf("very old message")
- } else {
- log.Debug("expired envelope dropped", "hash", envelope.Hash().Hex())
- return false, nil // drop envelope without error
- }
- }
-
- if uint32(envelope.size()) > wh.MaxMessageSize() {
- return false, fmt.Errorf("huge messages are not allowed [%x]", envelope.Hash())
- }
-
- if len(envelope.Version) > 4 {
- return false, fmt.Errorf("oversized version [%x]", envelope.Hash())
- }
-
- aesNonceSize := len(envelope.AESNonce)
- if aesNonceSize != 0 && aesNonceSize != AESNonceLength {
- // the standard AES GCM nonce size is 12 bytes,
- // but constant gcmStandardNonceSize cannot be accessed (not exported)
- return false, fmt.Errorf("wrong size of AESNonce: %d bytes [env: %x]", aesNonceSize, envelope.Hash())
- }
-
- if envelope.PoW() < wh.MinPow() {
- log.Debug("envelope with low PoW dropped", "PoW", envelope.PoW(), "hash", envelope.Hash().Hex())
- return false, nil // drop envelope without error
- }
-
- hash := envelope.Hash()
-
- wh.poolMu.Lock()
- _, alreadyCached := wh.envelopes[hash]
- if !alreadyCached {
- wh.envelopes[hash] = envelope
- if wh.expirations[envelope.Expiry] == nil {
- wh.expirations[envelope.Expiry] = set.NewNonTS()
- }
- if !wh.expirations[envelope.Expiry].Has(hash) {
- wh.expirations[envelope.Expiry].Add(hash)
- }
- }
- wh.poolMu.Unlock()
-
- if alreadyCached {
- log.Trace("whisper envelope already cached", "hash", envelope.Hash().Hex())
- } else {
- log.Trace("cached whisper envelope", "hash", envelope.Hash().Hex())
- wh.statsMu.Lock()
- wh.stats.memoryUsed += envelope.size()
- wh.statsMu.Unlock()
- wh.postEvent(envelope, false) // notify the local node about the new message
- if wh.mailServer != nil {
- wh.mailServer.Archive(envelope)
- }
- }
- return true, nil
-}
-
-// postEvent queues the message for further processing.
-func (w *Whisper) postEvent(envelope *Envelope, isP2P bool) {
- // if the version of incoming message is higher than
- // currently supported version, we can not decrypt it,
- // and therefore just ignore this message
- if envelope.Ver() <= EnvelopeVersion {
- if isP2P {
- w.p2pMsgQueue <- envelope
- } else {
- w.checkOverflow()
- w.messageQueue <- envelope
- }
- }
-}
-
-// checkOverflow checks if message queue overflow occurs and reports it if necessary.
-func (w *Whisper) checkOverflow() {
- queueSize := len(w.messageQueue)
-
- if queueSize == messageQueueLimit {
- if !w.Overflow() {
- w.settings.Store(overflowIdx, true)
- log.Warn("message queue overflow")
- }
- } else if queueSize <= messageQueueLimit/2 {
- if w.Overflow() {
- w.settings.Store(overflowIdx, false)
- log.Warn("message queue overflow fixed (back to normal)")
- }
- }
-}
-
-// processQueue delivers the messages to the watchers during the lifetime of the whisper node.
-func (w *Whisper) processQueue() {
- var e *Envelope
- for {
- select {
- case <-w.quit:
- return
-
- case e = <-w.messageQueue:
- w.filters.NotifyWatchers(e, false)
-
- case e = <-w.p2pMsgQueue:
- w.filters.NotifyWatchers(e, true)
- }
- }
-}
-
-// update loops until the lifetime of the whisper node, updating its internal
-// state by expiring stale messages from the pool.
-func (w *Whisper) update() {
- // Start a ticker to check for expirations
- expire := time.NewTicker(expirationCycle)
-
- // Repeat updates until termination is requested
- for {
- select {
- case <-expire.C:
- w.expire()
-
- case <-w.quit:
- return
- }
- }
-}
-
-// expire iterates over all the expiration timestamps, removing all stale
-// messages from the pools.
-func (w *Whisper) expire() {
- w.poolMu.Lock()
- defer w.poolMu.Unlock()
-
- w.statsMu.Lock()
- defer w.statsMu.Unlock()
- w.stats.reset()
- now := uint32(time.Now().Unix())
- for expiry, hashSet := range w.expirations {
- if expiry < now {
- // Dump all expired messages and remove timestamp
- hashSet.Each(func(v interface{}) bool {
- sz := w.envelopes[v.(common.Hash)].size()
- delete(w.envelopes, v.(common.Hash))
- w.stats.messagesCleared++
- w.stats.memoryCleared += sz
- w.stats.memoryUsed -= sz
- return true
- })
- w.expirations[expiry].Clear()
- delete(w.expirations, expiry)
- }
- }
-}
-
-// Stats returns the whisper node statistics.
-func (w *Whisper) Stats() Statistics {
- w.statsMu.Lock()
- defer w.statsMu.Unlock()
-
- return w.stats
-}
-
-// Envelopes retrieves all the messages currently pooled by the node.
-func (w *Whisper) Envelopes() []*Envelope {
- w.poolMu.RLock()
- defer w.poolMu.RUnlock()
-
- all := make([]*Envelope, 0, len(w.envelopes))
- for _, envelope := range w.envelopes {
- all = append(all, envelope)
- }
- return all
-}
-
-// Messages iterates through all currently floating envelopes
-// and retrieves all the messages, that this filter could decrypt.
-func (w *Whisper) Messages(id string) []*ReceivedMessage {
- result := make([]*ReceivedMessage, 0)
- w.poolMu.RLock()
- defer w.poolMu.RUnlock()
-
- if filter := w.filters.Get(id); filter != nil {
- for _, env := range w.envelopes {
- msg := filter.processEnvelope(env)
- if msg != nil {
- result = append(result, msg)
- }
- }
- }
- return result
-}
-
-// isEnvelopeCached checks if envelope with specific hash has already been received and cached.
-func (w *Whisper) isEnvelopeCached(hash common.Hash) bool {
- w.poolMu.Lock()
- defer w.poolMu.Unlock()
-
- _, exist := w.envelopes[hash]
- return exist
-}
-
-// reset resets the node's statistics after each expiry cycle.
-func (s *Statistics) reset() {
- s.cycles++
- s.totalMessagesCleared += s.messagesCleared
-
- s.memoryCleared = 0
- s.messagesCleared = 0
-}
-
-// ValidatePublicKey checks the format of the given public key.
-func ValidatePublicKey(k *ecdsa.PublicKey) bool {
- return k != nil && k.X != nil && k.Y != nil && k.X.Sign() != 0 && k.Y.Sign() != 0
-}
-
-// validatePrivateKey checks the format of the given private key.
-func validatePrivateKey(k *ecdsa.PrivateKey) bool {
- if k == nil || k.D == nil || k.D.Sign() == 0 {
- return false
- }
- return ValidatePublicKey(&k.PublicKey)
-}
-
-// validateSymmetricKey returns false if the key contains all zeros
-func validateSymmetricKey(k []byte) bool {
- return len(k) > 0 && !containsOnlyZeros(k)
-}
-
-// containsOnlyZeros checks if the data contain only zeros.
-func containsOnlyZeros(data []byte) bool {
- for _, b := range data {
- if b != 0 {
- return false
- }
- }
- return true
-}
-
-// bytesToUintLittleEndian converts the slice to 64-bit unsigned integer.
-func bytesToUintLittleEndian(b []byte) (res uint64) {
- mul := uint64(1)
- for i := 0; i < len(b); i++ {
- res += uint64(b[i]) * mul
- mul *= 256
- }
- return res
-}
-
-// BytesToUintBigEndian converts the slice to 64-bit unsigned integer.
-func BytesToUintBigEndian(b []byte) (res uint64) {
- for i := 0; i < len(b); i++ {
- res *= 256
- res += uint64(b[i])
- }
- return res
-}
-
-// deriveKeyMaterial derives symmetric key material from the key or password.
-// pbkdf2 is used for security, in case people use password instead of randomly generated keys.
-func deriveKeyMaterial(key []byte, version uint64) (derivedKey []byte, err error) {
- if version == 0 {
- // kdf should run no less than 0.1 seconds on average compute,
- // because it's a once in a session experience
- derivedKey := pbkdf2.Key(key, nil, 65356, aesKeyLength, sha256.New)
- return derivedKey, nil
- } else {
- return nil, unknownVersionError(version)
- }
-}
-
-// GenerateRandomID generates a random string, which is then returned to be used as a key id
-func GenerateRandomID() (id string, err error) {
- buf := make([]byte, keyIdSize)
- _, err = crand.Read(buf)
- if err != nil {
- return "", err
- }
- if !validateSymmetricKey(buf) {
- return "", fmt.Errorf("error in generateRandomID: crypto/rand failed to generate random data")
- }
- id = common.Bytes2Hex(buf)
- return id, err
-}
diff --git a/whisper/whisperv5/whisper_test.go b/whisper/whisperv5/whisper_test.go
deleted file mode 100644
index 8af085292acf..000000000000
--- a/whisper/whisperv5/whisper_test.go
+++ /dev/null
@@ -1,851 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv5
-
-import (
- "bytes"
- "crypto/ecdsa"
- mrand "math/rand"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
-)
-
-func TestWhisperBasic(t *testing.T) {
- w := New(&DefaultConfig)
- p := w.Protocols()
- shh := p[0]
- if shh.Name != ProtocolName {
- t.Fatalf("failed Protocol Name: %v.", shh.Name)
- }
- if uint64(shh.Version) != ProtocolVersion {
- t.Fatalf("failed Protocol Version: %v.", shh.Version)
- }
- if shh.Length != NumberOfMessageCodes {
- t.Fatalf("failed Protocol Length: %v.", shh.Length)
- }
- if shh.Run == nil {
- t.Fatalf("failed shh.Run.")
- }
- if uint64(w.Version()) != ProtocolVersion {
- t.Fatalf("failed whisper Version: %v.", shh.Version)
- }
- if w.GetFilter("non-existent") != nil {
- t.Fatalf("failed GetFilter.")
- }
-
- peerID := make([]byte, 64)
- mrand.Read(peerID)
- peer, _ := w.getPeer(peerID)
- if peer != nil {
- t.Fatal("found peer for random key.")
- }
- if err := w.AllowP2PMessagesFromPeer(peerID); err == nil {
- t.Fatalf("failed MarkPeerTrusted.")
- }
- exist := w.HasSymKey("non-existing")
- if exist {
- t.Fatalf("failed HasSymKey.")
- }
- key, err := w.GetSymKey("non-existing")
- if err == nil {
- t.Fatalf("failed GetSymKey(non-existing): false positive.")
- }
- if key != nil {
- t.Fatalf("failed GetSymKey: false positive.")
- }
- mail := w.Envelopes()
- if len(mail) != 0 {
- t.Fatalf("failed w.Envelopes().")
- }
- m := w.Messages("non-existent")
- if len(m) != 0 {
- t.Fatalf("failed w.Messages.")
- }
-
- var derived []byte
- ver := uint64(0xDEADBEEF)
- if _, err := deriveKeyMaterial(peerID, ver); err != unknownVersionError(ver) {
- t.Fatalf("failed deriveKeyMaterial with param = %v: %s.", peerID, err)
- }
- derived, err = deriveKeyMaterial(peerID, 0)
- if err != nil {
- t.Fatalf("failed second deriveKeyMaterial with param = %v: %s.", peerID, err)
- }
- if !validateSymmetricKey(derived) {
- t.Fatalf("failed validateSymmetricKey with param = %v.", derived)
- }
- if containsOnlyZeros(derived) {
- t.Fatalf("failed containsOnlyZeros with param = %v.", derived)
- }
-
- buf := []byte{0xFF, 0xE5, 0x80, 0x2, 0}
- le := bytesToUintLittleEndian(buf)
- be := BytesToUintBigEndian(buf)
- if le != uint64(0x280e5ff) {
- t.Fatalf("failed bytesToIntLittleEndian: %d.", le)
- }
- if be != uint64(0xffe5800200) {
- t.Fatalf("failed BytesToIntBigEndian: %d.", be)
- }
-
- id, err := w.NewKeyPair()
- if err != nil {
- t.Fatalf("failed to generate new key pair: %s.", err)
- }
- pk, err := w.GetPrivateKey(id)
- if err != nil {
- t.Fatalf("failed to retrieve new key pair: %s.", err)
- }
- if !validatePrivateKey(pk) {
- t.Fatalf("failed validatePrivateKey: %v.", pk)
- }
- if !ValidatePublicKey(&pk.PublicKey) {
- t.Fatalf("failed ValidatePublicKey: %v.", pk)
- }
-}
-
-func TestWhisperAsymmetricKeyImport(t *testing.T) {
- var (
- w = New(&DefaultConfig)
- privateKeys []*ecdsa.PrivateKey
- )
-
- for i := 0; i < 50; i++ {
- id, err := w.NewKeyPair()
- if err != nil {
- t.Fatalf("could not generate key: %v", err)
- }
-
- pk, err := w.GetPrivateKey(id)
- if err != nil {
- t.Fatalf("could not export private key: %v", err)
- }
-
- privateKeys = append(privateKeys, pk)
-
- if !w.DeleteKeyPair(id) {
- t.Fatalf("could not delete private key")
- }
- }
-
- for _, pk := range privateKeys {
- if _, err := w.AddKeyPair(pk); err != nil {
- t.Fatalf("could not import private key: %v", err)
- }
- }
-}
-
-func TestWhisperIdentityManagement(t *testing.T) {
- w := New(&DefaultConfig)
- id1, err := w.NewKeyPair()
- if err != nil {
- t.Fatalf("failed to generate new key pair: %s.", err)
- }
- id2, err := w.NewKeyPair()
- if err != nil {
- t.Fatalf("failed to generate new key pair: %s.", err)
- }
- pk1, err := w.GetPrivateKey(id1)
- if err != nil {
- t.Fatalf("failed to retrieve the key pair: %s.", err)
- }
- pk2, err := w.GetPrivateKey(id2)
- if err != nil {
- t.Fatalf("failed to retrieve the key pair: %s.", err)
- }
-
- if !w.HasKeyPair(id1) {
- t.Fatalf("failed HasIdentity(pk1).")
- }
- if !w.HasKeyPair(id2) {
- t.Fatalf("failed HasIdentity(pk2).")
- }
- if pk1 == nil {
- t.Fatalf("failed GetIdentity(pk1).")
- }
- if pk2 == nil {
- t.Fatalf("failed GetIdentity(pk2).")
- }
-
- if !validatePrivateKey(pk1) {
- t.Fatalf("pk1 is invalid.")
- }
- if !validatePrivateKey(pk2) {
- t.Fatalf("pk2 is invalid.")
- }
-
- // Delete one identity
- done := w.DeleteKeyPair(id1)
- if !done {
- t.Fatalf("failed to delete id1.")
- }
- pk1, err = w.GetPrivateKey(id1)
- if err == nil {
- t.Fatalf("retrieve the key pair: false positive.")
- }
- pk2, err = w.GetPrivateKey(id2)
- if err != nil {
- t.Fatalf("failed to retrieve the key pair: %s.", err)
- }
- if w.HasKeyPair(id1) {
- t.Fatalf("failed DeleteIdentity(pub1): still exist.")
- }
- if !w.HasKeyPair(id2) {
- t.Fatalf("failed DeleteIdentity(pub1): pub2 does not exist.")
- }
- if pk1 != nil {
- t.Fatalf("failed DeleteIdentity(pub1): first key still exist.")
- }
- if pk2 == nil {
- t.Fatalf("failed DeleteIdentity(pub1): second key does not exist.")
- }
-
- // Delete again non-existing identity
- done = w.DeleteKeyPair(id1)
- if done {
- t.Fatalf("delete id1: false positive.")
- }
- pk1, err = w.GetPrivateKey(id1)
- if err == nil {
- t.Fatalf("retrieve the key pair: false positive.")
- }
- pk2, err = w.GetPrivateKey(id2)
- if err != nil {
- t.Fatalf("failed to retrieve the key pair: %s.", err)
- }
- if w.HasKeyPair(id1) {
- t.Fatalf("failed delete non-existing identity: exist.")
- }
- if !w.HasKeyPair(id2) {
- t.Fatalf("failed delete non-existing identity: pub2 does not exist.")
- }
- if pk1 != nil {
- t.Fatalf("failed delete non-existing identity: first key exist.")
- }
- if pk2 == nil {
- t.Fatalf("failed delete non-existing identity: second key does not exist.")
- }
-
- // Delete second identity
- done = w.DeleteKeyPair(id2)
- if !done {
- t.Fatalf("failed to delete id2.")
- }
- pk1, err = w.GetPrivateKey(id1)
- if err == nil {
- t.Fatalf("retrieve the key pair: false positive.")
- }
- pk2, err = w.GetPrivateKey(id2)
- if err == nil {
- t.Fatalf("retrieve the key pair: false positive.")
- }
- if w.HasKeyPair(id1) {
- t.Fatalf("failed delete second identity: first identity exist.")
- }
- if w.HasKeyPair(id2) {
- t.Fatalf("failed delete second identity: still exist.")
- }
- if pk1 != nil {
- t.Fatalf("failed delete second identity: first key exist.")
- }
- if pk2 != nil {
- t.Fatalf("failed delete second identity: second key exist.")
- }
-}
-
-func TestWhisperSymKeyManagement(t *testing.T) {
- InitSingleTest()
-
- var err error
- var k1, k2 []byte
- w := New(&DefaultConfig)
- id1 := string("arbitrary-string-1")
- id2 := string("arbitrary-string-2")
-
- id1, err = w.GenerateSymKey()
- if err != nil {
- t.Fatalf("failed GenerateSymKey with seed %d: %s.", seed, err)
- }
-
- k1, err = w.GetSymKey(id1)
- if err != nil {
- t.Fatalf("failed GetSymKey(id1).")
- }
- k2, err = w.GetSymKey(id2)
- if err == nil {
- t.Fatalf("failed GetSymKey(id2): false positive.")
- }
- if !w.HasSymKey(id1) {
- t.Fatalf("failed HasSymKey(id1).")
- }
- if w.HasSymKey(id2) {
- t.Fatalf("failed HasSymKey(id2): false positive.")
- }
- if k1 == nil {
- t.Fatalf("first key does not exist.")
- }
- if k2 != nil {
- t.Fatalf("second key still exist.")
- }
-
- // add existing id, nothing should change
- randomKey := make([]byte, aesKeyLength)
- mrand.Read(randomKey)
- id1, err = w.AddSymKeyDirect(randomKey)
- if err != nil {
- t.Fatalf("failed AddSymKey with seed %d: %s.", seed, err)
- }
-
- k1, err = w.GetSymKey(id1)
- if err != nil {
- t.Fatalf("failed w.GetSymKey(id1).")
- }
- k2, err = w.GetSymKey(id2)
- if err == nil {
- t.Fatalf("failed w.GetSymKey(id2): false positive.")
- }
- if !w.HasSymKey(id1) {
- t.Fatalf("failed w.HasSymKey(id1).")
- }
- if w.HasSymKey(id2) {
- t.Fatalf("failed w.HasSymKey(id2): false positive.")
- }
- if k1 == nil {
- t.Fatalf("first key does not exist.")
- }
- if !bytes.Equal(k1, randomKey) {
- t.Fatalf("k1 != randomKey.")
- }
- if k2 != nil {
- t.Fatalf("second key already exist.")
- }
-
- id2, err = w.AddSymKeyDirect(randomKey)
- if err != nil {
- t.Fatalf("failed AddSymKey(id2) with seed %d: %s.", seed, err)
- }
- k1, err = w.GetSymKey(id1)
- if err != nil {
- t.Fatalf("failed w.GetSymKey(id1).")
- }
- k2, err = w.GetSymKey(id2)
- if err != nil {
- t.Fatalf("failed w.GetSymKey(id2).")
- }
- if !w.HasSymKey(id1) {
- t.Fatalf("HasSymKey(id1) failed.")
- }
- if !w.HasSymKey(id2) {
- t.Fatalf("HasSymKey(id2) failed.")
- }
- if k1 == nil {
- t.Fatalf("k1 does not exist.")
- }
- if k2 == nil {
- t.Fatalf("k2 does not exist.")
- }
- if !bytes.Equal(k1, k2) {
- t.Fatalf("k1 != k2.")
- }
- if !bytes.Equal(k1, randomKey) {
- t.Fatalf("k1 != randomKey.")
- }
- if len(k1) != aesKeyLength {
- t.Fatalf("wrong length of k1.")
- }
- if len(k2) != aesKeyLength {
- t.Fatalf("wrong length of k2.")
- }
-
- w.DeleteSymKey(id1)
- k1, err = w.GetSymKey(id1)
- if err == nil {
- t.Fatalf("failed w.GetSymKey(id1): false positive.")
- }
- if k1 != nil {
- t.Fatalf("failed GetSymKey(id1): false positive.")
- }
- k2, err = w.GetSymKey(id2)
- if err != nil {
- t.Fatalf("failed w.GetSymKey(id2).")
- }
- if w.HasSymKey(id1) {
- t.Fatalf("failed to delete first key: still exist.")
- }
- if !w.HasSymKey(id2) {
- t.Fatalf("failed to delete first key: second key does not exist.")
- }
- if k1 != nil {
- t.Fatalf("failed to delete first key.")
- }
- if k2 == nil {
- t.Fatalf("failed to delete first key: second key is nil.")
- }
-
- w.DeleteSymKey(id1)
- w.DeleteSymKey(id2)
- k1, err = w.GetSymKey(id1)
- if err == nil {
- t.Fatalf("failed w.GetSymKey(id1): false positive.")
- }
- k2, err = w.GetSymKey(id2)
- if err == nil {
- t.Fatalf("failed w.GetSymKey(id2): false positive.")
- }
- if k1 != nil || k2 != nil {
- t.Fatalf("k1 or k2 is not nil")
- }
- if w.HasSymKey(id1) {
- t.Fatalf("failed to delete second key: first key exist.")
- }
- if w.HasSymKey(id2) {
- t.Fatalf("failed to delete second key: still exist.")
- }
- if k1 != nil {
- t.Fatalf("failed to delete second key: first key is not nil.")
- }
- if k2 != nil {
- t.Fatalf("failed to delete second key: second key is not nil.")
- }
-
- randomKey = make([]byte, aesKeyLength+1)
- mrand.Read(randomKey)
- _, err = w.AddSymKeyDirect(randomKey)
- if err == nil {
- t.Fatalf("added the key with wrong size, seed %d.", seed)
- }
-
- const password = "arbitrary data here"
- id1, err = w.AddSymKeyFromPassword(password)
- if err != nil {
- t.Fatalf("failed AddSymKeyFromPassword(id1) with seed %d: %s.", seed, err)
- }
- id2, err = w.AddSymKeyFromPassword(password)
- if err != nil {
- t.Fatalf("failed AddSymKeyFromPassword(id2) with seed %d: %s.", seed, err)
- }
- k1, err = w.GetSymKey(id1)
- if err != nil {
- t.Fatalf("failed w.GetSymKey(id1).")
- }
- k2, err = w.GetSymKey(id2)
- if err != nil {
- t.Fatalf("failed w.GetSymKey(id2).")
- }
- if !w.HasSymKey(id1) {
- t.Fatalf("HasSymKey(id1) failed.")
- }
- if !w.HasSymKey(id2) {
- t.Fatalf("HasSymKey(id2) failed.")
- }
- if k1 == nil {
- t.Fatalf("k1 does not exist.")
- }
- if k2 == nil {
- t.Fatalf("k2 does not exist.")
- }
- if !bytes.Equal(k1, k2) {
- t.Fatalf("k1 != k2.")
- }
- if len(k1) != aesKeyLength {
- t.Fatalf("wrong length of k1.")
- }
- if len(k2) != aesKeyLength {
- t.Fatalf("wrong length of k2.")
- }
- if !validateSymmetricKey(k2) {
- t.Fatalf("key validation failed.")
- }
-}
-
-func TestExpiry(t *testing.T) {
- InitSingleTest()
-
- w := New(&DefaultConfig)
- w.SetMinimumPoW(0.0000001)
- defer w.SetMinimumPoW(DefaultMinimumPoW)
- w.Start(nil)
- defer w.Stop()
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- params.TTL = 1
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- err = w.Send(env)
- if err != nil {
- t.Fatalf("failed to send envelope with seed %d: %s.", seed, err)
- }
-
- // wait till received or timeout
- var received, expired bool
- for j := 0; j < 20; j++ {
- time.Sleep(100 * time.Millisecond)
- if len(w.Envelopes()) > 0 {
- received = true
- break
- }
- }
-
- if !received {
- t.Fatalf("did not receive the sent envelope, seed: %d.", seed)
- }
-
- // wait till expired or timeout
- for j := 0; j < 20; j++ {
- time.Sleep(100 * time.Millisecond)
- if len(w.Envelopes()) == 0 {
- expired = true
- break
- }
- }
-
- if !expired {
- t.Fatalf("expire failed, seed: %d.", seed)
- }
-}
-
-func TestCustomization(t *testing.T) {
- InitSingleTest()
-
- w := New(&DefaultConfig)
- defer w.SetMinimumPoW(DefaultMinimumPoW)
- defer w.SetMaxMessageSize(DefaultMaxMessageSize)
- w.Start(nil)
- defer w.Stop()
-
- const smallPoW = 0.00001
-
- f, err := generateFilter(t, true)
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- params.KeySym = f.KeySym
- params.Topic = BytesToTopic(f.Topics[2])
- params.PoW = smallPoW
- params.TTL = 3600 * 24 // one day
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- err = w.Send(env)
- if err == nil {
- t.Fatalf("successfully sent envelope with PoW %.06f, false positive (seed %d).", env.PoW(), seed)
- }
-
- w.SetMinimumPoW(smallPoW / 2)
- err = w.Send(env)
- if err != nil {
- t.Fatalf("failed to send envelope with seed %d: %s.", seed, err)
- }
-
- params.TTL++
- msg, err = NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err = msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
- w.SetMaxMessageSize(uint32(env.size() - 1))
- err = w.Send(env)
- if err == nil {
- t.Fatalf("successfully sent oversized envelope (seed %d): false positive.", seed)
- }
-
- w.SetMaxMessageSize(DefaultMaxMessageSize)
- err = w.Send(env)
- if err != nil {
- t.Fatalf("failed to send second envelope with seed %d: %s.", seed, err)
- }
-
- // wait till received or timeout
- var received bool
- for j := 0; j < 20; j++ {
- time.Sleep(100 * time.Millisecond)
- if len(w.Envelopes()) > 1 {
- received = true
- break
- }
- }
-
- if !received {
- t.Fatalf("did not receive the sent envelope, seed: %d.", seed)
- }
-
- // check w.messages()
- id, err := w.Subscribe(f)
- if err != nil {
- t.Fatalf("failed subscribe with seed %d: %s.", seed, err)
- }
- time.Sleep(5 * time.Millisecond)
- mail := f.Retrieve()
- if len(mail) > 0 {
- t.Fatalf("received premature mail")
- }
-
- mail = w.Messages(id)
- if len(mail) != 2 {
- t.Fatalf("failed to get whisper messages")
- }
-}
-
-func TestSymmetricSendCycle(t *testing.T) {
- InitSingleTest()
-
- w := New(&DefaultConfig)
- defer w.SetMinimumPoW(DefaultMinimumPoW)
- defer w.SetMaxMessageSize(DefaultMaxMessageSize)
- w.Start(nil)
- defer w.Stop()
-
- filter1, err := generateFilter(t, true)
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- filter1.PoW = DefaultMinimumPoW
-
- // Copy the first filter since some of its fields
- // are randomly gnerated.
- filter2 := &Filter{
- KeySym: filter1.KeySym,
- Topics: filter1.Topics,
- PoW: filter1.PoW,
- AllowP2P: filter1.AllowP2P,
- Messages: make(map[common.Hash]*ReceivedMessage),
- }
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- filter1.Src = ¶ms.Src.PublicKey
- filter2.Src = ¶ms.Src.PublicKey
-
- params.KeySym = filter1.KeySym
- params.Topic = BytesToTopic(filter1.Topics[2])
- params.PoW = filter1.PoW
- params.WorkTime = 10
- params.TTL = 50
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- _, err = w.Subscribe(filter1)
- if err != nil {
- t.Fatalf("failed subscribe 1 with seed %d: %s.", seed, err)
- }
-
- _, err = w.Subscribe(filter2)
- if err != nil {
- t.Fatalf("failed subscribe 2 with seed %d: %s.", seed, err)
- }
-
- err = w.Send(env)
- if err != nil {
- t.Fatalf("Failed sending envelope with PoW %.06f (seed %d): %s", env.PoW(), seed, err)
- }
-
- // wait till received or timeout
- var received bool
- for j := 0; j < 200; j++ {
- time.Sleep(10 * time.Millisecond)
- if len(w.Envelopes()) > 0 {
- received = true
- break
- }
- }
-
- if !received {
- t.Fatalf("did not receive the sent envelope, seed: %d.", seed)
- }
-
- // check w.messages()
- time.Sleep(5 * time.Millisecond)
- mail1 := filter1.Retrieve()
- mail2 := filter2.Retrieve()
- if len(mail2) == 0 {
- t.Fatalf("did not receive any email for filter 2")
- }
- if len(mail1) == 0 {
- t.Fatalf("did not receive any email for filter 1")
- }
-
-}
-
-func TestSymmetricSendWithoutAKey(t *testing.T) {
- InitSingleTest()
-
- w := New(&DefaultConfig)
- defer w.SetMinimumPoW(DefaultMinimumPoW)
- defer w.SetMaxMessageSize(DefaultMaxMessageSize)
- w.Start(nil)
- defer w.Stop()
-
- filter, err := generateFilter(t, true)
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- filter.PoW = DefaultMinimumPoW
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- filter.Src = nil
-
- params.KeySym = filter.KeySym
- params.Topic = BytesToTopic(filter.Topics[2])
- params.PoW = filter.PoW
- params.WorkTime = 10
- params.TTL = 50
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- _, err = w.Subscribe(filter)
- if err != nil {
- t.Fatalf("failed subscribe 1 with seed %d: %s.", seed, err)
- }
-
- err = w.Send(env)
- if err != nil {
- t.Fatalf("Failed sending envelope with PoW %.06f (seed %d): %s", env.PoW(), seed, err)
- }
-
- // wait till received or timeout
- var received bool
- for j := 0; j < 200; j++ {
- time.Sleep(10 * time.Millisecond)
- if len(w.Envelopes()) > 0 {
- received = true
- break
- }
- }
-
- if !received {
- t.Fatalf("did not receive the sent envelope, seed: %d.", seed)
- }
-
- // check w.messages()
- time.Sleep(5 * time.Millisecond)
- mail := filter.Retrieve()
- if len(mail) == 0 {
- t.Fatalf("did not receive message in spite of not setting a public key")
- }
-}
-
-func TestSymmetricSendKeyMismatch(t *testing.T) {
- InitSingleTest()
-
- w := New(&DefaultConfig)
- defer w.SetMinimumPoW(DefaultMinimumPoW)
- defer w.SetMaxMessageSize(DefaultMaxMessageSize)
- w.Start(nil)
- defer w.Stop()
-
- filter, err := generateFilter(t, true)
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- filter.PoW = DefaultMinimumPoW
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- params.KeySym = filter.KeySym
- params.Topic = BytesToTopic(filter.Topics[2])
- params.PoW = filter.PoW
- params.WorkTime = 10
- params.TTL = 50
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- _, err = w.Subscribe(filter)
- if err != nil {
- t.Fatalf("failed subscribe 1 with seed %d: %s.", seed, err)
- }
-
- err = w.Send(env)
- if err != nil {
- t.Fatalf("Failed sending envelope with PoW %.06f (seed %d): %s", env.PoW(), seed, err)
- }
-
- // wait till received or timeout
- var received bool
- for j := 0; j < 200; j++ {
- time.Sleep(10 * time.Millisecond)
- if len(w.Envelopes()) > 0 {
- received = true
- break
- }
- }
-
- if !received {
- t.Fatalf("did not receive the sent envelope, seed: %d.", seed)
- }
-
- // check w.messages()
- time.Sleep(5 * time.Millisecond)
- mail := filter.Retrieve()
- if len(mail) > 0 {
- t.Fatalf("received a message when keys weren't matching")
- }
-}
diff --git a/whisper/whisperv6/api.go b/whisper/whisperv6/api.go
deleted file mode 100644
index 3dddb69539f0..000000000000
--- a/whisper/whisperv6/api.go
+++ /dev/null
@@ -1,591 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv6
-
-import (
- "context"
- "crypto/ecdsa"
- "errors"
- "fmt"
- "sync"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/rpc"
-)
-
-const (
- filterTimeout = 300 // filters are considered timeout out after filterTimeout seconds
-)
-
-var (
- ErrSymAsym = errors.New("specify either a symmetric or an asymmetric key")
- ErrInvalidSymmetricKey = errors.New("invalid symmetric key")
- ErrInvalidPublicKey = errors.New("invalid public key")
- ErrInvalidSigningPubKey = errors.New("invalid signing public key")
- ErrTooLowPoW = errors.New("message rejected, PoW too low")
- ErrNoTopics = errors.New("missing topic(s)")
-)
-
-// PublicWhisperAPI provides the whisper RPC service that can be
-// use publicly without security implications.
-type PublicWhisperAPI struct {
- w *Whisper
-
- mu sync.Mutex
- lastUsed map[string]time.Time // keeps track when a filter was polled for the last time.
-}
-
-// NewPublicWhisperAPI create a new RPC whisper service.
-func NewPublicWhisperAPI(w *Whisper) *PublicWhisperAPI {
- api := &PublicWhisperAPI{
- w: w,
- lastUsed: make(map[string]time.Time),
- }
-
- go api.run()
- return api
-}
-
-// run the api event loop.
-// this loop deletes filter that have not been used within filterTimeout
-func (api *PublicWhisperAPI) run() {
- timeout := time.NewTicker(2 * time.Minute)
- for {
- <-timeout.C
-
- api.mu.Lock()
- for id, lastUsed := range api.lastUsed {
- if time.Since(lastUsed).Seconds() >= filterTimeout {
- delete(api.lastUsed, id)
- if err := api.w.Unsubscribe(id); err != nil {
- log.Error("could not unsubscribe whisper filter", "error", err)
- }
- log.Debug("delete whisper filter (timeout)", "id", id)
- }
- }
- api.mu.Unlock()
- }
-}
-
-// Version returns the Whisper sub-protocol version.
-func (api *PublicWhisperAPI) Version(ctx context.Context) string {
- return ProtocolVersionStr
-}
-
-// Info contains diagnostic information.
-type Info struct {
- Memory int `json:"memory"` // Memory size of the floating messages in bytes.
- Messages int `json:"messages"` // Number of floating messages.
- MinPow float64 `json:"minPow"` // Minimal accepted PoW
- MaxMessageSize uint32 `json:"maxMessageSize"` // Maximum accepted message size
-}
-
-// Info returns diagnostic information about the whisper node.
-func (api *PublicWhisperAPI) Info(ctx context.Context) Info {
- stats := api.w.Stats()
- return Info{
- Memory: stats.memoryUsed,
- Messages: len(api.w.messageQueue) + len(api.w.p2pMsgQueue),
- MinPow: api.w.MinPow(),
- MaxMessageSize: api.w.MaxMessageSize(),
- }
-}
-
-// SetMaxMessageSize sets the maximum message size that is accepted.
-// Upper limit is defined by MaxMessageSize.
-func (api *PublicWhisperAPI) SetMaxMessageSize(ctx context.Context, size uint32) (bool, error) {
- return true, api.w.SetMaxMessageSize(size)
-}
-
-// SetMinPow sets the minimum PoW for a message before it is accepted.
-func (api *PublicWhisperAPI) SetMinPoW(ctx context.Context, pow float64) (bool, error) {
- return true, api.w.SetMinimumPoW(pow)
-}
-
-// MarkTrustedPeer marks a peer trusted. , which will allow it to send historic (expired) messages.
-// Note: This function is not adding new nodes, the node needs to exists as a peer.
-func (api *PublicWhisperAPI) MarkTrustedPeer(ctx context.Context, enode string) (bool, error) {
- n, err := discover.ParseNode(enode)
- if err != nil {
- return false, err
- }
- return true, api.w.AllowP2PMessagesFromPeer(n.ID[:])
-}
-
-// NewKeyPair generates a new public and private key pair for message decryption and encryption.
-// It returns an ID that can be used to refer to the keypair.
-func (api *PublicWhisperAPI) NewKeyPair(ctx context.Context) (string, error) {
- return api.w.NewKeyPair()
-}
-
-// AddPrivateKey imports the given private key.
-func (api *PublicWhisperAPI) AddPrivateKey(ctx context.Context, privateKey hexutil.Bytes) (string, error) {
- key, err := crypto.ToECDSA(privateKey)
- if err != nil {
- return "", err
- }
- return api.w.AddKeyPair(key)
-}
-
-// DeleteKeyPair removes the key with the given key if it exists.
-func (api *PublicWhisperAPI) DeleteKeyPair(ctx context.Context, key string) (bool, error) {
- if ok := api.w.DeleteKeyPair(key); ok {
- return true, nil
- }
- return false, fmt.Errorf("key pair %s not found", key)
-}
-
-// HasKeyPair returns an indication if the node has a key pair that is associated with the given id.
-func (api *PublicWhisperAPI) HasKeyPair(ctx context.Context, id string) bool {
- return api.w.HasKeyPair(id)
-}
-
-// GetPublicKey returns the public key associated with the given key. The key is the hex
-// encoded representation of a key in the form specified in section 4.3.6 of ANSI X9.62.
-func (api *PublicWhisperAPI) GetPublicKey(ctx context.Context, id string) (hexutil.Bytes, error) {
- key, err := api.w.GetPrivateKey(id)
- if err != nil {
- return hexutil.Bytes{}, err
- }
- return crypto.FromECDSAPub(&key.PublicKey), nil
-}
-
-// GetPublicKey returns the private key associated with the given key. The key is the hex
-// encoded representation of a key in the form specified in section 4.3.6 of ANSI X9.62.
-func (api *PublicWhisperAPI) GetPrivateKey(ctx context.Context, id string) (hexutil.Bytes, error) {
- key, err := api.w.GetPrivateKey(id)
- if err != nil {
- return hexutil.Bytes{}, err
- }
- return crypto.FromECDSA(key), nil
-}
-
-// NewSymKey generate a random symmetric key.
-// It returns an ID that can be used to refer to the key.
-// Can be used encrypting and decrypting messages where the key is known to both parties.
-func (api *PublicWhisperAPI) NewSymKey(ctx context.Context) (string, error) {
- return api.w.GenerateSymKey()
-}
-
-// AddSymKey import a symmetric key.
-// It returns an ID that can be used to refer to the key.
-// Can be used encrypting and decrypting messages where the key is known to both parties.
-func (api *PublicWhisperAPI) AddSymKey(ctx context.Context, key hexutil.Bytes) (string, error) {
- return api.w.AddSymKeyDirect([]byte(key))
-}
-
-// GenerateSymKeyFromPassword derive a key from the given password, stores it, and returns its ID.
-func (api *PublicWhisperAPI) GenerateSymKeyFromPassword(ctx context.Context, passwd string) (string, error) {
- return api.w.AddSymKeyFromPassword(passwd)
-}
-
-// HasSymKey returns an indication if the node has a symmetric key associated with the given key.
-func (api *PublicWhisperAPI) HasSymKey(ctx context.Context, id string) bool {
- return api.w.HasSymKey(id)
-}
-
-// GetSymKey returns the symmetric key associated with the given id.
-func (api *PublicWhisperAPI) GetSymKey(ctx context.Context, id string) (hexutil.Bytes, error) {
- return api.w.GetSymKey(id)
-}
-
-// DeleteSymKey deletes the symmetric key that is associated with the given id.
-func (api *PublicWhisperAPI) DeleteSymKey(ctx context.Context, id string) bool {
- return api.w.DeleteSymKey(id)
-}
-
-//go:generate gencodec -type NewMessage -field-override newMessageOverride -out gen_newmessage_json.go
-
-// NewMessage represents a new whisper message that is posted through the RPC.
-type NewMessage struct {
- SymKeyID string `json:"symKeyID"`
- PublicKey []byte `json:"pubKey"`
- Sig string `json:"sig"`
- TTL uint32 `json:"ttl"`
- Topic TopicType `json:"topic"`
- Payload []byte `json:"payload"`
- Padding []byte `json:"padding"`
- PowTime uint32 `json:"powTime"`
- PowTarget float64 `json:"powTarget"`
- TargetPeer string `json:"targetPeer"`
-}
-
-type newMessageOverride struct {
- PublicKey hexutil.Bytes
- Payload hexutil.Bytes
- Padding hexutil.Bytes
-}
-
-// Post a message on the Whisper network.
-func (api *PublicWhisperAPI) Post(ctx context.Context, req NewMessage) (bool, error) {
- var (
- symKeyGiven = len(req.SymKeyID) > 0
- pubKeyGiven = len(req.PublicKey) > 0
- err error
- )
-
- // user must specify either a symmetric or an asymmetric key
- if (symKeyGiven && pubKeyGiven) || (!symKeyGiven && !pubKeyGiven) {
- return false, ErrSymAsym
- }
-
- params := &MessageParams{
- TTL: req.TTL,
- Payload: req.Payload,
- Padding: req.Padding,
- WorkTime: req.PowTime,
- PoW: req.PowTarget,
- Topic: req.Topic,
- }
-
- // Set key that is used to sign the message
- if len(req.Sig) > 0 {
- if params.Src, err = api.w.GetPrivateKey(req.Sig); err != nil {
- return false, err
- }
- }
-
- // Set symmetric key that is used to encrypt the message
- if symKeyGiven {
- if params.Topic == (TopicType{}) { // topics are mandatory with symmetric encryption
- return false, ErrNoTopics
- }
- if params.KeySym, err = api.w.GetSymKey(req.SymKeyID); err != nil {
- return false, err
- }
- if !validateSymmetricKey(params.KeySym) {
- return false, ErrInvalidSymmetricKey
- }
- }
-
- // Set asymmetric key that is used to encrypt the message
- if pubKeyGiven {
- params.Dst = crypto.ToECDSAPub(req.PublicKey)
- if !ValidatePublicKey(params.Dst) {
- return false, ErrInvalidPublicKey
- }
- }
-
- // encrypt and sent message
- whisperMsg, err := NewSentMessage(params)
- if err != nil {
- return false, err
- }
-
- env, err := whisperMsg.Wrap(params)
- if err != nil {
- return false, err
- }
-
- // send to specific node (skip PoW check)
- if len(req.TargetPeer) > 0 {
- n, err := discover.ParseNode(req.TargetPeer)
- if err != nil {
- return false, fmt.Errorf("failed to parse target peer: %s", err)
- }
- return true, api.w.SendP2PMessage(n.ID[:], env)
- }
-
- // ensure that the message PoW meets the node's minimum accepted PoW
- if req.PowTarget < api.w.MinPow() {
- return false, ErrTooLowPoW
- }
-
- return true, api.w.Send(env)
-}
-
-//go:generate gencodec -type Criteria -field-override criteriaOverride -out gen_criteria_json.go
-
-// Criteria holds various filter options for inbound messages.
-type Criteria struct {
- SymKeyID string `json:"symKeyID"`
- PrivateKeyID string `json:"privateKeyID"`
- Sig []byte `json:"sig"`
- MinPow float64 `json:"minPow"`
- Topics []TopicType `json:"topics"`
- AllowP2P bool `json:"allowP2P"`
-}
-
-type criteriaOverride struct {
- Sig hexutil.Bytes
-}
-
-// Messages set up a subscription that fires events when messages arrive that match
-// the given set of criteria.
-func (api *PublicWhisperAPI) Messages(ctx context.Context, crit Criteria) (*rpc.Subscription, error) {
- var (
- symKeyGiven = len(crit.SymKeyID) > 0
- pubKeyGiven = len(crit.PrivateKeyID) > 0
- err error
- )
-
- // ensure that the RPC connection supports subscriptions
- notifier, supported := rpc.NotifierFromContext(ctx)
- if !supported {
- return nil, rpc.ErrNotificationsUnsupported
- }
-
- // user must specify either a symmetric or an asymmetric key
- if (symKeyGiven && pubKeyGiven) || (!symKeyGiven && !pubKeyGiven) {
- return nil, ErrSymAsym
- }
-
- filter := Filter{
- PoW: crit.MinPow,
- Messages: make(map[common.Hash]*ReceivedMessage),
- AllowP2P: crit.AllowP2P,
- }
-
- if len(crit.Sig) > 0 {
- filter.Src = crypto.ToECDSAPub(crit.Sig)
- if !ValidatePublicKey(filter.Src) {
- return nil, ErrInvalidSigningPubKey
- }
- }
-
- for i, bt := range crit.Topics {
- if len(bt) == 0 || len(bt) > 4 {
- return nil, fmt.Errorf("subscribe: topic %d has wrong size: %d", i, len(bt))
- }
- filter.Topics = append(filter.Topics, bt[:])
- }
-
- // listen for message that are encrypted with the given symmetric key
- if symKeyGiven {
- if len(filter.Topics) == 0 {
- return nil, ErrNoTopics
- }
- key, err := api.w.GetSymKey(crit.SymKeyID)
- if err != nil {
- return nil, err
- }
- if !validateSymmetricKey(key) {
- return nil, ErrInvalidSymmetricKey
- }
- filter.KeySym = key
- filter.SymKeyHash = crypto.Keccak256Hash(filter.KeySym)
- }
-
- // listen for messages that are encrypted with the given public key
- if pubKeyGiven {
- filter.KeyAsym, err = api.w.GetPrivateKey(crit.PrivateKeyID)
- if err != nil || filter.KeyAsym == nil {
- return nil, ErrInvalidPublicKey
- }
- }
-
- id, err := api.w.Subscribe(&filter)
- if err != nil {
- return nil, err
- }
-
- // create subscription and start waiting for message events
- rpcSub := notifier.CreateSubscription()
- go func() {
- // for now poll internally, refactor whisper internal for channel support
- ticker := time.NewTicker(250 * time.Millisecond)
- defer ticker.Stop()
-
- for {
- select {
- case <-ticker.C:
- if filter := api.w.GetFilter(id); filter != nil {
- for _, rpcMessage := range toMessage(filter.Retrieve()) {
- if err := notifier.Notify(rpcSub.ID, rpcMessage); err != nil {
- log.Error("Failed to send notification", "err", err)
- }
- }
- }
- case <-rpcSub.Err():
- api.w.Unsubscribe(id)
- return
- case <-notifier.Closed():
- api.w.Unsubscribe(id)
- return
- }
- }
- }()
-
- return rpcSub, nil
-}
-
-//go:generate gencodec -type Message -field-override messageOverride -out gen_message_json.go
-
-// Message is the RPC representation of a whisper message.
-type Message struct {
- Sig []byte `json:"sig,omitempty"`
- TTL uint32 `json:"ttl"`
- Timestamp uint32 `json:"timestamp"`
- Topic TopicType `json:"topic"`
- Payload []byte `json:"payload"`
- Padding []byte `json:"padding"`
- PoW float64 `json:"pow"`
- Hash []byte `json:"hash"`
- Dst []byte `json:"recipientPublicKey,omitempty"`
-}
-
-type messageOverride struct {
- Sig hexutil.Bytes
- Payload hexutil.Bytes
- Padding hexutil.Bytes
- Hash hexutil.Bytes
- Dst hexutil.Bytes
-}
-
-// ToWhisperMessage converts an internal message into an API version.
-func ToWhisperMessage(message *ReceivedMessage) *Message {
- msg := Message{
- Payload: message.Payload,
- Padding: message.Padding,
- Timestamp: message.Sent,
- TTL: message.TTL,
- PoW: message.PoW,
- Hash: message.EnvelopeHash.Bytes(),
- Topic: message.Topic,
- }
-
- if message.Dst != nil {
- b := crypto.FromECDSAPub(message.Dst)
- if b != nil {
- msg.Dst = b
- }
- }
-
- if isMessageSigned(message.Raw[0]) {
- b := crypto.FromECDSAPub(message.SigToPubKey())
- if b != nil {
- msg.Sig = b
- }
- }
-
- return &msg
-}
-
-// toMessage converts a set of messages to its RPC representation.
-func toMessage(messages []*ReceivedMessage) []*Message {
- msgs := make([]*Message, len(messages))
- for i, msg := range messages {
- msgs[i] = ToWhisperMessage(msg)
- }
- return msgs
-}
-
-// GetFilterMessages returns the messages that match the filter criteria and
-// are received between the last poll and now.
-func (api *PublicWhisperAPI) GetFilterMessages(id string) ([]*Message, error) {
- api.mu.Lock()
- f := api.w.GetFilter(id)
- if f == nil {
- api.mu.Unlock()
- return nil, fmt.Errorf("filter not found")
- }
- api.lastUsed[id] = time.Now()
- api.mu.Unlock()
-
- receivedMessages := f.Retrieve()
- messages := make([]*Message, 0, len(receivedMessages))
- for _, msg := range receivedMessages {
- messages = append(messages, ToWhisperMessage(msg))
- }
-
- return messages, nil
-}
-
-// DeleteMessageFilter deletes a filter.
-func (api *PublicWhisperAPI) DeleteMessageFilter(id string) (bool, error) {
- api.mu.Lock()
- defer api.mu.Unlock()
-
- delete(api.lastUsed, id)
- return true, api.w.Unsubscribe(id)
-}
-
-// NewMessageFilter creates a new filter that can be used to poll for
-// (new) messages that satisfy the given criteria.
-func (api *PublicWhisperAPI) NewMessageFilter(req Criteria) (string, error) {
- var (
- src *ecdsa.PublicKey
- keySym []byte
- keyAsym *ecdsa.PrivateKey
- topics [][]byte
-
- symKeyGiven = len(req.SymKeyID) > 0
- asymKeyGiven = len(req.PrivateKeyID) > 0
-
- err error
- )
-
- // user must specify either a symmetric or an asymmetric key
- if (symKeyGiven && asymKeyGiven) || (!symKeyGiven && !asymKeyGiven) {
- return "", ErrSymAsym
- }
-
- if len(req.Sig) > 0 {
- src = crypto.ToECDSAPub(req.Sig)
- if !ValidatePublicKey(src) {
- return "", ErrInvalidSigningPubKey
- }
- }
-
- if symKeyGiven {
- if keySym, err = api.w.GetSymKey(req.SymKeyID); err != nil {
- return "", err
- }
- if !validateSymmetricKey(keySym) {
- return "", ErrInvalidSymmetricKey
- }
- }
-
- if asymKeyGiven {
- if keyAsym, err = api.w.GetPrivateKey(req.PrivateKeyID); err != nil {
- return "", err
- }
- }
-
- if len(req.Topics) > 0 {
- topics = make([][]byte, 1)
- for _, topic := range req.Topics {
- topics = append(topics, topic[:])
- }
- }
-
- f := &Filter{
- Src: src,
- KeySym: keySym,
- KeyAsym: keyAsym,
- PoW: req.MinPow,
- AllowP2P: req.AllowP2P,
- Topics: topics,
- Messages: make(map[common.Hash]*ReceivedMessage),
- }
-
- id, err := api.w.Subscribe(f)
- if err != nil {
- return "", err
- }
-
- api.mu.Lock()
- api.lastUsed[id] = time.Now()
- api.mu.Unlock()
-
- return id, nil
-}
diff --git a/whisper/whisperv6/benchmarks_test.go b/whisper/whisperv6/benchmarks_test.go
deleted file mode 100644
index 9f413e7b0a26..000000000000
--- a/whisper/whisperv6/benchmarks_test.go
+++ /dev/null
@@ -1,206 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv6
-
-import (
- "testing"
-
- "github.com/ethereum/go-ethereum/crypto"
-)
-
-func BenchmarkDeriveKeyMaterial(b *testing.B) {
- for i := 0; i < b.N; i++ {
- deriveKeyMaterial([]byte("test"), 0)
- }
-}
-
-func BenchmarkEncryptionSym(b *testing.B) {
- InitSingleTest()
-
- params, err := generateMessageParams()
- if err != nil {
- b.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- for i := 0; i < b.N; i++ {
- msg, _ := NewSentMessage(params)
- _, err := msg.Wrap(params)
- if err != nil {
- b.Errorf("failed Wrap with seed %d: %s.", seed, err)
- b.Errorf("i = %d, len(msg.Raw) = %d, params.Payload = %d.", i, len(msg.Raw), len(params.Payload))
- return
- }
- }
-}
-
-func BenchmarkEncryptionAsym(b *testing.B) {
- InitSingleTest()
-
- params, err := generateMessageParams()
- if err != nil {
- b.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- key, err := crypto.GenerateKey()
- if err != nil {
- b.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
- }
- params.KeySym = nil
- params.Dst = &key.PublicKey
-
- for i := 0; i < b.N; i++ {
- msg, _ := NewSentMessage(params)
- _, err := msg.Wrap(params)
- if err != nil {
- b.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
- }
-}
-
-func BenchmarkDecryptionSymValid(b *testing.B) {
- InitSingleTest()
-
- params, err := generateMessageParams()
- if err != nil {
- b.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- msg, _ := NewSentMessage(params)
- env, err := msg.Wrap(params)
- if err != nil {
- b.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
- f := Filter{KeySym: params.KeySym}
-
- for i := 0; i < b.N; i++ {
- msg := env.Open(&f)
- if msg == nil {
- b.Fatalf("failed to open with seed %d.", seed)
- }
- }
-}
-
-func BenchmarkDecryptionSymInvalid(b *testing.B) {
- InitSingleTest()
-
- params, err := generateMessageParams()
- if err != nil {
- b.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- msg, _ := NewSentMessage(params)
- env, err := msg.Wrap(params)
- if err != nil {
- b.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
- f := Filter{KeySym: []byte("arbitrary stuff here")}
-
- for i := 0; i < b.N; i++ {
- msg := env.Open(&f)
- if msg != nil {
- b.Fatalf("opened envelope with invalid key, seed: %d.", seed)
- }
- }
-}
-
-func BenchmarkDecryptionAsymValid(b *testing.B) {
- InitSingleTest()
-
- params, err := generateMessageParams()
- if err != nil {
- b.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- key, err := crypto.GenerateKey()
- if err != nil {
- b.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
- }
- f := Filter{KeyAsym: key}
- params.KeySym = nil
- params.Dst = &key.PublicKey
- msg, _ := NewSentMessage(params)
- env, err := msg.Wrap(params)
- if err != nil {
- b.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- for i := 0; i < b.N; i++ {
- msg := env.Open(&f)
- if msg == nil {
- b.Fatalf("fail to open, seed: %d.", seed)
- }
- }
-}
-
-func BenchmarkDecryptionAsymInvalid(b *testing.B) {
- InitSingleTest()
-
- params, err := generateMessageParams()
- if err != nil {
- b.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- key, err := crypto.GenerateKey()
- if err != nil {
- b.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
- }
- params.KeySym = nil
- params.Dst = &key.PublicKey
- msg, _ := NewSentMessage(params)
- env, err := msg.Wrap(params)
- if err != nil {
- b.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- key, err = crypto.GenerateKey()
- if err != nil {
- b.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
- }
- f := Filter{KeyAsym: key}
-
- for i := 0; i < b.N; i++ {
- msg := env.Open(&f)
- if msg != nil {
- b.Fatalf("opened envelope with invalid key, seed: %d.", seed)
- }
- }
-}
-
-func increment(x []byte) {
- for i := 0; i < len(x); i++ {
- x[i]++
- if x[i] != 0 {
- break
- }
- }
-}
-
-func BenchmarkPoW(b *testing.B) {
- InitSingleTest()
-
- params, err := generateMessageParams()
- if err != nil {
- b.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- params.Payload = make([]byte, 32)
- params.PoW = 10.0
- params.TTL = 1
-
- for i := 0; i < b.N; i++ {
- increment(params.Payload)
- msg, _ := NewSentMessage(params)
- _, err := msg.Wrap(params)
- if err != nil {
- b.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
- }
-}
diff --git a/whisper/whisperv6/config.go b/whisper/whisperv6/config.go
deleted file mode 100644
index d7f817aa2d7f..000000000000
--- a/whisper/whisperv6/config.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2017 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv6
-
-type Config struct {
- MaxMessageSize uint32 `toml:",omitempty"`
- MinimumAcceptedPOW float64 `toml:",omitempty"`
-}
-
-var DefaultConfig = Config{
- MaxMessageSize: DefaultMaxMessageSize,
- MinimumAcceptedPOW: DefaultMinimumPoW,
-}
diff --git a/whisper/whisperv6/doc.go b/whisper/whisperv6/doc.go
deleted file mode 100644
index e64dd2f42d90..000000000000
--- a/whisper/whisperv6/doc.go
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-/*
-Package whisper implements the Whisper protocol (version 6).
-
-Whisper combines aspects of both DHTs and datagram messaging systems (e.g. UDP).
-As such it may be likened and compared to both, not dissimilar to the
-matter/energy duality (apologies to physicists for the blatant abuse of a
-fundamental and beautiful natural principle).
-
-Whisper is a pure identity-based messaging system. Whisper provides a low-level
-(non-application-specific) but easily-accessible API without being based upon
-or prejudiced by the low-level hardware attributes and characteristics,
-particularly the notion of singular endpoints.
-*/
-package whisperv6
-
-import (
- "fmt"
- "time"
-)
-
-const (
- EnvelopeVersion = uint64(0)
- ProtocolVersion = uint64(5)
- ProtocolVersionStr = "5.0"
- ProtocolName = "shh"
-
- statusCode = 0 // used by whisper protocol
- messagesCode = 1 // normal whisper message
- p2pCode = 2 // peer-to-peer message (to be consumed by the peer, but not forwarded any further)
- p2pRequestCode = 3 // peer-to-peer message, used by Dapp protocol
- NumberOfMessageCodes = 64
-
- paddingMask = byte(3)
- signatureFlag = byte(4)
-
- TopicLength = 4
- signatureLength = 65
- aesKeyLength = 32
- AESNonceLength = 12
- keyIdSize = 32
-
- MaxMessageSize = uint32(10 * 1024 * 1024) // maximum accepted size of a message.
- DefaultMaxMessageSize = uint32(1024 * 1024)
- DefaultMinimumPoW = 0.2
-
- padSizeLimit = 256 // just an arbitrary number, could be changed without breaking the protocol (must not exceed 2^24)
- messageQueueLimit = 1024
-
- expirationCycle = time.Second
- transmissionCycle = 300 * time.Millisecond
-
- DefaultTTL = 50 // seconds
- SynchAllowance = 10 // seconds
-)
-
-type unknownVersionError uint64
-
-func (e unknownVersionError) Error() string {
- return fmt.Sprintf("invalid envelope version %d", uint64(e))
-}
-
-// MailServer represents a mail server, capable of
-// archiving the old messages for subsequent delivery
-// to the peers. Any implementation must ensure that both
-// functions are thread-safe. Also, they must return ASAP.
-// DeliverMail should use directMessagesCode for delivery,
-// in order to bypass the expiry checks.
-type MailServer interface {
- Archive(env *Envelope)
- DeliverMail(whisperPeer *Peer, request *Envelope)
-}
diff --git a/whisper/whisperv6/envelope.go b/whisper/whisperv6/envelope.go
deleted file mode 100644
index a5f4770b0760..000000000000
--- a/whisper/whisperv6/envelope.go
+++ /dev/null
@@ -1,246 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains the Whisper protocol Envelope element.
-
-package whisperv6
-
-import (
- "crypto/ecdsa"
- "encoding/binary"
- "fmt"
- gmath "math"
- "math/big"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/math"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/ecies"
- "github.com/ethereum/go-ethereum/rlp"
-)
-
-// Envelope represents a clear-text data packet to transmit through the Whisper
-// network. Its contents may or may not be encrypted and signed.
-type Envelope struct {
- Version []byte
- Expiry uint32
- TTL uint32
- Topic TopicType
- AESNonce []byte
- Data []byte
- EnvNonce uint64
-
- pow float64 // Message-specific PoW as described in the Whisper specification.
- hash common.Hash // Cached hash of the envelope to avoid rehashing every time.
- // Don't access hash directly, use Hash() function instead.
-}
-
-// size returns the size of envelope as it is sent (i.e. public fields only)
-func (e *Envelope) size() int {
- return 20 + len(e.Version) + len(e.AESNonce) + len(e.Data)
-}
-
-// rlpWithoutNonce returns the RLP encoded envelope contents, except the nonce.
-func (e *Envelope) rlpWithoutNonce() []byte {
- res, _ := rlp.EncodeToBytes([]interface{}{e.Version, e.Expiry, e.TTL, e.Topic, e.AESNonce, e.Data})
- return res
-}
-
-// NewEnvelope wraps a Whisper message with expiration and destination data
-// included into an envelope for network forwarding.
-func NewEnvelope(ttl uint32, topic TopicType, aesNonce []byte, msg *sentMessage) *Envelope {
- env := Envelope{
- Version: make([]byte, 1),
- Expiry: uint32(time.Now().Add(time.Second * time.Duration(ttl)).Unix()),
- TTL: ttl,
- Topic: topic,
- AESNonce: aesNonce,
- Data: msg.Raw,
- EnvNonce: 0,
- }
-
- if EnvelopeVersion < 256 {
- env.Version[0] = byte(EnvelopeVersion)
- } else {
- panic("please increase the size of Envelope.Version before releasing this version")
- }
-
- return &env
-}
-
-func (e *Envelope) IsSymmetric() bool {
- return len(e.AESNonce) > 0
-}
-
-func (e *Envelope) isAsymmetric() bool {
- return !e.IsSymmetric()
-}
-
-func (e *Envelope) Ver() uint64 {
- return bytesToUintLittleEndian(e.Version)
-}
-
-// Seal closes the envelope by spending the requested amount of time as a proof
-// of work on hashing the data.
-func (e *Envelope) Seal(options *MessageParams) error {
- var target, bestBit int
- if options.PoW == 0 {
- // adjust for the duration of Seal() execution only if execution time is predefined unconditionally
- e.Expiry += options.WorkTime
- } else {
- target = e.powToFirstBit(options.PoW)
- if target < 1 {
- target = 1
- }
- }
-
- buf := make([]byte, 64)
- h := crypto.Keccak256(e.rlpWithoutNonce())
- copy(buf[:32], h)
-
- finish := time.Now().Add(time.Duration(options.WorkTime) * time.Second).UnixNano()
- for nonce := uint64(0); time.Now().UnixNano() < finish; {
- for i := 0; i < 1024; i++ {
- binary.BigEndian.PutUint64(buf[56:], nonce)
- d := new(big.Int).SetBytes(crypto.Keccak256(buf))
- firstBit := math.FirstBitSet(d)
- if firstBit > bestBit {
- e.EnvNonce, bestBit = nonce, firstBit
- if target > 0 && bestBit >= target {
- return nil
- }
- }
- nonce++
- }
- }
-
- if target > 0 && bestBit < target {
- return fmt.Errorf("failed to reach the PoW target, specified pow time (%d seconds) was insufficient", options.WorkTime)
- }
-
- return nil
-}
-
-func (e *Envelope) PoW() float64 {
- if e.pow == 0 {
- e.calculatePoW(0)
- }
- return e.pow
-}
-
-func (e *Envelope) calculatePoW(diff uint32) {
- buf := make([]byte, 64)
- h := crypto.Keccak256(e.rlpWithoutNonce())
- copy(buf[:32], h)
- binary.BigEndian.PutUint64(buf[56:], e.EnvNonce)
- d := new(big.Int).SetBytes(crypto.Keccak256(buf))
- firstBit := math.FirstBitSet(d)
- x := gmath.Pow(2, float64(firstBit))
- x /= float64(e.size())
- x /= float64(e.TTL + diff)
- e.pow = x
-}
-
-func (e *Envelope) powToFirstBit(pow float64) int {
- x := pow
- x *= float64(e.size())
- x *= float64(e.TTL)
- bits := gmath.Log2(x)
- bits = gmath.Ceil(bits)
- return int(bits)
-}
-
-// Hash returns the SHA3 hash of the envelope, calculating it if not yet done.
-func (e *Envelope) Hash() common.Hash {
- if (e.hash == common.Hash{}) {
- encoded, _ := rlp.EncodeToBytes(e)
- e.hash = crypto.Keccak256Hash(encoded)
- }
- return e.hash
-}
-
-// DecodeRLP decodes an Envelope from an RLP data stream.
-func (e *Envelope) DecodeRLP(s *rlp.Stream) error {
- raw, err := s.Raw()
- if err != nil {
- return err
- }
- // The decoding of Envelope uses the struct fields but also needs
- // to compute the hash of the whole RLP-encoded envelope. This
- // type has the same structure as Envelope but is not an
- // rlp.Decoder (does not implement DecodeRLP function).
- // Only public members will be encoded.
- type rlpenv Envelope
- if err := rlp.DecodeBytes(raw, (*rlpenv)(e)); err != nil {
- return err
- }
- e.hash = crypto.Keccak256Hash(raw)
- return nil
-}
-
-// OpenAsymmetric tries to decrypt an envelope, potentially encrypted with a particular key.
-func (e *Envelope) OpenAsymmetric(key *ecdsa.PrivateKey) (*ReceivedMessage, error) {
- message := &ReceivedMessage{Raw: e.Data}
- err := message.decryptAsymmetric(key)
- switch err {
- case nil:
- return message, nil
- case ecies.ErrInvalidPublicKey: // addressed to somebody else
- return nil, err
- default:
- return nil, fmt.Errorf("unable to open envelope, decrypt failed: %v", err)
- }
-}
-
-// OpenSymmetric tries to decrypt an envelope, potentially encrypted with a particular key.
-func (e *Envelope) OpenSymmetric(key []byte) (msg *ReceivedMessage, err error) {
- msg = &ReceivedMessage{Raw: e.Data}
- err = msg.decryptSymmetric(key, e.AESNonce)
- if err != nil {
- msg = nil
- }
- return msg, err
-}
-
-// Open tries to decrypt an envelope, and populates the message fields in case of success.
-func (e *Envelope) Open(watcher *Filter) (msg *ReceivedMessage) {
- if e.isAsymmetric() {
- msg, _ = e.OpenAsymmetric(watcher.KeyAsym)
- if msg != nil {
- msg.Dst = &watcher.KeyAsym.PublicKey
- }
- } else if e.IsSymmetric() {
- msg, _ = e.OpenSymmetric(watcher.KeySym)
- if msg != nil {
- msg.SymKeyHash = crypto.Keccak256Hash(watcher.KeySym)
- }
- }
-
- if msg != nil {
- ok := msg.Validate()
- if !ok {
- return nil
- }
- msg.Topic = e.Topic
- msg.PoW = e.PoW()
- msg.TTL = e.TTL
- msg.Sent = e.Expiry - e.TTL
- msg.EnvelopeHash = e.Hash()
- msg.EnvelopeVersion = e.Ver()
- }
- return msg
-}
diff --git a/whisper/whisperv6/filter.go b/whisper/whisperv6/filter.go
deleted file mode 100644
index 5cb371b7d6ed..000000000000
--- a/whisper/whisperv6/filter.go
+++ /dev/null
@@ -1,239 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv6
-
-import (
- "crypto/ecdsa"
- "fmt"
- "sync"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
-)
-
-type Filter struct {
- Src *ecdsa.PublicKey // Sender of the message
- KeyAsym *ecdsa.PrivateKey // Private Key of recipient
- KeySym []byte // Key associated with the Topic
- Topics [][]byte // Topics to filter messages with
- PoW float64 // Proof of work as described in the Whisper spec
- AllowP2P bool // Indicates whether this filter is interested in direct peer-to-peer messages
- SymKeyHash common.Hash // The Keccak256Hash of the symmetric key, needed for optimization
-
- Messages map[common.Hash]*ReceivedMessage
- mutex sync.RWMutex
-}
-
-type Filters struct {
- watchers map[string]*Filter
- whisper *Whisper
- mutex sync.RWMutex
-}
-
-func NewFilters(w *Whisper) *Filters {
- return &Filters{
- watchers: make(map[string]*Filter),
- whisper: w,
- }
-}
-
-func (fs *Filters) Install(watcher *Filter) (string, error) {
- if watcher.Messages == nil {
- watcher.Messages = make(map[common.Hash]*ReceivedMessage)
- }
-
- id, err := GenerateRandomID()
- if err != nil {
- return "", err
- }
-
- fs.mutex.Lock()
- defer fs.mutex.Unlock()
-
- if fs.watchers[id] != nil {
- return "", fmt.Errorf("failed to generate unique ID")
- }
-
- if watcher.expectsSymmetricEncryption() {
- watcher.SymKeyHash = crypto.Keccak256Hash(watcher.KeySym)
- }
-
- fs.watchers[id] = watcher
- return id, err
-}
-
-func (fs *Filters) Uninstall(id string) bool {
- fs.mutex.Lock()
- defer fs.mutex.Unlock()
- if fs.watchers[id] != nil {
- delete(fs.watchers, id)
- return true
- }
- return false
-}
-
-func (fs *Filters) Get(id string) *Filter {
- fs.mutex.RLock()
- defer fs.mutex.RUnlock()
- return fs.watchers[id]
-}
-
-func (fs *Filters) NotifyWatchers(env *Envelope, p2pMessage bool) {
- var msg *ReceivedMessage
-
- fs.mutex.RLock()
- defer fs.mutex.RUnlock()
-
- i := -1 // only used for logging info
- for _, watcher := range fs.watchers {
- i++
- if p2pMessage && !watcher.AllowP2P {
- log.Trace(fmt.Sprintf("msg [%x], filter [%d]: p2p messages are not allowed", env.Hash(), i))
- continue
- }
-
- var match bool
- if msg != nil {
- match = watcher.MatchMessage(msg)
- } else {
- match = watcher.MatchEnvelope(env)
- if match {
- msg = env.Open(watcher)
- if msg == nil {
- log.Trace("processing message: failed to open", "message", env.Hash().Hex(), "filter", i)
- }
- } else {
- log.Trace("processing message: does not match", "message", env.Hash().Hex(), "filter", i)
- }
- }
-
- if match && msg != nil {
- log.Trace("processing message: decrypted", "hash", env.Hash().Hex())
- if watcher.Src == nil || IsPubKeyEqual(msg.Src, watcher.Src) {
- watcher.Trigger(msg)
- }
- }
- }
-}
-
-func (f *Filter) processEnvelope(env *Envelope) *ReceivedMessage {
- if f.MatchEnvelope(env) {
- msg := env.Open(f)
- if msg != nil {
- return msg
- } else {
- log.Trace("processing envelope: failed to open", "hash", env.Hash().Hex())
- }
- } else {
- log.Trace("processing envelope: does not match", "hash", env.Hash().Hex())
- }
- return nil
-}
-
-func (f *Filter) expectsAsymmetricEncryption() bool {
- return f.KeyAsym != nil
-}
-
-func (f *Filter) expectsSymmetricEncryption() bool {
- return f.KeySym != nil
-}
-
-func (f *Filter) Trigger(msg *ReceivedMessage) {
- f.mutex.Lock()
- defer f.mutex.Unlock()
-
- if _, exist := f.Messages[msg.EnvelopeHash]; !exist {
- f.Messages[msg.EnvelopeHash] = msg
- }
-}
-
-func (f *Filter) Retrieve() (all []*ReceivedMessage) {
- f.mutex.Lock()
- defer f.mutex.Unlock()
-
- all = make([]*ReceivedMessage, 0, len(f.Messages))
- for _, msg := range f.Messages {
- all = append(all, msg)
- }
-
- f.Messages = make(map[common.Hash]*ReceivedMessage) // delete old messages
- return all
-}
-
-func (f *Filter) MatchMessage(msg *ReceivedMessage) bool {
- if f.PoW > 0 && msg.PoW < f.PoW {
- return false
- }
-
- if f.expectsAsymmetricEncryption() && msg.isAsymmetricEncryption() {
- return IsPubKeyEqual(&f.KeyAsym.PublicKey, msg.Dst) && f.MatchTopic(msg.Topic)
- } else if f.expectsSymmetricEncryption() && msg.isSymmetricEncryption() {
- return f.SymKeyHash == msg.SymKeyHash && f.MatchTopic(msg.Topic)
- }
- return false
-}
-
-func (f *Filter) MatchEnvelope(envelope *Envelope) bool {
- if f.PoW > 0 && envelope.pow < f.PoW {
- return false
- }
-
- if f.expectsAsymmetricEncryption() && envelope.isAsymmetric() {
- return f.MatchTopic(envelope.Topic)
- } else if f.expectsSymmetricEncryption() && envelope.IsSymmetric() {
- return f.MatchTopic(envelope.Topic)
- }
- return false
-}
-
-func (f *Filter) MatchTopic(topic TopicType) bool {
- if len(f.Topics) == 0 {
- // any topic matches
- return true
- }
-
- for _, bt := range f.Topics {
- if matchSingleTopic(topic, bt) {
- return true
- }
- }
- return false
-}
-
-func matchSingleTopic(topic TopicType, bt []byte) bool {
- if len(bt) > 4 {
- bt = bt[:4]
- }
-
- for j, b := range bt {
- if topic[j] != b {
- return false
- }
- }
- return true
-}
-
-func IsPubKeyEqual(a, b *ecdsa.PublicKey) bool {
- if !ValidatePublicKey(a) {
- return false
- } else if !ValidatePublicKey(b) {
- return false
- }
- // the curve is always the same, just compare the points
- return a.X.Cmp(b.X) == 0 && a.Y.Cmp(b.Y) == 0
-}
diff --git a/whisper/whisperv6/filter_test.go b/whisper/whisperv6/filter_test.go
deleted file mode 100644
index 58d90d60c2c4..000000000000
--- a/whisper/whisperv6/filter_test.go
+++ /dev/null
@@ -1,814 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv6
-
-import (
- "math/big"
- mrand "math/rand"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
-)
-
-var seed int64
-
-// InitSingleTest should be called in the beginning of every
-// test, which uses RNG, in order to make the tests
-// reproduciblity independent of their sequence.
-func InitSingleTest() {
- seed = time.Now().Unix()
- mrand.Seed(seed)
-}
-
-func InitDebugTest(i int64) {
- seed = i
- mrand.Seed(seed)
-}
-
-type FilterTestCase struct {
- f *Filter
- id string
- alive bool
- msgCnt int
-}
-
-func generateFilter(t *testing.T, symmetric bool) (*Filter, error) {
- var f Filter
- f.Messages = make(map[common.Hash]*ReceivedMessage)
-
- const topicNum = 8
- f.Topics = make([][]byte, topicNum)
- for i := 0; i < topicNum; i++ {
- f.Topics[i] = make([]byte, 4)
- mrand.Read(f.Topics[i][:])
- f.Topics[i][0] = 0x01
- }
-
- key, err := crypto.GenerateKey()
- if err != nil {
- t.Fatalf("generateFilter 1 failed with seed %d.", seed)
- return nil, err
- }
- f.Src = &key.PublicKey
-
- if symmetric {
- f.KeySym = make([]byte, aesKeyLength)
- mrand.Read(f.KeySym)
- f.SymKeyHash = crypto.Keccak256Hash(f.KeySym)
- } else {
- f.KeyAsym, err = crypto.GenerateKey()
- if err != nil {
- t.Fatalf("generateFilter 2 failed with seed %d.", seed)
- return nil, err
- }
- }
-
- // AcceptP2P & PoW are not set
- return &f, nil
-}
-
-func generateTestCases(t *testing.T, SizeTestFilters int) []FilterTestCase {
- cases := make([]FilterTestCase, SizeTestFilters)
- for i := 0; i < SizeTestFilters; i++ {
- f, _ := generateFilter(t, true)
- cases[i].f = f
- cases[i].alive = (mrand.Int()&int(1) == 0)
- }
- return cases
-}
-
-func TestInstallFilters(t *testing.T) {
- InitSingleTest()
-
- const SizeTestFilters = 256
- w := New(&Config{})
- filters := NewFilters(w)
- tst := generateTestCases(t, SizeTestFilters)
-
- var err error
- var j string
- for i := 0; i < SizeTestFilters; i++ {
- j, err = filters.Install(tst[i].f)
- if err != nil {
- t.Fatalf("seed %d: failed to install filter: %s", seed, err)
- }
- tst[i].id = j
- if len(j) != keyIdSize*2 {
- t.Fatalf("seed %d: wrong filter id size [%d]", seed, len(j))
- }
- }
-
- for _, testCase := range tst {
- if !testCase.alive {
- filters.Uninstall(testCase.id)
- }
- }
-
- for i, testCase := range tst {
- fil := filters.Get(testCase.id)
- exist := (fil != nil)
- if exist != testCase.alive {
- t.Fatalf("seed %d: failed alive: %d, %v, %v", seed, i, exist, testCase.alive)
- }
- if exist && fil.PoW != testCase.f.PoW {
- t.Fatalf("seed %d: failed Get: %d, %v, %v", seed, i, exist, testCase.alive)
- }
- }
-}
-
-func TestInstallSymKeyGeneratesHash(t *testing.T) {
- InitSingleTest()
-
- w := New(&Config{})
- filters := NewFilters(w)
- filter, _ := generateFilter(t, true)
-
- // save the current SymKeyHash for comparison
- initialSymKeyHash := filter.SymKeyHash
-
- // ensure the SymKeyHash is invalid, for Install to recreate it
- var invalid common.Hash
- filter.SymKeyHash = invalid
-
- _, err := filters.Install(filter)
-
- if err != nil {
- t.Fatalf("Error installing the filter: %s", err)
- }
-
- for i, b := range filter.SymKeyHash {
- if b != initialSymKeyHash[i] {
- t.Fatalf("The filter's symmetric key hash was not properly generated by Install")
- }
- }
-}
-
-func TestInstallIdenticalFilters(t *testing.T) {
- InitSingleTest()
-
- w := New(&Config{})
- filters := NewFilters(w)
- filter1, _ := generateFilter(t, true)
-
- // Copy the first filter since some of its fields
- // are randomly gnerated.
- filter2 := &Filter{
- KeySym: filter1.KeySym,
- Topics: filter1.Topics,
- PoW: filter1.PoW,
- AllowP2P: filter1.AllowP2P,
- Messages: make(map[common.Hash]*ReceivedMessage),
- }
-
- _, err := filters.Install(filter1)
-
- if err != nil {
- t.Fatalf("Error installing the first filter with seed %d: %s", seed, err)
- }
-
- _, err = filters.Install(filter2)
-
- if err != nil {
- t.Fatalf("Error installing the second filter with seed %d: %s", seed, err)
- }
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("Error generating message parameters with seed %d: %s", seed, err)
- }
-
- params.KeySym = filter1.KeySym
- params.Topic = BytesToTopic(filter1.Topics[0])
-
- filter1.Src = ¶ms.Src.PublicKey
- filter2.Src = ¶ms.Src.PublicKey
-
- sentMessage, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := sentMessage.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
- msg := env.Open(filter1)
- if msg == nil {
- t.Fatalf("failed to Open with filter1")
- }
-
- if !filter1.MatchEnvelope(env) {
- t.Fatalf("failed matching with the first filter")
- }
-
- if !filter2.MatchEnvelope(env) {
- t.Fatalf("failed matching with the first filter")
- }
-
- if !filter1.MatchMessage(msg) {
- t.Fatalf("failed matching with the second filter")
- }
-
- if !filter2.MatchMessage(msg) {
- t.Fatalf("failed matching with the second filter")
- }
-}
-
-func TestComparePubKey(t *testing.T) {
- InitSingleTest()
-
- key1, err := crypto.GenerateKey()
- if err != nil {
- t.Fatalf("failed to generate first key with seed %d: %s.", seed, err)
- }
- key2, err := crypto.GenerateKey()
- if err != nil {
- t.Fatalf("failed to generate second key with seed %d: %s.", seed, err)
- }
- if IsPubKeyEqual(&key1.PublicKey, &key2.PublicKey) {
- t.Fatalf("public keys are equal, seed %d.", seed)
- }
-
- // generate key3 == key1
- mrand.Seed(seed)
- key3, err := crypto.GenerateKey()
- if err != nil {
- t.Fatalf("failed to generate third key with seed %d: %s.", seed, err)
- }
- if IsPubKeyEqual(&key1.PublicKey, &key3.PublicKey) {
- t.Fatalf("key1 == key3, seed %d.", seed)
- }
-}
-
-func TestMatchEnvelope(t *testing.T) {
- InitSingleTest()
-
- fsym, err := generateFilter(t, true)
- if err != nil {
- t.Fatalf("failed generateFilter with seed %d: %s.", seed, err)
- }
-
- fasym, err := generateFilter(t, false)
- if err != nil {
- t.Fatalf("failed generateFilter() with seed %d: %s.", seed, err)
- }
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- params.Topic[0] = 0xFF // ensure mismatch
-
- // mismatch with pseudo-random data
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
- match := fsym.MatchEnvelope(env)
- if match {
- t.Fatalf("failed MatchEnvelope symmetric with seed %d.", seed)
- }
- match = fasym.MatchEnvelope(env)
- if match {
- t.Fatalf("failed MatchEnvelope asymmetric with seed %d.", seed)
- }
-
- // encrypt symmetrically
- i := mrand.Int() % 4
- fsym.Topics[i] = params.Topic[:]
- fasym.Topics[i] = params.Topic[:]
- msg, err = NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err = msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap() with seed %d: %s.", seed, err)
- }
-
- // symmetric + matching topic: match
- match = fsym.MatchEnvelope(env)
- if !match {
- t.Fatalf("failed MatchEnvelope() symmetric with seed %d.", seed)
- }
-
- // asymmetric + matching topic: mismatch
- match = fasym.MatchEnvelope(env)
- if match {
- t.Fatalf("failed MatchEnvelope() asymmetric with seed %d.", seed)
- }
-
- // symmetric + matching topic + insufficient PoW: mismatch
- fsym.PoW = env.PoW() + 1.0
- match = fsym.MatchEnvelope(env)
- if match {
- t.Fatalf("failed MatchEnvelope(symmetric + matching topic + insufficient PoW) asymmetric with seed %d.", seed)
- }
-
- // symmetric + matching topic + sufficient PoW: match
- fsym.PoW = env.PoW() / 2
- match = fsym.MatchEnvelope(env)
- if !match {
- t.Fatalf("failed MatchEnvelope(symmetric + matching topic + sufficient PoW) with seed %d.", seed)
- }
-
- // symmetric + topics are nil (wildcard): match
- prevTopics := fsym.Topics
- fsym.Topics = nil
- match = fsym.MatchEnvelope(env)
- if !match {
- t.Fatalf("failed MatchEnvelope(symmetric + topics are nil) with seed %d.", seed)
- }
- fsym.Topics = prevTopics
-
- // encrypt asymmetrically
- key, err := crypto.GenerateKey()
- if err != nil {
- t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
- }
- params.KeySym = nil
- params.Dst = &key.PublicKey
- msg, err = NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err = msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap() with seed %d: %s.", seed, err)
- }
-
- // encryption method mismatch
- match = fsym.MatchEnvelope(env)
- if match {
- t.Fatalf("failed MatchEnvelope(encryption method mismatch) with seed %d.", seed)
- }
-
- // asymmetric + mismatching topic: mismatch
- match = fasym.MatchEnvelope(env)
- if !match {
- t.Fatalf("failed MatchEnvelope(asymmetric + mismatching topic) with seed %d.", seed)
- }
-
- // asymmetric + matching topic: match
- fasym.Topics[i] = fasym.Topics[i+1]
- match = fasym.MatchEnvelope(env)
- if match {
- t.Fatalf("failed MatchEnvelope(asymmetric + matching topic) with seed %d.", seed)
- }
-
- // asymmetric + filter without topic (wildcard): match
- fasym.Topics = nil
- match = fasym.MatchEnvelope(env)
- if !match {
- t.Fatalf("failed MatchEnvelope(asymmetric + filter without topic) with seed %d.", seed)
- }
-
- // asymmetric + insufficient PoW: mismatch
- fasym.PoW = env.PoW() + 1.0
- match = fasym.MatchEnvelope(env)
- if match {
- t.Fatalf("failed MatchEnvelope(asymmetric + insufficient PoW) with seed %d.", seed)
- }
-
- // asymmetric + sufficient PoW: match
- fasym.PoW = env.PoW() / 2
- match = fasym.MatchEnvelope(env)
- if !match {
- t.Fatalf("failed MatchEnvelope(asymmetric + sufficient PoW) with seed %d.", seed)
- }
-
- // filter without topic + envelope without topic: match
- env.Topic = TopicType{}
- match = fasym.MatchEnvelope(env)
- if !match {
- t.Fatalf("failed MatchEnvelope(filter without topic + envelope without topic) with seed %d.", seed)
- }
-
- // filter with topic + envelope without topic: mismatch
- fasym.Topics = fsym.Topics
- match = fasym.MatchEnvelope(env)
- if match {
- t.Fatalf("failed MatchEnvelope(filter without topic + envelope without topic) with seed %d.", seed)
- }
-}
-
-func TestMatchMessageSym(t *testing.T) {
- InitSingleTest()
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- f, err := generateFilter(t, true)
- if err != nil {
- t.Fatalf("failed generateFilter with seed %d: %s.", seed, err)
- }
-
- const index = 1
- params.KeySym = f.KeySym
- params.Topic = BytesToTopic(f.Topics[index])
-
- sentMessage, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := sentMessage.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
- msg := env.Open(f)
- if msg == nil {
- t.Fatalf("failed Open with seed %d.", seed)
- }
-
- // Src: match
- *f.Src.X = *params.Src.PublicKey.X
- *f.Src.Y = *params.Src.PublicKey.Y
- if !f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(src match) with seed %d.", seed)
- }
-
- // insufficient PoW: mismatch
- f.PoW = msg.PoW + 1.0
- if f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(insufficient PoW) with seed %d.", seed)
- }
-
- // sufficient PoW: match
- f.PoW = msg.PoW / 2
- if !f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(sufficient PoW) with seed %d.", seed)
- }
-
- // topic mismatch
- f.Topics[index][0]++
- if f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(topic mismatch) with seed %d.", seed)
- }
- f.Topics[index][0]--
-
- // key mismatch
- f.SymKeyHash[0]++
- if f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(key mismatch) with seed %d.", seed)
- }
- f.SymKeyHash[0]--
-
- // Src absent: match
- f.Src = nil
- if !f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(src absent) with seed %d.", seed)
- }
-
- // key hash mismatch
- h := f.SymKeyHash
- f.SymKeyHash = common.Hash{}
- if f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(key hash mismatch) with seed %d.", seed)
- }
- f.SymKeyHash = h
- if !f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(key hash match) with seed %d.", seed)
- }
-
- // encryption method mismatch
- f.KeySym = nil
- f.KeyAsym, err = crypto.GenerateKey()
- if err != nil {
- t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
- }
- if f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(encryption method mismatch) with seed %d.", seed)
- }
-}
-
-func TestMatchMessageAsym(t *testing.T) {
- InitSingleTest()
-
- f, err := generateFilter(t, false)
- if err != nil {
- t.Fatalf("failed generateFilter with seed %d: %s.", seed, err)
- }
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- const index = 1
- params.Topic = BytesToTopic(f.Topics[index])
- params.Dst = &f.KeyAsym.PublicKey
- keySymOrig := params.KeySym
- params.KeySym = nil
-
- sentMessage, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := sentMessage.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
- msg := env.Open(f)
- if msg == nil {
- t.Fatalf("failed to open with seed %d.", seed)
- }
-
- // Src: match
- *f.Src.X = *params.Src.PublicKey.X
- *f.Src.Y = *params.Src.PublicKey.Y
- if !f.MatchMessage(msg) {
- t.Fatalf("failed MatchMessage(src match) with seed %d.", seed)
- }
-
- // insufficient PoW: mismatch
- f.PoW = msg.PoW + 1.0
- if f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(insufficient PoW) with seed %d.", seed)
- }
-
- // sufficient PoW: match
- f.PoW = msg.PoW / 2
- if !f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(sufficient PoW) with seed %d.", seed)
- }
-
- // topic mismatch
- f.Topics[index][0]++
- if f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(topic mismatch) with seed %d.", seed)
- }
- f.Topics[index][0]--
-
- // key mismatch
- prev := *f.KeyAsym.PublicKey.X
- zero := *big.NewInt(0)
- *f.KeyAsym.PublicKey.X = zero
- if f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(key mismatch) with seed %d.", seed)
- }
- *f.KeyAsym.PublicKey.X = prev
-
- // Src absent: match
- f.Src = nil
- if !f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(src absent) with seed %d.", seed)
- }
-
- // encryption method mismatch
- f.KeySym = keySymOrig
- f.KeyAsym = nil
- if f.MatchMessage(msg) {
- t.Fatalf("failed MatchEnvelope(encryption method mismatch) with seed %d.", seed)
- }
-}
-
-func cloneFilter(orig *Filter) *Filter {
- var clone Filter
- clone.Messages = make(map[common.Hash]*ReceivedMessage)
- clone.Src = orig.Src
- clone.KeyAsym = orig.KeyAsym
- clone.KeySym = orig.KeySym
- clone.Topics = orig.Topics
- clone.PoW = orig.PoW
- clone.AllowP2P = orig.AllowP2P
- clone.SymKeyHash = orig.SymKeyHash
- return &clone
-}
-
-func generateCompatibeEnvelope(t *testing.T, f *Filter) *Envelope {
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- return nil
- }
-
- params.KeySym = f.KeySym
- params.Topic = BytesToTopic(f.Topics[2])
- sentMessage, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := sentMessage.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- return nil
- }
- return env
-}
-
-func TestWatchers(t *testing.T) {
- InitSingleTest()
-
- const NumFilters = 16
- const NumMessages = 256
- var i int
- var j uint32
- var e *Envelope
- var x, firstID string
- var err error
-
- w := New(&Config{})
- filters := NewFilters(w)
- tst := generateTestCases(t, NumFilters)
- for i = 0; i < NumFilters; i++ {
- tst[i].f.Src = nil
- x, err = filters.Install(tst[i].f)
- if err != nil {
- t.Fatalf("failed to install filter with seed %d: %s.", seed, err)
- }
- tst[i].id = x
- if len(firstID) == 0 {
- firstID = x
- }
- }
-
- lastID := x
-
- var envelopes [NumMessages]*Envelope
- for i = 0; i < NumMessages; i++ {
- j = mrand.Uint32() % NumFilters
- e = generateCompatibeEnvelope(t, tst[j].f)
- envelopes[i] = e
- tst[j].msgCnt++
- }
-
- for i = 0; i < NumMessages; i++ {
- filters.NotifyWatchers(envelopes[i], false)
- }
-
- var total int
- var mail []*ReceivedMessage
- var count [NumFilters]int
-
- for i = 0; i < NumFilters; i++ {
- mail = tst[i].f.Retrieve()
- count[i] = len(mail)
- total += len(mail)
- }
-
- if total != NumMessages {
- t.Fatalf("failed with seed %d: total = %d, want: %d.", seed, total, NumMessages)
- }
-
- for i = 0; i < NumFilters; i++ {
- mail = tst[i].f.Retrieve()
- if len(mail) != 0 {
- t.Fatalf("failed with seed %d: i = %d.", seed, i)
- }
-
- if tst[i].msgCnt != count[i] {
- t.Fatalf("failed with seed %d: count[%d]: get %d, want %d.", seed, i, tst[i].msgCnt, count[i])
- }
- }
-
- // another round with a cloned filter
-
- clone := cloneFilter(tst[0].f)
- filters.Uninstall(lastID)
- total = 0
- last := NumFilters - 1
- tst[last].f = clone
- filters.Install(clone)
- for i = 0; i < NumFilters; i++ {
- tst[i].msgCnt = 0
- count[i] = 0
- }
-
- // make sure that the first watcher receives at least one message
- e = generateCompatibeEnvelope(t, tst[0].f)
- envelopes[0] = e
- tst[0].msgCnt++
- for i = 1; i < NumMessages; i++ {
- j = mrand.Uint32() % NumFilters
- e = generateCompatibeEnvelope(t, tst[j].f)
- envelopes[i] = e
- tst[j].msgCnt++
- }
-
- for i = 0; i < NumMessages; i++ {
- filters.NotifyWatchers(envelopes[i], false)
- }
-
- for i = 0; i < NumFilters; i++ {
- mail = tst[i].f.Retrieve()
- count[i] = len(mail)
- total += len(mail)
- }
-
- combined := tst[0].msgCnt + tst[last].msgCnt
- if total != NumMessages+count[0] {
- t.Fatalf("failed with seed %d: total = %d, count[0] = %d.", seed, total, count[0])
- }
-
- if combined != count[0] {
- t.Fatalf("failed with seed %d: combined = %d, count[0] = %d.", seed, combined, count[0])
- }
-
- if combined != count[last] {
- t.Fatalf("failed with seed %d: combined = %d, count[last] = %d.", seed, combined, count[last])
- }
-
- for i = 1; i < NumFilters-1; i++ {
- mail = tst[i].f.Retrieve()
- if len(mail) != 0 {
- t.Fatalf("failed with seed %d: i = %d.", seed, i)
- }
-
- if tst[i].msgCnt != count[i] {
- t.Fatalf("failed with seed %d: i = %d, get %d, want %d.", seed, i, tst[i].msgCnt, count[i])
- }
- }
-
- // test AcceptP2P
-
- total = 0
- filters.NotifyWatchers(envelopes[0], true)
-
- for i = 0; i < NumFilters; i++ {
- mail = tst[i].f.Retrieve()
- total += len(mail)
- }
-
- if total != 0 {
- t.Fatalf("failed with seed %d: total: got %d, want 0.", seed, total)
- }
-
- f := filters.Get(firstID)
- if f == nil {
- t.Fatalf("failed to get the filter with seed %d.", seed)
- }
- f.AllowP2P = true
- total = 0
- filters.NotifyWatchers(envelopes[0], true)
-
- for i = 0; i < NumFilters; i++ {
- mail = tst[i].f.Retrieve()
- total += len(mail)
- }
-
- if total != 1 {
- t.Fatalf("failed with seed %d: total: got %d, want 1.", seed, total)
- }
-}
-
-func TestVariableTopics(t *testing.T) {
- InitSingleTest()
-
- var match bool
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- f, err := generateFilter(t, true)
- if err != nil {
- t.Fatalf("failed generateFilter with seed %d: %s.", seed, err)
- }
-
- for i := 0; i < 4; i++ {
- arr := make([]byte, i+1, 4)
- copy(arr, env.Topic[:i+1])
-
- f.Topics[4] = arr
- match = f.MatchEnvelope(env)
- if !match {
- t.Fatalf("failed MatchEnvelope symmetric with seed %d, step %d.", seed, i)
- }
-
- f.Topics[4][i]++
- match = f.MatchEnvelope(env)
- if match {
- t.Fatalf("MatchEnvelope symmetric with seed %d, step %d: false positive.", seed, i)
- }
- }
-}
diff --git a/whisper/whisperv6/gen_criteria_json.go b/whisper/whisperv6/gen_criteria_json.go
deleted file mode 100644
index 52a4d3cb66ad..000000000000
--- a/whisper/whisperv6/gen_criteria_json.go
+++ /dev/null
@@ -1,64 +0,0 @@
-// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
-
-package whisperv6
-
-import (
- "encoding/json"
-
- "github.com/ethereum/go-ethereum/common/hexutil"
-)
-
-var _ = (*criteriaOverride)(nil)
-
-func (c Criteria) MarshalJSON() ([]byte, error) {
- type Criteria struct {
- SymKeyID string `json:"symKeyID"`
- PrivateKeyID string `json:"privateKeyID"`
- Sig hexutil.Bytes `json:"sig"`
- MinPow float64 `json:"minPow"`
- Topics []TopicType `json:"topics"`
- AllowP2P bool `json:"allowP2P"`
- }
- var enc Criteria
- enc.SymKeyID = c.SymKeyID
- enc.PrivateKeyID = c.PrivateKeyID
- enc.Sig = c.Sig
- enc.MinPow = c.MinPow
- enc.Topics = c.Topics
- enc.AllowP2P = c.AllowP2P
- return json.Marshal(&enc)
-}
-
-func (c *Criteria) UnmarshalJSON(input []byte) error {
- type Criteria struct {
- SymKeyID *string `json:"symKeyID"`
- PrivateKeyID *string `json:"privateKeyID"`
- Sig hexutil.Bytes `json:"sig"`
- MinPow *float64 `json:"minPow"`
- Topics []TopicType `json:"topics"`
- AllowP2P *bool `json:"allowP2P"`
- }
- var dec Criteria
- if err := json.Unmarshal(input, &dec); err != nil {
- return err
- }
- if dec.SymKeyID != nil {
- c.SymKeyID = *dec.SymKeyID
- }
- if dec.PrivateKeyID != nil {
- c.PrivateKeyID = *dec.PrivateKeyID
- }
- if dec.Sig != nil {
- c.Sig = dec.Sig
- }
- if dec.MinPow != nil {
- c.MinPow = *dec.MinPow
- }
- if dec.Topics != nil {
- c.Topics = dec.Topics
- }
- if dec.AllowP2P != nil {
- c.AllowP2P = *dec.AllowP2P
- }
- return nil
-}
diff --git a/whisper/whisperv6/gen_message_json.go b/whisper/whisperv6/gen_message_json.go
deleted file mode 100644
index 27b46752befc..000000000000
--- a/whisper/whisperv6/gen_message_json.go
+++ /dev/null
@@ -1,82 +0,0 @@
-// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
-
-package whisperv6
-
-import (
- "encoding/json"
-
- "github.com/ethereum/go-ethereum/common/hexutil"
-)
-
-var _ = (*messageOverride)(nil)
-
-func (m Message) MarshalJSON() ([]byte, error) {
- type Message struct {
- Sig hexutil.Bytes `json:"sig,omitempty"`
- TTL uint32 `json:"ttl"`
- Timestamp uint32 `json:"timestamp"`
- Topic TopicType `json:"topic"`
- Payload hexutil.Bytes `json:"payload"`
- Padding hexutil.Bytes `json:"padding"`
- PoW float64 `json:"pow"`
- Hash hexutil.Bytes `json:"hash"`
- Dst hexutil.Bytes `json:"recipientPublicKey,omitempty"`
- }
- var enc Message
- enc.Sig = m.Sig
- enc.TTL = m.TTL
- enc.Timestamp = m.Timestamp
- enc.Topic = m.Topic
- enc.Payload = m.Payload
- enc.Padding = m.Padding
- enc.PoW = m.PoW
- enc.Hash = m.Hash
- enc.Dst = m.Dst
- return json.Marshal(&enc)
-}
-
-func (m *Message) UnmarshalJSON(input []byte) error {
- type Message struct {
- Sig hexutil.Bytes `json:"sig,omitempty"`
- TTL *uint32 `json:"ttl"`
- Timestamp *uint32 `json:"timestamp"`
- Topic *TopicType `json:"topic"`
- Payload hexutil.Bytes `json:"payload"`
- Padding hexutil.Bytes `json:"padding"`
- PoW *float64 `json:"pow"`
- Hash hexutil.Bytes `json:"hash"`
- Dst hexutil.Bytes `json:"recipientPublicKey,omitempty"`
- }
- var dec Message
- if err := json.Unmarshal(input, &dec); err != nil {
- return err
- }
- if dec.Sig != nil {
- m.Sig = dec.Sig
- }
- if dec.TTL != nil {
- m.TTL = *dec.TTL
- }
- if dec.Timestamp != nil {
- m.Timestamp = *dec.Timestamp
- }
- if dec.Topic != nil {
- m.Topic = *dec.Topic
- }
- if dec.Payload != nil {
- m.Payload = dec.Payload
- }
- if dec.Padding != nil {
- m.Padding = dec.Padding
- }
- if dec.PoW != nil {
- m.PoW = *dec.PoW
- }
- if dec.Hash != nil {
- m.Hash = dec.Hash
- }
- if dec.Dst != nil {
- m.Dst = dec.Dst
- }
- return nil
-}
diff --git a/whisper/whisperv6/gen_newmessage_json.go b/whisper/whisperv6/gen_newmessage_json.go
deleted file mode 100644
index d16011a57903..000000000000
--- a/whisper/whisperv6/gen_newmessage_json.go
+++ /dev/null
@@ -1,88 +0,0 @@
-// Code generated by github.com/fjl/gencodec. DO NOT EDIT.
-
-package whisperv6
-
-import (
- "encoding/json"
-
- "github.com/ethereum/go-ethereum/common/hexutil"
-)
-
-var _ = (*newMessageOverride)(nil)
-
-func (n NewMessage) MarshalJSON() ([]byte, error) {
- type NewMessage struct {
- SymKeyID string `json:"symKeyID"`
- PublicKey hexutil.Bytes `json:"pubKey"`
- Sig string `json:"sig"`
- TTL uint32 `json:"ttl"`
- Topic TopicType `json:"topic"`
- Payload hexutil.Bytes `json:"payload"`
- Padding hexutil.Bytes `json:"padding"`
- PowTime uint32 `json:"powTime"`
- PowTarget float64 `json:"powTarget"`
- TargetPeer string `json:"targetPeer"`
- }
- var enc NewMessage
- enc.SymKeyID = n.SymKeyID
- enc.PublicKey = n.PublicKey
- enc.Sig = n.Sig
- enc.TTL = n.TTL
- enc.Topic = n.Topic
- enc.Payload = n.Payload
- enc.Padding = n.Padding
- enc.PowTime = n.PowTime
- enc.PowTarget = n.PowTarget
- enc.TargetPeer = n.TargetPeer
- return json.Marshal(&enc)
-}
-
-func (n *NewMessage) UnmarshalJSON(input []byte) error {
- type NewMessage struct {
- SymKeyID *string `json:"symKeyID"`
- PublicKey hexutil.Bytes `json:"pubKey"`
- Sig *string `json:"sig"`
- TTL *uint32 `json:"ttl"`
- Topic *TopicType `json:"topic"`
- Payload hexutil.Bytes `json:"payload"`
- Padding hexutil.Bytes `json:"padding"`
- PowTime *uint32 `json:"powTime"`
- PowTarget *float64 `json:"powTarget"`
- TargetPeer *string `json:"targetPeer"`
- }
- var dec NewMessage
- if err := json.Unmarshal(input, &dec); err != nil {
- return err
- }
- if dec.SymKeyID != nil {
- n.SymKeyID = *dec.SymKeyID
- }
- if dec.PublicKey != nil {
- n.PublicKey = dec.PublicKey
- }
- if dec.Sig != nil {
- n.Sig = *dec.Sig
- }
- if dec.TTL != nil {
- n.TTL = *dec.TTL
- }
- if dec.Topic != nil {
- n.Topic = *dec.Topic
- }
- if dec.Payload != nil {
- n.Payload = dec.Payload
- }
- if dec.Padding != nil {
- n.Padding = dec.Padding
- }
- if dec.PowTime != nil {
- n.PowTime = *dec.PowTime
- }
- if dec.PowTarget != nil {
- n.PowTarget = *dec.PowTarget
- }
- if dec.TargetPeer != nil {
- n.TargetPeer = *dec.TargetPeer
- }
- return nil
-}
diff --git a/whisper/whisperv6/message.go b/whisper/whisperv6/message.go
deleted file mode 100644
index 0815f07a2d12..000000000000
--- a/whisper/whisperv6/message.go
+++ /dev/null
@@ -1,352 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains the Whisper protocol Message element.
-
-package whisperv6
-
-import (
- "crypto/aes"
- "crypto/cipher"
- "crypto/ecdsa"
- crand "crypto/rand"
- "encoding/binary"
- "errors"
- "strconv"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/crypto/ecies"
- "github.com/ethereum/go-ethereum/log"
-)
-
-// Options specifies the exact way a message should be wrapped into an Envelope.
-type MessageParams struct {
- TTL uint32
- Src *ecdsa.PrivateKey
- Dst *ecdsa.PublicKey
- KeySym []byte
- Topic TopicType
- WorkTime uint32
- PoW float64
- Payload []byte
- Padding []byte
-}
-
-// SentMessage represents an end-user data packet to transmit through the
-// Whisper protocol. These are wrapped into Envelopes that need not be
-// understood by intermediate nodes, just forwarded.
-type sentMessage struct {
- Raw []byte
-}
-
-// ReceivedMessage represents a data packet to be received through the
-// Whisper protocol.
-type ReceivedMessage struct {
- Raw []byte
-
- Payload []byte
- Padding []byte
- Signature []byte
-
- PoW float64 // Proof of work as described in the Whisper spec
- Sent uint32 // Time when the message was posted into the network
- TTL uint32 // Maximum time to live allowed for the message
- Src *ecdsa.PublicKey // Message recipient (identity used to decode the message)
- Dst *ecdsa.PublicKey // Message recipient (identity used to decode the message)
- Topic TopicType
-
- SymKeyHash common.Hash // The Keccak256Hash of the key, associated with the Topic
- EnvelopeHash common.Hash // Message envelope hash to act as a unique id
- EnvelopeVersion uint64
-}
-
-func isMessageSigned(flags byte) bool {
- return (flags & signatureFlag) != 0
-}
-
-func (msg *ReceivedMessage) isSymmetricEncryption() bool {
- return msg.SymKeyHash != common.Hash{}
-}
-
-func (msg *ReceivedMessage) isAsymmetricEncryption() bool {
- return msg.Dst != nil
-}
-
-// NewMessage creates and initializes a non-signed, non-encrypted Whisper message.
-func NewSentMessage(params *MessageParams) (*sentMessage, error) {
- msg := sentMessage{}
- msg.Raw = make([]byte, 1, len(params.Payload)+len(params.Padding)+signatureLength+padSizeLimit)
- msg.Raw[0] = 0 // set all the flags to zero
- err := msg.appendPadding(params)
- if err != nil {
- return nil, err
- }
- msg.Raw = append(msg.Raw, params.Payload...)
- return &msg, nil
-}
-
-// getSizeOfLength returns the number of bytes necessary to encode the entire size padding (including these bytes)
-func getSizeOfLength(b []byte) (sz int, err error) {
- sz = intSize(len(b)) // first iteration
- sz = intSize(len(b) + sz) // second iteration
- if sz > 3 {
- err = errors.New("oversized padding parameter")
- }
- return sz, err
-}
-
-// sizeOfIntSize returns minimal number of bytes necessary to encode an integer value
-func intSize(i int) (s int) {
- for s = 1; i >= 256; s++ {
- i /= 256
- }
- return s
-}
-
-// appendPadding appends the pseudorandom padding bytes and sets the padding flag.
-// The last byte contains the size of padding (thus, its size must not exceed 256).
-func (msg *sentMessage) appendPadding(params *MessageParams) error {
- rawSize := len(params.Payload) + 1
- if params.Src != nil {
- rawSize += signatureLength
- }
- odd := rawSize % padSizeLimit
-
- if len(params.Padding) != 0 {
- padSize := len(params.Padding)
- padLengthSize, err := getSizeOfLength(params.Padding)
- if err != nil {
- return err
- }
- totalPadSize := padSize + padLengthSize
- buf := make([]byte, 8)
- binary.LittleEndian.PutUint32(buf, uint32(totalPadSize))
- buf = buf[:padLengthSize]
- msg.Raw = append(msg.Raw, buf...)
- msg.Raw = append(msg.Raw, params.Padding...)
- msg.Raw[0] |= byte(padLengthSize) // number of bytes indicating the padding size
- } else if odd != 0 {
- totalPadSize := padSizeLimit - odd
- if totalPadSize > 255 {
- // this algorithm is only valid if padSizeLimit < 256.
- // if padSizeLimit will ever change, please fix the algorithm
- // (please see also ReceivedMessage.extractPadding() function).
- panic("please fix the padding algorithm before releasing new version")
- }
- buf := make([]byte, totalPadSize)
- _, err := crand.Read(buf[1:])
- if err != nil {
- return err
- }
- if totalPadSize > 6 && !validateSymmetricKey(buf) {
- return errors.New("failed to generate random padding of size " + strconv.Itoa(totalPadSize))
- }
- buf[0] = byte(totalPadSize)
- msg.Raw = append(msg.Raw, buf...)
- msg.Raw[0] |= byte(0x1) // number of bytes indicating the padding size
- }
- return nil
-}
-
-// sign calculates and sets the cryptographic signature for the message,
-// also setting the sign flag.
-func (msg *sentMessage) sign(key *ecdsa.PrivateKey) error {
- if isMessageSigned(msg.Raw[0]) {
- // this should not happen, but no reason to panic
- log.Error("failed to sign the message: already signed")
- return nil
- }
-
- msg.Raw[0] |= signatureFlag
- hash := crypto.Keccak256(msg.Raw)
- signature, err := crypto.Sign(hash, key)
- if err != nil {
- msg.Raw[0] &= ^signatureFlag // clear the flag
- return err
- }
- msg.Raw = append(msg.Raw, signature...)
- return nil
-}
-
-// encryptAsymmetric encrypts a message with a public key.
-func (msg *sentMessage) encryptAsymmetric(key *ecdsa.PublicKey) error {
- if !ValidatePublicKey(key) {
- return errors.New("invalid public key provided for asymmetric encryption")
- }
- encrypted, err := ecies.Encrypt(crand.Reader, ecies.ImportECDSAPublic(key), msg.Raw, nil, nil)
- if err == nil {
- msg.Raw = encrypted
- }
- return err
-}
-
-// encryptSymmetric encrypts a message with a topic key, using AES-GCM-256.
-// nonce size should be 12 bytes (see cipher.gcmStandardNonceSize).
-func (msg *sentMessage) encryptSymmetric(key []byte) (nonce []byte, err error) {
- if !validateSymmetricKey(key) {
- return nil, errors.New("invalid key provided for symmetric encryption")
- }
-
- block, err := aes.NewCipher(key)
- if err != nil {
- return nil, err
- }
- aesgcm, err := cipher.NewGCM(block)
- if err != nil {
- return nil, err
- }
-
- // never use more than 2^32 random nonces with a given key
- nonce = make([]byte, aesgcm.NonceSize())
- _, err = crand.Read(nonce)
- if err != nil {
- return nil, err
- } else if !validateSymmetricKey(nonce) {
- return nil, errors.New("crypto/rand failed to generate nonce")
- }
-
- msg.Raw = aesgcm.Seal(nil, nonce, msg.Raw, nil)
- return nonce, nil
-}
-
-// Wrap bundles the message into an Envelope to transmit over the network.
-func (msg *sentMessage) Wrap(options *MessageParams) (envelope *Envelope, err error) {
- if options.TTL == 0 {
- options.TTL = DefaultTTL
- }
- if options.Src != nil {
- if err = msg.sign(options.Src); err != nil {
- return nil, err
- }
- }
- var nonce []byte
- if options.Dst != nil {
- err = msg.encryptAsymmetric(options.Dst)
- } else if options.KeySym != nil {
- nonce, err = msg.encryptSymmetric(options.KeySym)
- } else {
- err = errors.New("unable to encrypt the message: neither symmetric nor assymmetric key provided")
- }
- if err != nil {
- return nil, err
- }
-
- envelope = NewEnvelope(options.TTL, options.Topic, nonce, msg)
- if err = envelope.Seal(options); err != nil {
- return nil, err
- }
- return envelope, nil
-}
-
-// decryptSymmetric decrypts a message with a topic key, using AES-GCM-256.
-// nonce size should be 12 bytes (see cipher.gcmStandardNonceSize).
-func (msg *ReceivedMessage) decryptSymmetric(key []byte, nonce []byte) error {
- block, err := aes.NewCipher(key)
- if err != nil {
- return err
- }
- aesgcm, err := cipher.NewGCM(block)
- if err != nil {
- return err
- }
- if len(nonce) != aesgcm.NonceSize() {
- log.Error("decrypting the message", "AES nonce size", len(nonce))
- return errors.New("wrong AES nonce size")
- }
- decrypted, err := aesgcm.Open(nil, nonce, msg.Raw, nil)
- if err != nil {
- return err
- }
- msg.Raw = decrypted
- return nil
-}
-
-// decryptAsymmetric decrypts an encrypted payload with a private key.
-func (msg *ReceivedMessage) decryptAsymmetric(key *ecdsa.PrivateKey) error {
- decrypted, err := ecies.ImportECDSA(key).Decrypt(crand.Reader, msg.Raw, nil, nil)
- if err == nil {
- msg.Raw = decrypted
- }
- return err
-}
-
-// Validate checks the validity and extracts the fields in case of success
-func (msg *ReceivedMessage) Validate() bool {
- end := len(msg.Raw)
- if end < 1 {
- return false
- }
-
- if isMessageSigned(msg.Raw[0]) {
- end -= signatureLength
- if end <= 1 {
- return false
- }
- msg.Signature = msg.Raw[end:]
- msg.Src = msg.SigToPubKey()
- if msg.Src == nil {
- return false
- }
- }
-
- padSize, ok := msg.extractPadding(end)
- if !ok {
- return false
- }
-
- msg.Payload = msg.Raw[1+padSize : end]
- return true
-}
-
-// extractPadding extracts the padding from raw message.
-// although we don't support sending messages with padding size
-// exceeding 255 bytes, such messages are perfectly valid, and
-// can be successfully decrypted.
-func (msg *ReceivedMessage) extractPadding(end int) (int, bool) {
- paddingSize := 0
- sz := int(msg.Raw[0] & paddingMask) // number of bytes indicating the entire size of padding (including these bytes)
- // could be zero -- it means no padding
- if sz != 0 {
- paddingSize = int(bytesToUintLittleEndian(msg.Raw[1 : 1+sz]))
- if paddingSize < sz || paddingSize+1 > end {
- return 0, false
- }
- msg.Padding = msg.Raw[1+sz : 1+paddingSize]
- }
- return paddingSize, true
-}
-
-// Recover retrieves the public key of the message signer.
-func (msg *ReceivedMessage) SigToPubKey() *ecdsa.PublicKey {
- defer func() { recover() }() // in case of invalid signature
-
- pub, err := crypto.SigToPub(msg.hash(), msg.Signature)
- if err != nil {
- log.Error("failed to recover public key from signature", "err", err)
- return nil
- }
- return pub
-}
-
-// hash calculates the SHA3 checksum of the message flags, payload and padding.
-func (msg *ReceivedMessage) hash() []byte {
- if isMessageSigned(msg.Raw[0]) {
- sz := len(msg.Raw) - signatureLength
- return crypto.Keccak256(msg.Raw[:sz])
- }
- return crypto.Keccak256(msg.Raw)
-}
diff --git a/whisper/whisperv6/message_test.go b/whisper/whisperv6/message_test.go
deleted file mode 100644
index 912b90f14579..000000000000
--- a/whisper/whisperv6/message_test.go
+++ /dev/null
@@ -1,415 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv6
-
-import (
- "bytes"
- mrand "math/rand"
- "testing"
-
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/rlp"
-)
-
-func generateMessageParams() (*MessageParams, error) {
- // set all the parameters except p.Dst and p.Padding
-
- buf := make([]byte, 4)
- mrand.Read(buf)
- sz := mrand.Intn(400)
-
- var p MessageParams
- p.PoW = 0.01
- p.WorkTime = 1
- p.TTL = uint32(mrand.Intn(1024))
- p.Payload = make([]byte, sz)
- p.KeySym = make([]byte, aesKeyLength)
- mrand.Read(p.Payload)
- mrand.Read(p.KeySym)
- p.Topic = BytesToTopic(buf)
-
- var err error
- p.Src, err = crypto.GenerateKey()
- if err != nil {
- return nil, err
- }
-
- return &p, nil
-}
-
-func singleMessageTest(t *testing.T, symmetric bool) {
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- key, err := crypto.GenerateKey()
- if err != nil {
- t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
- }
-
- if !symmetric {
- params.KeySym = nil
- params.Dst = &key.PublicKey
- }
-
- text := make([]byte, 0, 512)
- text = append(text, params.Payload...)
-
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- var decrypted *ReceivedMessage
- if symmetric {
- decrypted, err = env.OpenSymmetric(params.KeySym)
- } else {
- decrypted, err = env.OpenAsymmetric(key)
- }
-
- if err != nil {
- t.Fatalf("failed to encrypt with seed %d: %s.", seed, err)
- }
-
- if !decrypted.Validate() {
- t.Fatalf("failed to validate with seed %d.", seed)
- }
-
- if !bytes.Equal(text, decrypted.Payload) {
- t.Fatalf("failed with seed %d: compare payload.", seed)
- }
- if !isMessageSigned(decrypted.Raw[0]) {
- t.Fatalf("failed with seed %d: unsigned.", seed)
- }
- if len(decrypted.Signature) != signatureLength {
- t.Fatalf("failed with seed %d: signature len %d.", seed, len(decrypted.Signature))
- }
- if !IsPubKeyEqual(decrypted.Src, ¶ms.Src.PublicKey) {
- t.Fatalf("failed with seed %d: signature mismatch.", seed)
- }
-}
-
-func TestMessageEncryption(t *testing.T) {
- InitSingleTest()
-
- var symmetric bool
- for i := 0; i < 256; i++ {
- singleMessageTest(t, symmetric)
- symmetric = !symmetric
- }
-}
-
-func TestMessageWrap(t *testing.T) {
- seed = int64(1777444222)
- mrand.Seed(seed)
- target := 128.0
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- params.TTL = 1
- params.WorkTime = 12
- params.PoW = target
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- pow := env.PoW()
- if pow < target {
- t.Fatalf("failed Wrap with seed %d: pow < target (%f vs. %f).", seed, pow, target)
- }
-
- // set PoW target too high, expect error
- msg2, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- params.TTL = 1000000
- params.WorkTime = 1
- params.PoW = 10000000.0
- _, err = msg2.Wrap(params)
- if err == nil {
- t.Fatalf("unexpectedly reached the PoW target with seed %d.", seed)
- }
-}
-
-func TestMessageSeal(t *testing.T) {
- // this test depends on deterministic choice of seed (1976726903)
- seed = int64(1976726903)
- mrand.Seed(seed)
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- params.TTL = 1
- aesnonce := make([]byte, 12)
- mrand.Read(aesnonce)
-
- env := NewEnvelope(params.TTL, params.Topic, aesnonce, msg)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- env.Expiry = uint32(seed) // make it deterministic
- target := 32.0
- params.WorkTime = 4
- params.PoW = target
- env.Seal(params)
-
- env.calculatePoW(0)
- pow := env.PoW()
- if pow < target {
- t.Fatalf("failed Wrap with seed %d: pow < target (%f vs. %f).", seed, pow, target)
- }
-
- params.WorkTime = 1
- params.PoW = 1000000000.0
- env.Seal(params)
- env.calculatePoW(0)
- pow = env.PoW()
- if pow < 2*target {
- t.Fatalf("failed Wrap with seed %d: pow too small %f.", seed, pow)
- }
-}
-
-func TestEnvelopeOpen(t *testing.T) {
- InitSingleTest()
-
- var symmetric bool
- for i := 0; i < 256; i++ {
- singleEnvelopeOpenTest(t, symmetric)
- symmetric = !symmetric
- }
-}
-
-func singleEnvelopeOpenTest(t *testing.T, symmetric bool) {
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- key, err := crypto.GenerateKey()
- if err != nil {
- t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
- }
-
- if !symmetric {
- params.KeySym = nil
- params.Dst = &key.PublicKey
- }
-
- text := make([]byte, 0, 512)
- text = append(text, params.Payload...)
-
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- f := Filter{KeyAsym: key, KeySym: params.KeySym}
- decrypted := env.Open(&f)
- if decrypted == nil {
- t.Fatalf("failed to open with seed %d.", seed)
- }
-
- if !bytes.Equal(text, decrypted.Payload) {
- t.Fatalf("failed with seed %d: compare payload.", seed)
- }
- if !isMessageSigned(decrypted.Raw[0]) {
- t.Fatalf("failed with seed %d: unsigned.", seed)
- }
- if len(decrypted.Signature) != signatureLength {
- t.Fatalf("failed with seed %d: signature len %d.", seed, len(decrypted.Signature))
- }
- if !IsPubKeyEqual(decrypted.Src, ¶ms.Src.PublicKey) {
- t.Fatalf("failed with seed %d: signature mismatch.", seed)
- }
- if decrypted.isAsymmetricEncryption() == symmetric {
- t.Fatalf("failed with seed %d: asymmetric %v vs. %v.", seed, decrypted.isAsymmetricEncryption(), symmetric)
- }
- if decrypted.isSymmetricEncryption() != symmetric {
- t.Fatalf("failed with seed %d: symmetric %v vs. %v.", seed, decrypted.isSymmetricEncryption(), symmetric)
- }
- if !symmetric {
- if decrypted.Dst == nil {
- t.Fatalf("failed with seed %d: dst is nil.", seed)
- }
- if !IsPubKeyEqual(decrypted.Dst, &key.PublicKey) {
- t.Fatalf("failed with seed %d: Dst.", seed)
- }
- }
-}
-
-func TestEncryptWithZeroKey(t *testing.T) {
- InitSingleTest()
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- params.KeySym = make([]byte, aesKeyLength)
- _, err = msg.Wrap(params)
- if err == nil {
- t.Fatalf("wrapped with zero key, seed: %d.", seed)
- }
-
- params, err = generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- msg, err = NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- params.KeySym = make([]byte, 0)
- _, err = msg.Wrap(params)
- if err == nil {
- t.Fatalf("wrapped with empty key, seed: %d.", seed)
- }
-
- params, err = generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- msg, err = NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- params.KeySym = nil
- _, err = msg.Wrap(params)
- if err == nil {
- t.Fatalf("wrapped with nil key, seed: %d.", seed)
- }
-}
-
-func TestRlpEncode(t *testing.T) {
- InitSingleTest()
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("wrapped with zero key, seed: %d.", seed)
- }
-
- raw, err := rlp.EncodeToBytes(env)
- if err != nil {
- t.Fatalf("RLP encode failed: %s.", err)
- }
-
- var decoded Envelope
- rlp.DecodeBytes(raw, &decoded)
- if err != nil {
- t.Fatalf("RLP decode failed: %s.", err)
- }
-
- he := env.Hash()
- hd := decoded.Hash()
-
- if he != hd {
- t.Fatalf("Hashes are not equal: %x vs. %x", he, hd)
- }
-}
-
-func singlePaddingTest(t *testing.T, padSize int) {
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d and sz=%d: %s.", seed, padSize, err)
- }
- params.Padding = make([]byte, padSize)
- params.PoW = 0.0000000001
- pad := make([]byte, padSize)
- _, err = mrand.Read(pad)
- if err != nil {
- t.Fatalf("padding is not generated (seed %d): %s", seed, err)
- }
- n := copy(params.Padding, pad)
- if n != padSize {
- t.Fatalf("padding is not copied (seed %d): %s", seed, err)
- }
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed to wrap, seed: %d and sz=%d.", seed, padSize)
- }
- f := Filter{KeySym: params.KeySym}
- decrypted := env.Open(&f)
- if decrypted == nil {
- t.Fatalf("failed to open, seed and sz=%d: %d.", seed, padSize)
- }
- if !bytes.Equal(pad, decrypted.Padding) {
- t.Fatalf("padding is not retireved as expected with seed %d and sz=%d:\n[%x]\n[%x].", seed, padSize, pad, decrypted.Padding)
- }
-}
-
-func TestPadding(t *testing.T) {
- InitSingleTest()
-
- for i := 1; i < 260; i++ {
- singlePaddingTest(t, i)
- }
-
- lim := 256 * 256
- for i := lim - 5; i < lim+2; i++ {
- singlePaddingTest(t, i)
- }
-
- for i := 0; i < 256; i++ {
- n := mrand.Intn(256*254) + 256
- singlePaddingTest(t, n)
- }
-
- for i := 0; i < 256; i++ {
- n := mrand.Intn(256*1024) + 256*256
- singlePaddingTest(t, n)
- }
-}
diff --git a/whisper/whisperv6/peer.go b/whisper/whisperv6/peer.go
deleted file mode 100644
index ac7b3b12b659..000000000000
--- a/whisper/whisperv6/peer.go
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv6
-
-import (
- "fmt"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/rlp"
- set "gopkg.in/fatih/set.v0"
-)
-
-// peer represents a whisper protocol peer connection.
-type Peer struct {
- host *Whisper
- peer *p2p.Peer
- ws p2p.MsgReadWriter
- trusted bool
-
- known *set.Set // Messages already known by the peer to avoid wasting bandwidth
-
- quit chan struct{}
-}
-
-// newPeer creates a new whisper peer object, but does not run the handshake itself.
-func newPeer(host *Whisper, remote *p2p.Peer, rw p2p.MsgReadWriter) *Peer {
- return &Peer{
- host: host,
- peer: remote,
- ws: rw,
- trusted: false,
- known: set.New(),
- quit: make(chan struct{}),
- }
-}
-
-// start initiates the peer updater, periodically broadcasting the whisper packets
-// into the network.
-func (p *Peer) start() {
- go p.update()
- log.Trace("start", "peer", p.ID())
-}
-
-// stop terminates the peer updater, stopping message forwarding to it.
-func (p *Peer) stop() {
- close(p.quit)
- log.Trace("stop", "peer", p.ID())
-}
-
-// handshake sends the protocol initiation status message to the remote peer and
-// verifies the remote status too.
-func (p *Peer) handshake() error {
- // Send the handshake status message asynchronously
- errc := make(chan error, 1)
- go func() {
- errc <- p2p.Send(p.ws, statusCode, ProtocolVersion)
- }()
- // Fetch the remote status packet and verify protocol match
- packet, err := p.ws.ReadMsg()
- if err != nil {
- return err
- }
- if packet.Code != statusCode {
- return fmt.Errorf("peer [%x] sent packet %x before status packet", p.ID(), packet.Code)
- }
- s := rlp.NewStream(packet.Payload, uint64(packet.Size))
- peerVersion, err := s.Uint()
- if err != nil {
- return fmt.Errorf("peer [%x] sent bad status message: %v", p.ID(), err)
- }
- if peerVersion != ProtocolVersion {
- return fmt.Errorf("peer [%x]: protocol version mismatch %d != %d", p.ID(), peerVersion, ProtocolVersion)
- }
- // Wait until out own status is consumed too
- if err := <-errc; err != nil {
- return fmt.Errorf("peer [%x] failed to send status packet: %v", p.ID(), err)
- }
- return nil
-}
-
-// update executes periodic operations on the peer, including message transmission
-// and expiration.
-func (p *Peer) update() {
- // Start the tickers for the updates
- expire := time.NewTicker(expirationCycle)
- transmit := time.NewTicker(transmissionCycle)
-
- // Loop and transmit until termination is requested
- for {
- select {
- case <-expire.C:
- p.expire()
-
- case <-transmit.C:
- if err := p.broadcast(); err != nil {
- log.Trace("broadcast failed", "reason", err, "peer", p.ID())
- return
- }
-
- case <-p.quit:
- return
- }
- }
-}
-
-// mark marks an envelope known to the peer so that it won't be sent back.
-func (peer *Peer) mark(envelope *Envelope) {
- peer.known.Add(envelope.Hash())
-}
-
-// marked checks if an envelope is already known to the remote peer.
-func (peer *Peer) marked(envelope *Envelope) bool {
- return peer.known.Has(envelope.Hash())
-}
-
-// expire iterates over all the known envelopes in the host and removes all
-// expired (unknown) ones from the known list.
-func (peer *Peer) expire() {
- unmark := make(map[common.Hash]struct{})
- peer.known.Each(func(v interface{}) bool {
- if !peer.host.isEnvelopeCached(v.(common.Hash)) {
- unmark[v.(common.Hash)] = struct{}{}
- }
- return true
- })
- // Dump all known but no longer cached
- for hash := range unmark {
- peer.known.Remove(hash)
- }
-}
-
-// broadcast iterates over the collection of envelopes and transmits yet unknown
-// ones over the network.
-func (p *Peer) broadcast() error {
- var cnt int
- envelopes := p.host.Envelopes()
- for _, envelope := range envelopes {
- if !p.marked(envelope) {
- err := p2p.Send(p.ws, messagesCode, envelope)
- if err != nil {
- return err
- } else {
- p.mark(envelope)
- cnt++
- }
- }
- }
- if cnt > 0 {
- log.Trace("broadcast", "num. messages", cnt)
- }
- return nil
-}
-
-func (p *Peer) ID() []byte {
- id := p.peer.ID()
- return id[:]
-}
diff --git a/whisper/whisperv6/peer_test.go b/whisper/whisperv6/peer_test.go
deleted file mode 100644
index 39a4ab198069..000000000000
--- a/whisper/whisperv6/peer_test.go
+++ /dev/null
@@ -1,306 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv6
-
-import (
- "bytes"
- "crypto/ecdsa"
- "fmt"
- "net"
- "sync"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/p2p/discover"
- "github.com/ethereum/go-ethereum/p2p/nat"
-)
-
-var keys []string = []string{
- "d49dcf37238dc8a7aac57dc61b9fee68f0a97f062968978b9fafa7d1033d03a9",
- "73fd6143c48e80ed3c56ea159fe7494a0b6b393a392227b422f4c3e8f1b54f98",
- "119dd32adb1daa7a4c7bf77f847fb28730785aa92947edf42fdd997b54de40dc",
- "deeda8709dea935bb772248a3144dea449ffcc13e8e5a1fd4ef20ce4e9c87837",
- "5bd208a079633befa349441bdfdc4d85ba9bd56081525008380a63ac38a407cf",
- "1d27fb4912002d58a2a42a50c97edb05c1b3dffc665dbaa42df1fe8d3d95c9b5",
- "15def52800c9d6b8ca6f3066b7767a76afc7b611786c1276165fbc61636afb68",
- "51be6ab4b2dc89f251ff2ace10f3c1cc65d6855f3e083f91f6ff8efdfd28b48c",
- "ef1ef7441bf3c6419b162f05da6037474664f198b58db7315a6f4de52414b4a0",
- "09bdf6985aabc696dc1fbeb5381aebd7a6421727343872eb2fadfc6d82486fd9",
- "15d811bf2e01f99a224cdc91d0cf76cea08e8c67905c16fee9725c9be71185c4",
- "2f83e45cf1baaea779789f755b7da72d8857aeebff19362dd9af31d3c9d14620",
- "73f04e34ac6532b19c2aae8f8e52f38df1ac8f5cd10369f92325b9b0494b0590",
- "1e2e07b69e5025537fb73770f483dc8d64f84ae3403775ef61cd36e3faf162c1",
- "8963d9bbb3911aac6d30388c786756b1c423c4fbbc95d1f96ddbddf39809e43a",
- "0422da85abc48249270b45d8de38a4cc3c02032ede1fcf0864a51092d58a2f1f",
- "8ae5c15b0e8c7cade201fdc149831aa9b11ff626a7ffd27188886cc108ad0fa8",
- "acd8f5a71d4aecfcb9ad00d32aa4bcf2a602939b6a9dd071bab443154184f805",
- "a285a922125a7481600782ad69debfbcdb0316c1e97c267aff29ef50001ec045",
- "28fd4eee78c6cd4bf78f39f8ab30c32c67c24a6223baa40e6f9c9a0e1de7cef5",
- "c5cca0c9e6f043b288c6f1aef448ab59132dab3e453671af5d0752961f013fc7",
- "46df99b051838cb6f8d1b73f232af516886bd8c4d0ee07af9a0a033c391380fd",
- "c6a06a53cbaadbb432884f36155c8f3244e244881b5ee3e92e974cfa166d793f",
- "783b90c75c63dc72e2f8d11b6f1b4de54d63825330ec76ee8db34f06b38ea211",
- "9450038f10ca2c097a8013e5121b36b422b95b04892232f930a29292d9935611",
- "e215e6246ed1cfdcf7310d4d8cdbe370f0d6a8371e4eb1089e2ae05c0e1bc10f",
- "487110939ed9d64ebbc1f300adeab358bc58875faf4ca64990fbd7fe03b78f2b",
- "824a70ea76ac81366da1d4f4ac39de851c8ac49dca456bb3f0a186ceefa269a5",
- "ba8f34fa40945560d1006a328fe70c42e35cc3d1017e72d26864cd0d1b150f15",
- "30a5dfcfd144997f428901ea88a43c8d176b19c79dde54cc58eea001aa3d246c",
- "de59f7183aca39aa245ce66a05245fecfc7e2c75884184b52b27734a4a58efa2",
- "92629e2ff5f0cb4f5f08fffe0f64492024d36f045b901efb271674b801095c5a",
- "7184c1701569e3a4c4d2ddce691edd983b81e42e09196d332e1ae2f1e062cff4",
-}
-
-const NumNodes = 16 // must not exceed the number of keys (32)
-
-type TestData struct {
- counter [NumNodes]int
- mutex sync.RWMutex
-}
-
-type TestNode struct {
- shh *Whisper
- id *ecdsa.PrivateKey
- server *p2p.Server
- filerId string
-}
-
-var result TestData
-var nodes [NumNodes]*TestNode
-var sharedKey []byte = []byte("some arbitrary data here")
-var sharedTopic TopicType = TopicType{0xF, 0x1, 0x2, 0}
-var expectedMessage []byte = []byte("per rectum ad astra")
-
-// This test does the following:
-// 1. creates a chain of whisper nodes,
-// 2. installs the filters with shared (predefined) parameters,
-// 3. each node sends a number of random (undecryptable) messages,
-// 4. first node sends one expected (decryptable) message,
-// 5. checks if each node have received and decrypted exactly one message.
-func TestSimulation(t *testing.T) {
- initialize(t)
-
- for i := 0; i < NumNodes; i++ {
- sendMsg(t, false, i)
- }
-
- sendMsg(t, true, 0)
- checkPropagation(t)
- stopServers()
-}
-
-func initialize(t *testing.T) {
- var err error
- ip := net.IPv4(127, 0, 0, 1)
- port0 := 30303
-
- for i := 0; i < NumNodes; i++ {
- var node TestNode
- node.shh = New(&DefaultConfig)
- node.shh.SetMinimumPoW(0.00000001)
- node.shh.Start(nil)
- topics := make([]TopicType, 0)
- topics = append(topics, sharedTopic)
- f := Filter{KeySym: sharedKey}
- f.Topics = [][]byte{topics[0][:]}
- node.filerId, err = node.shh.Subscribe(&f)
- if err != nil {
- t.Fatalf("failed to install the filter: %s.", err)
- }
- node.id, err = crypto.HexToECDSA(keys[i])
- if err != nil {
- t.Fatalf("failed convert the key: %s.", keys[i])
- }
- port := port0 + i
- addr := fmt.Sprintf(":%d", port) // e.g. ":30303"
- name := common.MakeName("whisper-go", "2.0")
- var peers []*discover.Node
- if i > 0 {
- peerNodeId := nodes[i-1].id
- peerPort := uint16(port - 1)
- peerNode := discover.PubkeyID(&peerNodeId.PublicKey)
- peer := discover.NewNode(peerNode, ip, peerPort, peerPort)
- peers = append(peers, peer)
- }
-
- node.server = &p2p.Server{
- Config: p2p.Config{
- PrivateKey: node.id,
- MaxPeers: NumNodes/2 + 1,
- Name: name,
- Protocols: node.shh.Protocols(),
- ListenAddr: addr,
- NAT: nat.Any(),
- BootstrapNodes: peers,
- StaticNodes: peers,
- TrustedNodes: peers,
- },
- }
-
- err = node.server.Start()
- if err != nil {
- t.Fatalf("failed to start server %d.", i)
- }
-
- nodes[i] = &node
- }
-}
-
-func stopServers() {
- for i := 0; i < NumNodes; i++ {
- n := nodes[i]
- if n != nil {
- n.shh.Unsubscribe(n.filerId)
- n.shh.Stop()
- n.server.Stop()
- }
- }
-}
-
-func checkPropagation(t *testing.T) {
- if t.Failed() {
- return
- }
-
- const cycle = 100
- const iterations = 100
-
- for j := 0; j < iterations; j++ {
- time.Sleep(cycle * time.Millisecond)
-
- for i := 0; i < NumNodes; i++ {
- f := nodes[i].shh.GetFilter(nodes[i].filerId)
- if f == nil {
- t.Fatalf("failed to get filterId %s from node %d.", nodes[i].filerId, i)
- }
-
- mail := f.Retrieve()
- if !validateMail(t, i, mail) {
- return
- }
-
- if isTestComplete() {
- return
- }
- }
- }
-
- t.Fatalf("Test was not complete: timeout %d seconds.", iterations*cycle/1000)
-}
-
-func validateMail(t *testing.T, index int, mail []*ReceivedMessage) bool {
- var cnt int
- for _, m := range mail {
- if bytes.Equal(m.Payload, expectedMessage) {
- cnt++
- }
- }
-
- if cnt == 0 {
- // no messages received yet: nothing is wrong
- return true
- }
- if cnt > 1 {
- t.Fatalf("node %d received %d.", index, cnt)
- return false
- }
-
- if cnt > 0 {
- result.mutex.Lock()
- defer result.mutex.Unlock()
- result.counter[index] += cnt
- if result.counter[index] > 1 {
- t.Fatalf("node %d accumulated %d.", index, result.counter[index])
- }
- }
- return true
-}
-
-func isTestComplete() bool {
- result.mutex.RLock()
- defer result.mutex.RUnlock()
-
- for i := 0; i < NumNodes; i++ {
- if result.counter[i] < 1 {
- return false
- }
- }
-
- for i := 0; i < NumNodes; i++ {
- envelopes := nodes[i].shh.Envelopes()
- if len(envelopes) < 2 {
- return false
- }
- }
-
- return true
-}
-
-func sendMsg(t *testing.T, expected bool, id int) {
- if t.Failed() {
- return
- }
-
- opt := MessageParams{KeySym: sharedKey, Topic: sharedTopic, Payload: expectedMessage, PoW: 0.00000001, WorkTime: 1}
- if !expected {
- opt.KeySym[0]++
- opt.Topic[0]++
- opt.Payload = opt.Payload[1:]
- }
-
- msg, err := NewSentMessage(&opt)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- envelope, err := msg.Wrap(&opt)
- if err != nil {
- t.Fatalf("failed to seal message: %s", err)
- }
-
- err = nodes[id].shh.Send(envelope)
- if err != nil {
- t.Fatalf("failed to send message: %s", err)
- }
-}
-
-func TestPeerBasic(t *testing.T) {
- InitSingleTest()
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d.", seed)
- }
-
- params.PoW = 0.001
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d.", seed)
- }
-
- p := newPeer(nil, nil, nil)
- p.mark(env)
- if !p.marked(env) {
- t.Fatalf("failed mark with seed %d.", seed)
- }
-}
diff --git a/whisper/whisperv6/topic.go b/whisper/whisperv6/topic.go
deleted file mode 100644
index bf5da01e345d..000000000000
--- a/whisper/whisperv6/topic.go
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-// Contains the Whisper protocol Topic element.
-
-package whisperv6
-
-import (
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/common/hexutil"
-)
-
-// Topic represents a cryptographically secure, probabilistic partial
-// classifications of a message, determined as the first (left) 4 bytes of the
-// SHA3 hash of some arbitrary data given by the original author of the message.
-type TopicType [TopicLength]byte
-
-func BytesToTopic(b []byte) (t TopicType) {
- sz := TopicLength
- if x := len(b); x < TopicLength {
- sz = x
- }
- for i := 0; i < sz; i++ {
- t[i] = b[i]
- }
- return t
-}
-
-// String converts a topic byte array to a string representation.
-func (t *TopicType) String() string {
- return common.ToHex(t[:])
-}
-
-// MarshalText returns the hex representation of t.
-func (t TopicType) MarshalText() ([]byte, error) {
- return hexutil.Bytes(t[:]).MarshalText()
-}
-
-// UnmarshalText parses a hex representation to a topic.
-func (t *TopicType) UnmarshalText(input []byte) error {
- return hexutil.UnmarshalFixedText("Topic", input, t[:])
-}
diff --git a/whisper/whisperv6/topic_test.go b/whisper/whisperv6/topic_test.go
deleted file mode 100644
index 454afe0de17d..000000000000
--- a/whisper/whisperv6/topic_test.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv6
-
-import (
- "encoding/json"
- "testing"
-)
-
-var topicStringTests = []struct {
- topic TopicType
- str string
-}{
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, str: "0x00000000"},
- {topic: TopicType{0x00, 0x7f, 0x80, 0xff}, str: "0x007f80ff"},
- {topic: TopicType{0xff, 0x80, 0x7f, 0x00}, str: "0xff807f00"},
- {topic: TopicType{0xf2, 0x6e, 0x77, 0x79}, str: "0xf26e7779"},
-}
-
-func TestTopicString(t *testing.T) {
- for i, tst := range topicStringTests {
- s := tst.topic.String()
- if s != tst.str {
- t.Fatalf("failed test %d: have %s, want %s.", i, s, tst.str)
- }
- }
-}
-
-var bytesToTopicTests = []struct {
- data []byte
- topic TopicType
-}{
- {topic: TopicType{0x8f, 0x9a, 0x2b, 0x7d}, data: []byte{0x8f, 0x9a, 0x2b, 0x7d}},
- {topic: TopicType{0x00, 0x7f, 0x80, 0xff}, data: []byte{0x00, 0x7f, 0x80, 0xff}},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte{0x00, 0x00, 0x00, 0x00}},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte{0x00, 0x00, 0x00}},
- {topic: TopicType{0x01, 0x00, 0x00, 0x00}, data: []byte{0x01}},
- {topic: TopicType{0x00, 0xfe, 0x00, 0x00}, data: []byte{0x00, 0xfe}},
- {topic: TopicType{0xea, 0x1d, 0x43, 0x00}, data: []byte{0xea, 0x1d, 0x43}},
- {topic: TopicType{0x6f, 0x3c, 0xb0, 0xdd}, data: []byte{0x6f, 0x3c, 0xb0, 0xdd, 0x0f, 0x00, 0x90}},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte{}},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: nil},
-}
-
-var unmarshalTestsGood = []struct {
- topic TopicType
- data []byte
-}{
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"0x00000000"`)},
- {topic: TopicType{0x00, 0x7f, 0x80, 0xff}, data: []byte(`"0x007f80ff"`)},
- {topic: TopicType{0xff, 0x80, 0x7f, 0x00}, data: []byte(`"0xff807f00"`)},
- {topic: TopicType{0xf2, 0x6e, 0x77, 0x79}, data: []byte(`"0xf26e7779"`)},
-}
-
-var unmarshalTestsBad = []struct {
- topic TopicType
- data []byte
-}{
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"0x000000"`)},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"0x0000000"`)},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"0x000000000"`)},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"0x0000000000"`)},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"000000"`)},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"0000000"`)},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"000000000"`)},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"0000000000"`)},
- {topic: TopicType{0x00, 0x00, 0x00, 0x00}, data: []byte(`"abcdefg0"`)},
-}
-
-var unmarshalTestsUgly = []struct {
- topic TopicType
- data []byte
-}{
- {topic: TopicType{0x01, 0x00, 0x00, 0x00}, data: []byte(`"0x00000001"`)},
-}
-
-func TestBytesToTopic(t *testing.T) {
- for i, tst := range bytesToTopicTests {
- top := BytesToTopic(tst.data)
- if top != tst.topic {
- t.Fatalf("failed test %d: have %v, want %v.", i, t, tst.topic)
- }
- }
-}
-
-func TestUnmarshalTestsGood(t *testing.T) {
- for i, tst := range unmarshalTestsGood {
- var top TopicType
- err := json.Unmarshal(tst.data, &top)
- if err != nil {
- t.Errorf("failed test %d. input: %v. err: %v", i, tst.data, err)
- } else if top != tst.topic {
- t.Errorf("failed test %d: have %v, want %v.", i, t, tst.topic)
- }
- }
-}
-
-func TestUnmarshalTestsBad(t *testing.T) {
- // in this test UnmarshalJSON() is supposed to fail
- for i, tst := range unmarshalTestsBad {
- var top TopicType
- err := json.Unmarshal(tst.data, &top)
- if err == nil {
- t.Fatalf("failed test %d. input: %v.", i, tst.data)
- }
- }
-}
-
-func TestUnmarshalTestsUgly(t *testing.T) {
- // in this test UnmarshalJSON() is NOT supposed to fail, but result should be wrong
- for i, tst := range unmarshalTestsUgly {
- var top TopicType
- err := json.Unmarshal(tst.data, &top)
- if err != nil {
- t.Errorf("failed test %d. input: %v.", i, tst.data)
- } else if top == tst.topic {
- t.Errorf("failed test %d: have %v, want %v.", i, top, tst.topic)
- }
- }
-}
diff --git a/whisper/whisperv6/whisper.go b/whisper/whisperv6/whisper.go
deleted file mode 100644
index e2b884f3d4ac..000000000000
--- a/whisper/whisperv6/whisper.go
+++ /dev/null
@@ -1,858 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv6
-
-import (
- "bytes"
- "crypto/ecdsa"
- crand "crypto/rand"
- "crypto/sha256"
- "fmt"
- "runtime"
- "sync"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/log"
- "github.com/ethereum/go-ethereum/p2p"
- "github.com/ethereum/go-ethereum/rpc"
- "github.com/syndtr/goleveldb/leveldb/errors"
- "golang.org/x/crypto/pbkdf2"
- "golang.org/x/sync/syncmap"
- set "gopkg.in/fatih/set.v0"
-)
-
-type Statistics struct {
- messagesCleared int
- memoryCleared int
- memoryUsed int
- cycles int
- totalMessagesCleared int
-}
-
-const (
- minPowIdx = iota // Minimal PoW required by the whisper node
- maxMsgSizeIdx = iota // Maximal message length allowed by the whisper node
- overflowIdx = iota // Indicator of message queue overflow
-)
-
-// Whisper represents a dark communication interface through the Ethereum
-// network, using its very own P2P communication layer.
-type Whisper struct {
- protocol p2p.Protocol // Protocol description and parameters
- filters *Filters // Message filters installed with Subscribe function
-
- privateKeys map[string]*ecdsa.PrivateKey // Private key storage
- symKeys map[string][]byte // Symmetric key storage
- keyMu sync.RWMutex // Mutex associated with key storages
-
- poolMu sync.RWMutex // Mutex to sync the message and expiration pools
- envelopes map[common.Hash]*Envelope // Pool of envelopes currently tracked by this node
- expirations map[uint32]*set.SetNonTS // Message expiration pool
-
- peerMu sync.RWMutex // Mutex to sync the active peer set
- peers map[*Peer]struct{} // Set of currently active peers
-
- messageQueue chan *Envelope // Message queue for normal whisper messages
- p2pMsgQueue chan *Envelope // Message queue for peer-to-peer messages (not to be forwarded any further)
- quit chan struct{} // Channel used for graceful exit
-
- settings syncmap.Map // holds configuration settings that can be dynamically changed
-
- statsMu sync.Mutex // guard stats
- stats Statistics // Statistics of whisper node
-
- mailServer MailServer // MailServer interface
-}
-
-// New creates a Whisper client ready to communicate through the Ethereum P2P network.
-func New(cfg *Config) *Whisper {
- if cfg == nil {
- cfg = &DefaultConfig
- }
-
- whisper := &Whisper{
- privateKeys: make(map[string]*ecdsa.PrivateKey),
- symKeys: make(map[string][]byte),
- envelopes: make(map[common.Hash]*Envelope),
- expirations: make(map[uint32]*set.SetNonTS),
- peers: make(map[*Peer]struct{}),
- messageQueue: make(chan *Envelope, messageQueueLimit),
- p2pMsgQueue: make(chan *Envelope, messageQueueLimit),
- quit: make(chan struct{}),
- }
-
- whisper.filters = NewFilters(whisper)
-
- whisper.settings.Store(minPowIdx, cfg.MinimumAcceptedPOW)
- whisper.settings.Store(maxMsgSizeIdx, cfg.MaxMessageSize)
- whisper.settings.Store(overflowIdx, false)
-
- // p2p whisper sub protocol handler
- whisper.protocol = p2p.Protocol{
- Name: ProtocolName,
- Version: uint(ProtocolVersion),
- Length: NumberOfMessageCodes,
- Run: whisper.HandlePeer,
- NodeInfo: func() interface{} {
- return map[string]interface{}{
- "version": ProtocolVersionStr,
- "maxMessageSize": whisper.MaxMessageSize(),
- "minimumPoW": whisper.MinPow(),
- }
- },
- }
-
- return whisper
-}
-
-func (w *Whisper) MinPow() float64 {
- val, _ := w.settings.Load(minPowIdx)
- return val.(float64)
-}
-
-// MaxMessageSize returns the maximum accepted message size.
-func (w *Whisper) MaxMessageSize() uint32 {
- val, _ := w.settings.Load(maxMsgSizeIdx)
- return val.(uint32)
-}
-
-// Overflow returns an indication if the message queue is full.
-func (w *Whisper) Overflow() bool {
- val, _ := w.settings.Load(overflowIdx)
- return val.(bool)
-}
-
-// APIs returns the RPC descriptors the Whisper implementation offers
-func (w *Whisper) APIs() []rpc.API {
- return []rpc.API{
- {
- Namespace: ProtocolName,
- Version: ProtocolVersionStr,
- Service: NewPublicWhisperAPI(w),
- Public: true,
- },
- }
-}
-
-// RegisterServer registers MailServer interface.
-// MailServer will process all the incoming messages with p2pRequestCode.
-func (w *Whisper) RegisterServer(server MailServer) {
- w.mailServer = server
-}
-
-// Protocols returns the whisper sub-protocols ran by this particular client.
-func (w *Whisper) Protocols() []p2p.Protocol {
- return []p2p.Protocol{w.protocol}
-}
-
-// Version returns the whisper sub-protocols version number.
-func (w *Whisper) Version() uint {
- return w.protocol.Version
-}
-
-// SetMaxMessageSize sets the maximal message size allowed by this node
-func (w *Whisper) SetMaxMessageSize(size uint32) error {
- if size > MaxMessageSize {
- return fmt.Errorf("message size too large [%d>%d]", size, MaxMessageSize)
- }
- w.settings.Store(maxMsgSizeIdx, size)
- return nil
-}
-
-// SetMinimumPoW sets the minimal PoW required by this node
-func (w *Whisper) SetMinimumPoW(val float64) error {
- if val <= 0.0 {
- return fmt.Errorf("invalid PoW: %f", val)
- }
- w.settings.Store(minPowIdx, val)
- return nil
-}
-
-// getPeer retrieves peer by ID
-func (w *Whisper) getPeer(peerID []byte) (*Peer, error) {
- w.peerMu.Lock()
- defer w.peerMu.Unlock()
- for p := range w.peers {
- id := p.peer.ID()
- if bytes.Equal(peerID, id[:]) {
- return p, nil
- }
- }
- return nil, fmt.Errorf("Could not find peer with ID: %x", peerID)
-}
-
-// AllowP2PMessagesFromPeer marks specific peer trusted,
-// which will allow it to send historic (expired) messages.
-func (w *Whisper) AllowP2PMessagesFromPeer(peerID []byte) error {
- p, err := w.getPeer(peerID)
- if err != nil {
- return err
- }
- p.trusted = true
- return nil
-}
-
-// RequestHistoricMessages sends a message with p2pRequestCode to a specific peer,
-// which is known to implement MailServer interface, and is supposed to process this
-// request and respond with a number of peer-to-peer messages (possibly expired),
-// which are not supposed to be forwarded any further.
-// The whisper protocol is agnostic of the format and contents of envelope.
-func (w *Whisper) RequestHistoricMessages(peerID []byte, envelope *Envelope) error {
- p, err := w.getPeer(peerID)
- if err != nil {
- return err
- }
- p.trusted = true
- return p2p.Send(p.ws, p2pRequestCode, envelope)
-}
-
-// SendP2PMessage sends a peer-to-peer message to a specific peer.
-func (w *Whisper) SendP2PMessage(peerID []byte, envelope *Envelope) error {
- p, err := w.getPeer(peerID)
- if err != nil {
- return err
- }
- return w.SendP2PDirect(p, envelope)
-}
-
-// SendP2PDirect sends a peer-to-peer message to a specific peer.
-func (w *Whisper) SendP2PDirect(peer *Peer, envelope *Envelope) error {
- return p2p.Send(peer.ws, p2pCode, envelope)
-}
-
-// NewKeyPair generates a new cryptographic identity for the client, and injects
-// it into the known identities for message decryption. Returns ID of the new key pair.
-func (w *Whisper) NewKeyPair() (string, error) {
- key, err := crypto.GenerateKey()
- if err != nil || !validatePrivateKey(key) {
- key, err = crypto.GenerateKey() // retry once
- }
- if err != nil {
- return "", err
- }
- if !validatePrivateKey(key) {
- return "", fmt.Errorf("failed to generate valid key")
- }
-
- id, err := GenerateRandomID()
- if err != nil {
- return "", fmt.Errorf("failed to generate ID: %s", err)
- }
-
- w.keyMu.Lock()
- defer w.keyMu.Unlock()
-
- if w.privateKeys[id] != nil {
- return "", fmt.Errorf("failed to generate unique ID")
- }
- w.privateKeys[id] = key
- return id, nil
-}
-
-// DeleteKeyPair deletes the specified key if it exists.
-func (w *Whisper) DeleteKeyPair(key string) bool {
- w.keyMu.Lock()
- defer w.keyMu.Unlock()
-
- if w.privateKeys[key] != nil {
- delete(w.privateKeys, key)
- return true
- }
- return false
-}
-
-// AddKeyPair imports a asymmetric private key and returns it identifier.
-func (w *Whisper) AddKeyPair(key *ecdsa.PrivateKey) (string, error) {
- id, err := GenerateRandomID()
- if err != nil {
- return "", fmt.Errorf("failed to generate ID: %s", err)
- }
-
- w.keyMu.Lock()
- w.privateKeys[id] = key
- w.keyMu.Unlock()
-
- return id, nil
-}
-
-// HasKeyPair checks if the the whisper node is configured with the private key
-// of the specified public pair.
-func (w *Whisper) HasKeyPair(id string) bool {
- w.keyMu.RLock()
- defer w.keyMu.RUnlock()
- return w.privateKeys[id] != nil
-}
-
-// GetPrivateKey retrieves the private key of the specified identity.
-func (w *Whisper) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) {
- w.keyMu.RLock()
- defer w.keyMu.RUnlock()
- key := w.privateKeys[id]
- if key == nil {
- return nil, fmt.Errorf("invalid id")
- }
- return key, nil
-}
-
-// GenerateSymKey generates a random symmetric key and stores it under id,
-// which is then returned. Will be used in the future for session key exchange.
-func (w *Whisper) GenerateSymKey() (string, error) {
- key := make([]byte, aesKeyLength)
- _, err := crand.Read(key)
- if err != nil {
- return "", err
- } else if !validateSymmetricKey(key) {
- return "", fmt.Errorf("error in GenerateSymKey: crypto/rand failed to generate random data")
- }
-
- id, err := GenerateRandomID()
- if err != nil {
- return "", fmt.Errorf("failed to generate ID: %s", err)
- }
-
- w.keyMu.Lock()
- defer w.keyMu.Unlock()
-
- if w.symKeys[id] != nil {
- return "", fmt.Errorf("failed to generate unique ID")
- }
- w.symKeys[id] = key
- return id, nil
-}
-
-// AddSymKeyDirect stores the key, and returns its id.
-func (w *Whisper) AddSymKeyDirect(key []byte) (string, error) {
- if len(key) != aesKeyLength {
- return "", fmt.Errorf("wrong key size: %d", len(key))
- }
-
- id, err := GenerateRandomID()
- if err != nil {
- return "", fmt.Errorf("failed to generate ID: %s", err)
- }
-
- w.keyMu.Lock()
- defer w.keyMu.Unlock()
-
- if w.symKeys[id] != nil {
- return "", fmt.Errorf("failed to generate unique ID")
- }
- w.symKeys[id] = key
- return id, nil
-}
-
-// AddSymKeyFromPassword generates the key from password, stores it, and returns its id.
-func (w *Whisper) AddSymKeyFromPassword(password string) (string, error) {
- id, err := GenerateRandomID()
- if err != nil {
- return "", fmt.Errorf("failed to generate ID: %s", err)
- }
- if w.HasSymKey(id) {
- return "", fmt.Errorf("failed to generate unique ID")
- }
-
- derived, err := deriveKeyMaterial([]byte(password), EnvelopeVersion)
- if err != nil {
- return "", err
- }
-
- w.keyMu.Lock()
- defer w.keyMu.Unlock()
-
- // double check is necessary, because deriveKeyMaterial() is very slow
- if w.symKeys[id] != nil {
- return "", fmt.Errorf("critical error: failed to generate unique ID")
- }
- w.symKeys[id] = derived
- return id, nil
-}
-
-// HasSymKey returns true if there is a key associated with the given id.
-// Otherwise returns false.
-func (w *Whisper) HasSymKey(id string) bool {
- w.keyMu.RLock()
- defer w.keyMu.RUnlock()
- return w.symKeys[id] != nil
-}
-
-// DeleteSymKey deletes the key associated with the name string if it exists.
-func (w *Whisper) DeleteSymKey(id string) bool {
- w.keyMu.Lock()
- defer w.keyMu.Unlock()
- if w.symKeys[id] != nil {
- delete(w.symKeys, id)
- return true
- }
- return false
-}
-
-// GetSymKey returns the symmetric key associated with the given id.
-func (w *Whisper) GetSymKey(id string) ([]byte, error) {
- w.keyMu.RLock()
- defer w.keyMu.RUnlock()
- if w.symKeys[id] != nil {
- return w.symKeys[id], nil
- }
- return nil, fmt.Errorf("non-existent key ID")
-}
-
-// Subscribe installs a new message handler used for filtering, decrypting
-// and subsequent storing of incoming messages.
-func (w *Whisper) Subscribe(f *Filter) (string, error) {
- return w.filters.Install(f)
-}
-
-// GetFilter returns the filter by id.
-func (w *Whisper) GetFilter(id string) *Filter {
- return w.filters.Get(id)
-}
-
-// Unsubscribe removes an installed message handler.
-func (w *Whisper) Unsubscribe(id string) error {
- ok := w.filters.Uninstall(id)
- if !ok {
- return fmt.Errorf("Unsubscribe: Invalid ID")
- }
- return nil
-}
-
-// Send injects a message into the whisper send queue, to be distributed in the
-// network in the coming cycles.
-func (w *Whisper) Send(envelope *Envelope) error {
- ok, err := w.add(envelope)
- if err != nil {
- return err
- }
- if !ok {
- return fmt.Errorf("failed to add envelope")
- }
- return err
-}
-
-// Start implements node.Service, starting the background data propagation thread
-// of the Whisper protocol.
-func (w *Whisper) Start(*p2p.Server) error {
- log.Info("started whisper v." + ProtocolVersionStr)
- go w.update()
-
- numCPU := runtime.NumCPU()
- for i := 0; i < numCPU; i++ {
- go w.processQueue()
- }
-
- return nil
-}
-
-// Stop implements node.Service, stopping the background data propagation thread
-// of the Whisper protocol.
-func (w *Whisper) Stop() error {
- close(w.quit)
- log.Info("whisper stopped")
- return nil
-}
-
-// HandlePeer is called by the underlying P2P layer when the whisper sub-protocol
-// connection is negotiated.
-func (wh *Whisper) HandlePeer(peer *p2p.Peer, rw p2p.MsgReadWriter) error {
- // Create the new peer and start tracking it
- whisperPeer := newPeer(wh, peer, rw)
-
- wh.peerMu.Lock()
- wh.peers[whisperPeer] = struct{}{}
- wh.peerMu.Unlock()
-
- defer func() {
- wh.peerMu.Lock()
- delete(wh.peers, whisperPeer)
- wh.peerMu.Unlock()
- }()
-
- // Run the peer handshake and state updates
- if err := whisperPeer.handshake(); err != nil {
- return err
- }
- whisperPeer.start()
- defer whisperPeer.stop()
-
- return wh.runMessageLoop(whisperPeer, rw)
-}
-
-// runMessageLoop reads and processes inbound messages directly to merge into client-global state.
-func (wh *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error {
- for {
- // fetch the next packet
- packet, err := rw.ReadMsg()
- if err != nil {
- log.Warn("message loop", "peer", p.peer.ID(), "err", err)
- return err
- }
- if packet.Size > wh.MaxMessageSize() {
- log.Warn("oversized message received", "peer", p.peer.ID())
- return errors.New("oversized message received")
- }
-
- switch packet.Code {
- case statusCode:
- // this should not happen, but no need to panic; just ignore this message.
- log.Warn("unxepected status message received", "peer", p.peer.ID())
- case messagesCode:
- // decode the contained envelopes
- var envelope Envelope
- if err := packet.Decode(&envelope); err != nil {
- log.Warn("failed to decode envelope, peer will be disconnected", "peer", p.peer.ID(), "err", err)
- return errors.New("invalid envelope")
- }
- cached, err := wh.add(&envelope)
- if err != nil {
- log.Warn("bad envelope received, peer will be disconnected", "peer", p.peer.ID(), "err", err)
- return errors.New("invalid envelope")
- }
- if cached {
- p.mark(&envelope)
- }
- case p2pCode:
- // peer-to-peer message, sent directly to peer bypassing PoW checks, etc.
- // this message is not supposed to be forwarded to other peers, and
- // therefore might not satisfy the PoW, expiry and other requirements.
- // these messages are only accepted from the trusted peer.
- if p.trusted {
- var envelope Envelope
- if err := packet.Decode(&envelope); err != nil {
- log.Warn("failed to decode direct message, peer will be disconnected", "peer", p.peer.ID(), "err", err)
- return errors.New("invalid direct message")
- }
- wh.postEvent(&envelope, true)
- }
- case p2pRequestCode:
- // Must be processed if mail server is implemented. Otherwise ignore.
- if wh.mailServer != nil {
- var request Envelope
- if err := packet.Decode(&request); err != nil {
- log.Warn("failed to decode p2p request message, peer will be disconnected", "peer", p.peer.ID(), "err", err)
- return errors.New("invalid p2p request")
- }
- wh.mailServer.DeliverMail(p, &request)
- }
- default:
- // New message types might be implemented in the future versions of Whisper.
- // For forward compatibility, just ignore.
- }
-
- packet.Discard()
- }
-}
-
-// add inserts a new envelope into the message pool to be distributed within the
-// whisper network. It also inserts the envelope into the expiration pool at the
-// appropriate time-stamp. In case of error, connection should be dropped.
-func (wh *Whisper) add(envelope *Envelope) (bool, error) {
- now := uint32(time.Now().Unix())
- sent := envelope.Expiry - envelope.TTL
-
- if sent > now {
- if sent-SynchAllowance > now {
- return false, fmt.Errorf("envelope created in the future [%x]", envelope.Hash())
- } else {
- // recalculate PoW, adjusted for the time difference, plus one second for latency
- envelope.calculatePoW(sent - now + 1)
- }
- }
-
- if envelope.Expiry < now {
- if envelope.Expiry+SynchAllowance*2 < now {
- return false, fmt.Errorf("very old message")
- } else {
- log.Debug("expired envelope dropped", "hash", envelope.Hash().Hex())
- return false, nil // drop envelope without error
- }
- }
-
- if uint32(envelope.size()) > wh.MaxMessageSize() {
- return false, fmt.Errorf("huge messages are not allowed [%x]", envelope.Hash())
- }
-
- if len(envelope.Version) > 4 {
- return false, fmt.Errorf("oversized version [%x]", envelope.Hash())
- }
-
- aesNonceSize := len(envelope.AESNonce)
- if aesNonceSize != 0 && aesNonceSize != AESNonceLength {
- // the standard AES GCM nonce size is 12 bytes,
- // but constant gcmStandardNonceSize cannot be accessed (not exported)
- return false, fmt.Errorf("wrong size of AESNonce: %d bytes [env: %x]", aesNonceSize, envelope.Hash())
- }
-
- if envelope.PoW() < wh.MinPow() {
- log.Debug("envelope with low PoW dropped", "PoW", envelope.PoW(), "hash", envelope.Hash().Hex())
- return false, nil // drop envelope without error
- }
-
- hash := envelope.Hash()
-
- wh.poolMu.Lock()
- _, alreadyCached := wh.envelopes[hash]
- if !alreadyCached {
- wh.envelopes[hash] = envelope
- if wh.expirations[envelope.Expiry] == nil {
- wh.expirations[envelope.Expiry] = set.NewNonTS()
- }
- if !wh.expirations[envelope.Expiry].Has(hash) {
- wh.expirations[envelope.Expiry].Add(hash)
- }
- }
- wh.poolMu.Unlock()
-
- if alreadyCached {
- log.Trace("whisper envelope already cached", "hash", envelope.Hash().Hex())
- } else {
- log.Trace("cached whisper envelope", "hash", envelope.Hash().Hex())
- wh.statsMu.Lock()
- wh.stats.memoryUsed += envelope.size()
- wh.statsMu.Unlock()
- wh.postEvent(envelope, false) // notify the local node about the new message
- if wh.mailServer != nil {
- wh.mailServer.Archive(envelope)
- }
- }
- return true, nil
-}
-
-// postEvent queues the message for further processing.
-func (w *Whisper) postEvent(envelope *Envelope, isP2P bool) {
- // if the version of incoming message is higher than
- // currently supported version, we can not decrypt it,
- // and therefore just ignore this message
- if envelope.Ver() <= EnvelopeVersion {
- if isP2P {
- w.p2pMsgQueue <- envelope
- } else {
- w.checkOverflow()
- w.messageQueue <- envelope
- }
- }
-}
-
-// checkOverflow checks if message queue overflow occurs and reports it if necessary.
-func (w *Whisper) checkOverflow() {
- queueSize := len(w.messageQueue)
-
- if queueSize == messageQueueLimit {
- if !w.Overflow() {
- w.settings.Store(overflowIdx, true)
- log.Warn("message queue overflow")
- }
- } else if queueSize <= messageQueueLimit/2 {
- if w.Overflow() {
- w.settings.Store(overflowIdx, false)
- log.Warn("message queue overflow fixed (back to normal)")
- }
- }
-}
-
-// processQueue delivers the messages to the watchers during the lifetime of the whisper node.
-func (w *Whisper) processQueue() {
- var e *Envelope
- for {
- select {
- case <-w.quit:
- return
-
- case e = <-w.messageQueue:
- w.filters.NotifyWatchers(e, false)
-
- case e = <-w.p2pMsgQueue:
- w.filters.NotifyWatchers(e, true)
- }
- }
-}
-
-// update loops until the lifetime of the whisper node, updating its internal
-// state by expiring stale messages from the pool.
-func (w *Whisper) update() {
- // Start a ticker to check for expirations
- expire := time.NewTicker(expirationCycle)
-
- // Repeat updates until termination is requested
- for {
- select {
- case <-expire.C:
- w.expire()
-
- case <-w.quit:
- return
- }
- }
-}
-
-// expire iterates over all the expiration timestamps, removing all stale
-// messages from the pools.
-func (w *Whisper) expire() {
- w.poolMu.Lock()
- defer w.poolMu.Unlock()
-
- w.statsMu.Lock()
- defer w.statsMu.Unlock()
- w.stats.reset()
- now := uint32(time.Now().Unix())
- for expiry, hashSet := range w.expirations {
- if expiry < now {
- // Dump all expired messages and remove timestamp
- hashSet.Each(func(v interface{}) bool {
- sz := w.envelopes[v.(common.Hash)].size()
- delete(w.envelopes, v.(common.Hash))
- w.stats.messagesCleared++
- w.stats.memoryCleared += sz
- w.stats.memoryUsed -= sz
- return true
- })
- w.expirations[expiry].Clear()
- delete(w.expirations, expiry)
- }
- }
-}
-
-// Stats returns the whisper node statistics.
-func (w *Whisper) Stats() Statistics {
- w.statsMu.Lock()
- defer w.statsMu.Unlock()
-
- return w.stats
-}
-
-// Envelopes retrieves all the messages currently pooled by the node.
-func (w *Whisper) Envelopes() []*Envelope {
- w.poolMu.RLock()
- defer w.poolMu.RUnlock()
-
- all := make([]*Envelope, 0, len(w.envelopes))
- for _, envelope := range w.envelopes {
- all = append(all, envelope)
- }
- return all
-}
-
-// Messages iterates through all currently floating envelopes
-// and retrieves all the messages, that this filter could decrypt.
-func (w *Whisper) Messages(id string) []*ReceivedMessage {
- result := make([]*ReceivedMessage, 0)
- w.poolMu.RLock()
- defer w.poolMu.RUnlock()
-
- if filter := w.filters.Get(id); filter != nil {
- for _, env := range w.envelopes {
- msg := filter.processEnvelope(env)
- if msg != nil {
- result = append(result, msg)
- }
- }
- }
- return result
-}
-
-// isEnvelopeCached checks if envelope with specific hash has already been received and cached.
-func (w *Whisper) isEnvelopeCached(hash common.Hash) bool {
- w.poolMu.Lock()
- defer w.poolMu.Unlock()
-
- _, exist := w.envelopes[hash]
- return exist
-}
-
-// reset resets the node's statistics after each expiry cycle.
-func (s *Statistics) reset() {
- s.cycles++
- s.totalMessagesCleared += s.messagesCleared
-
- s.memoryCleared = 0
- s.messagesCleared = 0
-}
-
-// ValidatePublicKey checks the format of the given public key.
-func ValidatePublicKey(k *ecdsa.PublicKey) bool {
- return k != nil && k.X != nil && k.Y != nil && k.X.Sign() != 0 && k.Y.Sign() != 0
-}
-
-// validatePrivateKey checks the format of the given private key.
-func validatePrivateKey(k *ecdsa.PrivateKey) bool {
- if k == nil || k.D == nil || k.D.Sign() == 0 {
- return false
- }
- return ValidatePublicKey(&k.PublicKey)
-}
-
-// validateSymmetricKey returns false if the key contains all zeros
-func validateSymmetricKey(k []byte) bool {
- return len(k) > 0 && !containsOnlyZeros(k)
-}
-
-// containsOnlyZeros checks if the data contain only zeros.
-func containsOnlyZeros(data []byte) bool {
- for _, b := range data {
- if b != 0 {
- return false
- }
- }
- return true
-}
-
-// bytesToUintLittleEndian converts the slice to 64-bit unsigned integer.
-func bytesToUintLittleEndian(b []byte) (res uint64) {
- mul := uint64(1)
- for i := 0; i < len(b); i++ {
- res += uint64(b[i]) * mul
- mul *= 256
- }
- return res
-}
-
-// BytesToUintBigEndian converts the slice to 64-bit unsigned integer.
-func BytesToUintBigEndian(b []byte) (res uint64) {
- for i := 0; i < len(b); i++ {
- res *= 256
- res += uint64(b[i])
- }
- return res
-}
-
-// deriveKeyMaterial derives symmetric key material from the key or password.
-// pbkdf2 is used for security, in case people use password instead of randomly generated keys.
-func deriveKeyMaterial(key []byte, version uint64) (derivedKey []byte, err error) {
- if version == 0 {
- // kdf should run no less than 0.1 seconds on average compute,
- // because it's a once in a session experience
- derivedKey := pbkdf2.Key(key, nil, 65356, aesKeyLength, sha256.New)
- return derivedKey, nil
- } else {
- return nil, unknownVersionError(version)
- }
-}
-
-// GenerateRandomID generates a random string, which is then returned to be used as a key id
-func GenerateRandomID() (id string, err error) {
- buf := make([]byte, keyIdSize)
- _, err = crand.Read(buf)
- if err != nil {
- return "", err
- }
- if !validateSymmetricKey(buf) {
- return "", fmt.Errorf("error in generateRandomID: crypto/rand failed to generate random data")
- }
- id = common.Bytes2Hex(buf)
- return id, err
-}
diff --git a/whisper/whisperv6/whisper_test.go b/whisper/whisperv6/whisper_test.go
deleted file mode 100644
index c7cea40146f3..000000000000
--- a/whisper/whisperv6/whisper_test.go
+++ /dev/null
@@ -1,851 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see .
-
-package whisperv6
-
-import (
- "bytes"
- "crypto/ecdsa"
- mrand "math/rand"
- "testing"
- "time"
-
- "github.com/ethereum/go-ethereum/common"
-)
-
-func TestWhisperBasic(t *testing.T) {
- w := New(&DefaultConfig)
- p := w.Protocols()
- shh := p[0]
- if shh.Name != ProtocolName {
- t.Fatalf("failed Protocol Name: %v.", shh.Name)
- }
- if uint64(shh.Version) != ProtocolVersion {
- t.Fatalf("failed Protocol Version: %v.", shh.Version)
- }
- if shh.Length != NumberOfMessageCodes {
- t.Fatalf("failed Protocol Length: %v.", shh.Length)
- }
- if shh.Run == nil {
- t.Fatalf("failed shh.Run.")
- }
- if uint64(w.Version()) != ProtocolVersion {
- t.Fatalf("failed whisper Version: %v.", shh.Version)
- }
- if w.GetFilter("non-existent") != nil {
- t.Fatalf("failed GetFilter.")
- }
-
- peerID := make([]byte, 64)
- mrand.Read(peerID)
- peer, _ := w.getPeer(peerID)
- if peer != nil {
- t.Fatal("found peer for random key.")
- }
- if err := w.AllowP2PMessagesFromPeer(peerID); err == nil {
- t.Fatalf("failed MarkPeerTrusted.")
- }
- exist := w.HasSymKey("non-existing")
- if exist {
- t.Fatalf("failed HasSymKey.")
- }
- key, err := w.GetSymKey("non-existing")
- if err == nil {
- t.Fatalf("failed GetSymKey(non-existing): false positive.")
- }
- if key != nil {
- t.Fatalf("failed GetSymKey: false positive.")
- }
- mail := w.Envelopes()
- if len(mail) != 0 {
- t.Fatalf("failed w.Envelopes().")
- }
- m := w.Messages("non-existent")
- if len(m) != 0 {
- t.Fatalf("failed w.Messages.")
- }
-
- var derived []byte
- ver := uint64(0xDEADBEEF)
- if _, err := deriveKeyMaterial(peerID, ver); err != unknownVersionError(ver) {
- t.Fatalf("failed deriveKeyMaterial with param = %v: %s.", peerID, err)
- }
- derived, err = deriveKeyMaterial(peerID, 0)
- if err != nil {
- t.Fatalf("failed second deriveKeyMaterial with param = %v: %s.", peerID, err)
- }
- if !validateSymmetricKey(derived) {
- t.Fatalf("failed validateSymmetricKey with param = %v.", derived)
- }
- if containsOnlyZeros(derived) {
- t.Fatalf("failed containsOnlyZeros with param = %v.", derived)
- }
-
- buf := []byte{0xFF, 0xE5, 0x80, 0x2, 0}
- le := bytesToUintLittleEndian(buf)
- be := BytesToUintBigEndian(buf)
- if le != uint64(0x280e5ff) {
- t.Fatalf("failed bytesToIntLittleEndian: %d.", le)
- }
- if be != uint64(0xffe5800200) {
- t.Fatalf("failed BytesToIntBigEndian: %d.", be)
- }
-
- id, err := w.NewKeyPair()
- if err != nil {
- t.Fatalf("failed to generate new key pair: %s.", err)
- }
- pk, err := w.GetPrivateKey(id)
- if err != nil {
- t.Fatalf("failed to retrieve new key pair: %s.", err)
- }
- if !validatePrivateKey(pk) {
- t.Fatalf("failed validatePrivateKey: %v.", pk)
- }
- if !ValidatePublicKey(&pk.PublicKey) {
- t.Fatalf("failed ValidatePublicKey: %v.", pk)
- }
-}
-
-func TestWhisperAsymmetricKeyImport(t *testing.T) {
- var (
- w = New(&DefaultConfig)
- privateKeys []*ecdsa.PrivateKey
- )
-
- for i := 0; i < 50; i++ {
- id, err := w.NewKeyPair()
- if err != nil {
- t.Fatalf("could not generate key: %v", err)
- }
-
- pk, err := w.GetPrivateKey(id)
- if err != nil {
- t.Fatalf("could not export private key: %v", err)
- }
-
- privateKeys = append(privateKeys, pk)
-
- if !w.DeleteKeyPair(id) {
- t.Fatalf("could not delete private key")
- }
- }
-
- for _, pk := range privateKeys {
- if _, err := w.AddKeyPair(pk); err != nil {
- t.Fatalf("could not import private key: %v", err)
- }
- }
-}
-
-func TestWhisperIdentityManagement(t *testing.T) {
- w := New(&DefaultConfig)
- id1, err := w.NewKeyPair()
- if err != nil {
- t.Fatalf("failed to generate new key pair: %s.", err)
- }
- id2, err := w.NewKeyPair()
- if err != nil {
- t.Fatalf("failed to generate new key pair: %s.", err)
- }
- pk1, err := w.GetPrivateKey(id1)
- if err != nil {
- t.Fatalf("failed to retrieve the key pair: %s.", err)
- }
- pk2, err := w.GetPrivateKey(id2)
- if err != nil {
- t.Fatalf("failed to retrieve the key pair: %s.", err)
- }
-
- if !w.HasKeyPair(id1) {
- t.Fatalf("failed HasIdentity(pk1).")
- }
- if !w.HasKeyPair(id2) {
- t.Fatalf("failed HasIdentity(pk2).")
- }
- if pk1 == nil {
- t.Fatalf("failed GetIdentity(pk1).")
- }
- if pk2 == nil {
- t.Fatalf("failed GetIdentity(pk2).")
- }
-
- if !validatePrivateKey(pk1) {
- t.Fatalf("pk1 is invalid.")
- }
- if !validatePrivateKey(pk2) {
- t.Fatalf("pk2 is invalid.")
- }
-
- // Delete one identity
- done := w.DeleteKeyPair(id1)
- if !done {
- t.Fatalf("failed to delete id1.")
- }
- pk1, err = w.GetPrivateKey(id1)
- if err == nil {
- t.Fatalf("retrieve the key pair: false positive.")
- }
- pk2, err = w.GetPrivateKey(id2)
- if err != nil {
- t.Fatalf("failed to retrieve the key pair: %s.", err)
- }
- if w.HasKeyPair(id1) {
- t.Fatalf("failed DeleteIdentity(pub1): still exist.")
- }
- if !w.HasKeyPair(id2) {
- t.Fatalf("failed DeleteIdentity(pub1): pub2 does not exist.")
- }
- if pk1 != nil {
- t.Fatalf("failed DeleteIdentity(pub1): first key still exist.")
- }
- if pk2 == nil {
- t.Fatalf("failed DeleteIdentity(pub1): second key does not exist.")
- }
-
- // Delete again non-existing identity
- done = w.DeleteKeyPair(id1)
- if done {
- t.Fatalf("delete id1: false positive.")
- }
- pk1, err = w.GetPrivateKey(id1)
- if err == nil {
- t.Fatalf("retrieve the key pair: false positive.")
- }
- pk2, err = w.GetPrivateKey(id2)
- if err != nil {
- t.Fatalf("failed to retrieve the key pair: %s.", err)
- }
- if w.HasKeyPair(id1) {
- t.Fatalf("failed delete non-existing identity: exist.")
- }
- if !w.HasKeyPair(id2) {
- t.Fatalf("failed delete non-existing identity: pub2 does not exist.")
- }
- if pk1 != nil {
- t.Fatalf("failed delete non-existing identity: first key exist.")
- }
- if pk2 == nil {
- t.Fatalf("failed delete non-existing identity: second key does not exist.")
- }
-
- // Delete second identity
- done = w.DeleteKeyPair(id2)
- if !done {
- t.Fatalf("failed to delete id2.")
- }
- pk1, err = w.GetPrivateKey(id1)
- if err == nil {
- t.Fatalf("retrieve the key pair: false positive.")
- }
- pk2, err = w.GetPrivateKey(id2)
- if err == nil {
- t.Fatalf("retrieve the key pair: false positive.")
- }
- if w.HasKeyPair(id1) {
- t.Fatalf("failed delete second identity: first identity exist.")
- }
- if w.HasKeyPair(id2) {
- t.Fatalf("failed delete second identity: still exist.")
- }
- if pk1 != nil {
- t.Fatalf("failed delete second identity: first key exist.")
- }
- if pk2 != nil {
- t.Fatalf("failed delete second identity: second key exist.")
- }
-}
-
-func TestWhisperSymKeyManagement(t *testing.T) {
- InitSingleTest()
-
- var err error
- var k1, k2 []byte
- w := New(&DefaultConfig)
- id1 := string("arbitrary-string-1")
- id2 := string("arbitrary-string-2")
-
- id1, err = w.GenerateSymKey()
- if err != nil {
- t.Fatalf("failed GenerateSymKey with seed %d: %s.", seed, err)
- }
-
- k1, err = w.GetSymKey(id1)
- if err != nil {
- t.Fatalf("failed GetSymKey(id1).")
- }
- k2, err = w.GetSymKey(id2)
- if err == nil {
- t.Fatalf("failed GetSymKey(id2): false positive.")
- }
- if !w.HasSymKey(id1) {
- t.Fatalf("failed HasSymKey(id1).")
- }
- if w.HasSymKey(id2) {
- t.Fatalf("failed HasSymKey(id2): false positive.")
- }
- if k1 == nil {
- t.Fatalf("first key does not exist.")
- }
- if k2 != nil {
- t.Fatalf("second key still exist.")
- }
-
- // add existing id, nothing should change
- randomKey := make([]byte, aesKeyLength)
- mrand.Read(randomKey)
- id1, err = w.AddSymKeyDirect(randomKey)
- if err != nil {
- t.Fatalf("failed AddSymKey with seed %d: %s.", seed, err)
- }
-
- k1, err = w.GetSymKey(id1)
- if err != nil {
- t.Fatalf("failed w.GetSymKey(id1).")
- }
- k2, err = w.GetSymKey(id2)
- if err == nil {
- t.Fatalf("failed w.GetSymKey(id2): false positive.")
- }
- if !w.HasSymKey(id1) {
- t.Fatalf("failed w.HasSymKey(id1).")
- }
- if w.HasSymKey(id2) {
- t.Fatalf("failed w.HasSymKey(id2): false positive.")
- }
- if k1 == nil {
- t.Fatalf("first key does not exist.")
- }
- if !bytes.Equal(k1, randomKey) {
- t.Fatalf("k1 != randomKey.")
- }
- if k2 != nil {
- t.Fatalf("second key already exist.")
- }
-
- id2, err = w.AddSymKeyDirect(randomKey)
- if err != nil {
- t.Fatalf("failed AddSymKey(id2) with seed %d: %s.", seed, err)
- }
- k1, err = w.GetSymKey(id1)
- if err != nil {
- t.Fatalf("failed w.GetSymKey(id1).")
- }
- k2, err = w.GetSymKey(id2)
- if err != nil {
- t.Fatalf("failed w.GetSymKey(id2).")
- }
- if !w.HasSymKey(id1) {
- t.Fatalf("HasSymKey(id1) failed.")
- }
- if !w.HasSymKey(id2) {
- t.Fatalf("HasSymKey(id2) failed.")
- }
- if k1 == nil {
- t.Fatalf("k1 does not exist.")
- }
- if k2 == nil {
- t.Fatalf("k2 does not exist.")
- }
- if !bytes.Equal(k1, k2) {
- t.Fatalf("k1 != k2.")
- }
- if !bytes.Equal(k1, randomKey) {
- t.Fatalf("k1 != randomKey.")
- }
- if len(k1) != aesKeyLength {
- t.Fatalf("wrong length of k1.")
- }
- if len(k2) != aesKeyLength {
- t.Fatalf("wrong length of k2.")
- }
-
- w.DeleteSymKey(id1)
- k1, err = w.GetSymKey(id1)
- if err == nil {
- t.Fatalf("failed w.GetSymKey(id1): false positive.")
- }
- if k1 != nil {
- t.Fatalf("failed GetSymKey(id1): false positive.")
- }
- k2, err = w.GetSymKey(id2)
- if err != nil {
- t.Fatalf("failed w.GetSymKey(id2).")
- }
- if w.HasSymKey(id1) {
- t.Fatalf("failed to delete first key: still exist.")
- }
- if !w.HasSymKey(id2) {
- t.Fatalf("failed to delete first key: second key does not exist.")
- }
- if k1 != nil {
- t.Fatalf("failed to delete first key.")
- }
- if k2 == nil {
- t.Fatalf("failed to delete first key: second key is nil.")
- }
-
- w.DeleteSymKey(id1)
- w.DeleteSymKey(id2)
- k1, err = w.GetSymKey(id1)
- if err == nil {
- t.Fatalf("failed w.GetSymKey(id1): false positive.")
- }
- k2, err = w.GetSymKey(id2)
- if err == nil {
- t.Fatalf("failed w.GetSymKey(id2): false positive.")
- }
- if k1 != nil || k2 != nil {
- t.Fatalf("k1 or k2 is not nil")
- }
- if w.HasSymKey(id1) {
- t.Fatalf("failed to delete second key: first key exist.")
- }
- if w.HasSymKey(id2) {
- t.Fatalf("failed to delete second key: still exist.")
- }
- if k1 != nil {
- t.Fatalf("failed to delete second key: first key is not nil.")
- }
- if k2 != nil {
- t.Fatalf("failed to delete second key: second key is not nil.")
- }
-
- randomKey = make([]byte, aesKeyLength+1)
- mrand.Read(randomKey)
- _, err = w.AddSymKeyDirect(randomKey)
- if err == nil {
- t.Fatalf("added the key with wrong size, seed %d.", seed)
- }
-
- const password = "arbitrary data here"
- id1, err = w.AddSymKeyFromPassword(password)
- if err != nil {
- t.Fatalf("failed AddSymKeyFromPassword(id1) with seed %d: %s.", seed, err)
- }
- id2, err = w.AddSymKeyFromPassword(password)
- if err != nil {
- t.Fatalf("failed AddSymKeyFromPassword(id2) with seed %d: %s.", seed, err)
- }
- k1, err = w.GetSymKey(id1)
- if err != nil {
- t.Fatalf("failed w.GetSymKey(id1).")
- }
- k2, err = w.GetSymKey(id2)
- if err != nil {
- t.Fatalf("failed w.GetSymKey(id2).")
- }
- if !w.HasSymKey(id1) {
- t.Fatalf("HasSymKey(id1) failed.")
- }
- if !w.HasSymKey(id2) {
- t.Fatalf("HasSymKey(id2) failed.")
- }
- if k1 == nil {
- t.Fatalf("k1 does not exist.")
- }
- if k2 == nil {
- t.Fatalf("k2 does not exist.")
- }
- if !bytes.Equal(k1, k2) {
- t.Fatalf("k1 != k2.")
- }
- if len(k1) != aesKeyLength {
- t.Fatalf("wrong length of k1.")
- }
- if len(k2) != aesKeyLength {
- t.Fatalf("wrong length of k2.")
- }
- if !validateSymmetricKey(k2) {
- t.Fatalf("key validation failed.")
- }
-}
-
-func TestExpiry(t *testing.T) {
- InitSingleTest()
-
- w := New(&DefaultConfig)
- w.SetMinimumPoW(0.0000001)
- defer w.SetMinimumPoW(DefaultMinimumPoW)
- w.Start(nil)
- defer w.Stop()
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- params.TTL = 1
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- err = w.Send(env)
- if err != nil {
- t.Fatalf("failed to send envelope with seed %d: %s.", seed, err)
- }
-
- // wait till received or timeout
- var received, expired bool
- for j := 0; j < 20; j++ {
- time.Sleep(100 * time.Millisecond)
- if len(w.Envelopes()) > 0 {
- received = true
- break
- }
- }
-
- if !received {
- t.Fatalf("did not receive the sent envelope, seed: %d.", seed)
- }
-
- // wait till expired or timeout
- for j := 0; j < 20; j++ {
- time.Sleep(100 * time.Millisecond)
- if len(w.Envelopes()) == 0 {
- expired = true
- break
- }
- }
-
- if !expired {
- t.Fatalf("expire failed, seed: %d.", seed)
- }
-}
-
-func TestCustomization(t *testing.T) {
- InitSingleTest()
-
- w := New(&DefaultConfig)
- defer w.SetMinimumPoW(DefaultMinimumPoW)
- defer w.SetMaxMessageSize(DefaultMaxMessageSize)
- w.Start(nil)
- defer w.Stop()
-
- const smallPoW = 0.00001
-
- f, err := generateFilter(t, true)
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- params.KeySym = f.KeySym
- params.Topic = BytesToTopic(f.Topics[2])
- params.PoW = smallPoW
- params.TTL = 3600 * 24 // one day
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- err = w.Send(env)
- if err == nil {
- t.Fatalf("successfully sent envelope with PoW %.06f, false positive (seed %d).", env.PoW(), seed)
- }
-
- w.SetMinimumPoW(smallPoW / 2)
- err = w.Send(env)
- if err != nil {
- t.Fatalf("failed to send envelope with seed %d: %s.", seed, err)
- }
-
- params.TTL++
- msg, err = NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err = msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
- w.SetMaxMessageSize(uint32(env.size() - 1))
- err = w.Send(env)
- if err == nil {
- t.Fatalf("successfully sent oversized envelope (seed %d): false positive.", seed)
- }
-
- w.SetMaxMessageSize(DefaultMaxMessageSize)
- err = w.Send(env)
- if err != nil {
- t.Fatalf("failed to send second envelope with seed %d: %s.", seed, err)
- }
-
- // wait till received or timeout
- var received bool
- for j := 0; j < 20; j++ {
- time.Sleep(100 * time.Millisecond)
- if len(w.Envelopes()) > 1 {
- received = true
- break
- }
- }
-
- if !received {
- t.Fatalf("did not receive the sent envelope, seed: %d.", seed)
- }
-
- // check w.messages()
- id, err := w.Subscribe(f)
- if err != nil {
- t.Fatalf("failed subscribe with seed %d: %s.", seed, err)
- }
- time.Sleep(5 * time.Millisecond)
- mail := f.Retrieve()
- if len(mail) > 0 {
- t.Fatalf("received premature mail")
- }
-
- mail = w.Messages(id)
- if len(mail) != 2 {
- t.Fatalf("failed to get whisper messages")
- }
-}
-
-func TestSymmetricSendCycle(t *testing.T) {
- InitSingleTest()
-
- w := New(&DefaultConfig)
- defer w.SetMinimumPoW(DefaultMinimumPoW)
- defer w.SetMaxMessageSize(DefaultMaxMessageSize)
- w.Start(nil)
- defer w.Stop()
-
- filter1, err := generateFilter(t, true)
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- filter1.PoW = DefaultMinimumPoW
-
- // Copy the first filter since some of its fields
- // are randomly gnerated.
- filter2 := &Filter{
- KeySym: filter1.KeySym,
- Topics: filter1.Topics,
- PoW: filter1.PoW,
- AllowP2P: filter1.AllowP2P,
- Messages: make(map[common.Hash]*ReceivedMessage),
- }
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- filter1.Src = ¶ms.Src.PublicKey
- filter2.Src = ¶ms.Src.PublicKey
-
- params.KeySym = filter1.KeySym
- params.Topic = BytesToTopic(filter1.Topics[2])
- params.PoW = filter1.PoW
- params.WorkTime = 10
- params.TTL = 50
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- _, err = w.Subscribe(filter1)
- if err != nil {
- t.Fatalf("failed subscribe 1 with seed %d: %s.", seed, err)
- }
-
- _, err = w.Subscribe(filter2)
- if err != nil {
- t.Fatalf("failed subscribe 2 with seed %d: %s.", seed, err)
- }
-
- err = w.Send(env)
- if err != nil {
- t.Fatalf("Failed sending envelope with PoW %.06f (seed %d): %s", env.PoW(), seed, err)
- }
-
- // wait till received or timeout
- var received bool
- for j := 0; j < 200; j++ {
- time.Sleep(10 * time.Millisecond)
- if len(w.Envelopes()) > 0 {
- received = true
- break
- }
- }
-
- if !received {
- t.Fatalf("did not receive the sent envelope, seed: %d.", seed)
- }
-
- // check w.messages()
- time.Sleep(5 * time.Millisecond)
- mail1 := filter1.Retrieve()
- mail2 := filter2.Retrieve()
- if len(mail2) == 0 {
- t.Fatalf("did not receive any email for filter 2")
- }
- if len(mail1) == 0 {
- t.Fatalf("did not receive any email for filter 1")
- }
-
-}
-
-func TestSymmetricSendWithoutAKey(t *testing.T) {
- InitSingleTest()
-
- w := New(&DefaultConfig)
- defer w.SetMinimumPoW(DefaultMinimumPoW)
- defer w.SetMaxMessageSize(DefaultMaxMessageSize)
- w.Start(nil)
- defer w.Stop()
-
- filter, err := generateFilter(t, true)
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- filter.PoW = DefaultMinimumPoW
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- filter.Src = nil
-
- params.KeySym = filter.KeySym
- params.Topic = BytesToTopic(filter.Topics[2])
- params.PoW = filter.PoW
- params.WorkTime = 10
- params.TTL = 50
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- _, err = w.Subscribe(filter)
- if err != nil {
- t.Fatalf("failed subscribe 1 with seed %d: %s.", seed, err)
- }
-
- err = w.Send(env)
- if err != nil {
- t.Fatalf("Failed sending envelope with PoW %.06f (seed %d): %s", env.PoW(), seed, err)
- }
-
- // wait till received or timeout
- var received bool
- for j := 0; j < 200; j++ {
- time.Sleep(10 * time.Millisecond)
- if len(w.Envelopes()) > 0 {
- received = true
- break
- }
- }
-
- if !received {
- t.Fatalf("did not receive the sent envelope, seed: %d.", seed)
- }
-
- // check w.messages()
- time.Sleep(5 * time.Millisecond)
- mail := filter.Retrieve()
- if len(mail) == 0 {
- t.Fatalf("did not receive message in spite of not setting a public key")
- }
-}
-
-func TestSymmetricSendKeyMismatch(t *testing.T) {
- InitSingleTest()
-
- w := New(&DefaultConfig)
- defer w.SetMinimumPoW(DefaultMinimumPoW)
- defer w.SetMaxMessageSize(DefaultMaxMessageSize)
- w.Start(nil)
- defer w.Stop()
-
- filter, err := generateFilter(t, true)
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
- filter.PoW = DefaultMinimumPoW
-
- params, err := generateMessageParams()
- if err != nil {
- t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
- }
-
- params.KeySym = filter.KeySym
- params.Topic = BytesToTopic(filter.Topics[2])
- params.PoW = filter.PoW
- params.WorkTime = 10
- params.TTL = 50
- msg, err := NewSentMessage(params)
- if err != nil {
- t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
- }
- env, err := msg.Wrap(params)
- if err != nil {
- t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
- }
-
- _, err = w.Subscribe(filter)
- if err != nil {
- t.Fatalf("failed subscribe 1 with seed %d: %s.", seed, err)
- }
-
- err = w.Send(env)
- if err != nil {
- t.Fatalf("Failed sending envelope with PoW %.06f (seed %d): %s", env.PoW(), seed, err)
- }
-
- // wait till received or timeout
- var received bool
- for j := 0; j < 200; j++ {
- time.Sleep(10 * time.Millisecond)
- if len(w.Envelopes()) > 0 {
- received = true
- break
- }
- }
-
- if !received {
- t.Fatalf("did not receive the sent envelope, seed: %d.", seed)
- }
-
- // check w.messages()
- time.Sleep(5 * time.Millisecond)
- mail := filter.Retrieve()
- if len(mail) > 0 {
- t.Fatalf("received a message when keys weren't matching")
- }
-}