diff --git a/.travis.yml b/.travis.yml
index b09bd7ce041180fa1ca8e444e9e115453db07954..7d0777fee9cae118eb94bf0089040a77c5cbc39b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,7 +14,6 @@ matrix:
       - go run build/ci.go install
       - go run build/ci.go test -coverage $TEST_PACKAGES
 
-    # These are the latest Go versions.
     - os: linux
       dist: trusty
       sudo: required
@@ -26,8 +25,20 @@ matrix:
         - go run build/ci.go install
         - go run build/ci.go test -coverage $TEST_PACKAGES
 
+    # These are the latest Go versions.
+    - os: linux
+      dist: trusty
+      sudo: required
+      go: 1.12.x
+      script:
+        - sudo modprobe fuse
+        - sudo chmod 666 /dev/fuse
+        - sudo chown root:$USER /etc/fuse.conf
+        - go run build/ci.go install
+        - go run build/ci.go test -coverage $TEST_PACKAGES
+
     - os: osx
-      go: 1.11.x
+      go: 1.12.x
       script:
         - echo "Increase the maximum number of open file descriptors on macOS"
         - NOFILE=20480
@@ -44,7 +55,7 @@ matrix:
     # This builder only tests code linters on latest version of Go
     - os: linux
       dist: trusty
-      go: 1.11.x
+      go: 1.12.x
       env:
         - lint
       git:
@@ -56,7 +67,7 @@ matrix:
     - if: repo = ethereum/go-ethereum AND type = push
       os: linux
       dist: trusty
-      go: 1.11.x
+      go: 1.12.x
       env:
         - ubuntu-ppa
       git:
@@ -79,7 +90,7 @@ matrix:
       os: linux
       dist: trusty
       sudo: required
-      go: 1.11.x
+      go: 1.12.x
       env:
         - azure-linux
       git:
@@ -114,7 +125,7 @@ matrix:
       dist: trusty
       services:
         - docker
-      go: 1.11.x
+      go: 1.12.x
       env:
         - azure-linux-mips
       git:
@@ -159,7 +170,7 @@ matrix:
       git:
         submodules: false # avoid cloning ethereum/tests
       before_install:
-        - curl https://storage.googleapis.com/golang/go1.11.5.linux-amd64.tar.gz | tar -xz
+        - curl https://dl.google.com/go/go1.12.linux-amd64.tar.gz | tar -xz
         - export PATH=`pwd`/go/bin:$PATH
         - export GOROOT=`pwd`/go
         - export GOPATH=$HOME/go
@@ -176,7 +187,7 @@ matrix:
     # This builder does the OSX Azure, iOS CocoaPods and iOS Azure uploads
     - if: repo = ethereum/go-ethereum AND type = push
       os: osx
-      go: 1.11.x
+      go: 1.12.x
       env:
         - azure-osx
         - azure-ios
@@ -206,7 +217,7 @@ matrix:
     - if: repo = ethereum/go-ethereum AND type = cron
       os: linux
       dist: trusty
-      go: 1.11.x
+      go: 1.12.x
       env:
         - azure-purge
       git:
@@ -218,7 +229,7 @@ matrix:
       if: repo = ethersphere/go-ethereum
       os: linux
       dist: trusty
-      go: 1.11.x
+      go: 1.12.x
       git:
         submodules: false # avoid cloning ethereum/tests
       script: ./build/travis_keepalive.sh go test -v -timeout 20m -race ./swarm...
diff --git a/Dockerfile b/Dockerfile
index e87dd35d3215259b0d9455f29a973e9238821d99..4b205d64923b5d8255abaacb894b79ccab1f71b2 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
 # Build Geth in a stock Go builder container
-FROM golang:1.11-alpine as builder
+FROM golang:1.12-alpine as builder
 
 RUN apk add --no-cache make gcc musl-dev linux-headers
 
diff --git a/Dockerfile.alltools b/Dockerfile.alltools
index e984a1b092bff4ef0e803b67728a21e1f277976f..4a4a26f8bce4f756c0ec1a4b933c51a1f569a02c 100644
--- a/Dockerfile.alltools
+++ b/Dockerfile.alltools
@@ -1,5 +1,5 @@
 # Build Geth in a stock Go builder container
-FROM golang:1.11-alpine as builder
+FROM golang:1.12-alpine as builder
 
 RUN apk add --no-cache make gcc musl-dev linux-headers
 
diff --git a/appveyor.yml b/appveyor.yml
index 9ed4f114e3564b14530b3585290974ae5f880bc0..515f3d9fbe6f78c467d7f0b7241154d01fa1d3ad 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -23,8 +23,8 @@ environment:
 install:
   - git submodule update --init
   - rmdir C:\go /s /q
-  - appveyor DownloadFile https://storage.googleapis.com/golang/go1.11.5.windows-%GETH_ARCH%.zip
-  - 7z x go1.11.5.windows-%GETH_ARCH%.zip -y -oC:\ > NUL
+  - appveyor DownloadFile https://dl.google.com/go/go1.12.windows-%GETH_ARCH%.zip
+  - 7z x go1.12.windows-%GETH_ARCH%.zip -y -oC:\ > NUL
   - go version
   - gcc --version
 
diff --git a/common/fdlimit/fdlimit_darwin.go b/common/fdlimit/fdlimit_darwin.go
new file mode 100644
index 0000000000000000000000000000000000000000..88dd0f56cbc3fdd05f153e62f1b6ab65ba0df8ae
--- /dev/null
+++ b/common/fdlimit/fdlimit_darwin.go
@@ -0,0 +1,71 @@
+// Copyright 2019 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
+
+package fdlimit
+
+import "syscall"
+
+// hardlimit is the number of file descriptors allowed at max by the kernel.
+const hardlimit = 10240
+
+// Raise tries to maximize the file descriptor allowance of this process
+// to the maximum hard-limit allowed by the OS.
+// Returns the size it was set to (may differ from the desired 'max')
+func Raise(max uint64) (uint64, error) {
+	// Get the current limit
+	var limit syscall.Rlimit
+	if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+		return 0, 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 0, err
+	}
+	// MacOS can silently apply further caps, so retrieve the actually set limit
+	if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+		return 0, err
+	}
+	return limit.Cur, 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) {
+	// Retrieve the maximum allowed by dynamic OS limits
+	var limit syscall.Rlimit
+	if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
+		return 0, err
+	}
+	// Cap it to OPEN_MAX (10240) because macos is a special snowflake
+	if limit.Max > hardlimit {
+		limit.Max = hardlimit
+	}
+	return int(limit.Max), nil
+}
diff --git a/common/fdlimit/fdlimit_unix.go b/common/fdlimit/fdlimit_unix.go
index 67011275155422d78be972848bcffd05963fe8fd..e5a575f7a79d3c92dfb8fd5b312a78701884975c 100644
--- a/common/fdlimit/fdlimit_unix.go
+++ b/common/fdlimit/fdlimit_unix.go
@@ -14,7 +14,7 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
 
-// +build linux darwin netbsd openbsd solaris
+// +build linux netbsd openbsd solaris
 
 package fdlimit
 
diff --git a/common/fdlimit/fdlimit_windows.go b/common/fdlimit/fdlimit_windows.go
index 63a44e0de05b47a03e44170f81b0524d8394d274..f472153662e6d0cea6f35683411bf0264239e217 100644
--- a/common/fdlimit/fdlimit_windows.go
+++ b/common/fdlimit/fdlimit_windows.go
@@ -18,6 +18,7 @@ package fdlimit
 
 import "fmt"
 
+// hardlimit is the number of file descriptors allowed at max by the kernel.
 const hardlimit = 16384
 
 // Raise tries to maximize the file descriptor allowance of this process
diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go
index 7177ae9ce7619041972d0cb877290df81e10c745..e1c2e066964f29279ad03b7c097e11dc0365b63c 100644
--- a/core/tx_pool_test.go
+++ b/core/tx_pool_test.go
@@ -126,7 +126,7 @@ func validateEvents(events chan NewTxsEvent, count int) error {
 		case ev := <-events:
 			received = append(received, ev.Txs...)
 		case <-time.After(time.Second):
-			return fmt.Errorf("event #%d not fired", received)
+			return fmt.Errorf("event #%d not fired", len(received))
 		}
 	}
 	if len(received) > count {
diff --git a/crypto/bn256/cloudflare/main_test.go b/crypto/bn256/cloudflare/main_test.go
index 0230f1b1993d5078f77d772f69210f367ebea615..c0c85457becabc0fded7f74593cd80dff35eade8 100644
--- a/crypto/bn256/cloudflare/main_test.go
+++ b/crypto/bn256/cloudflare/main_test.go
@@ -13,7 +13,7 @@ func TestRandomG2Marshal(t *testing.T) {
 			t.Error(err)
 			continue
 		}
-		t.Logf("%d: %x\n", n, g2.Marshal())
+		t.Logf("%v: %x\n", n, g2.Marshal())
 	}
 }
 
diff --git a/crypto/bn256/google/main_test.go b/crypto/bn256/google/main_test.go
index 0230f1b1993d5078f77d772f69210f367ebea615..c0c85457becabc0fded7f74593cd80dff35eade8 100644
--- a/crypto/bn256/google/main_test.go
+++ b/crypto/bn256/google/main_test.go
@@ -13,7 +13,7 @@ func TestRandomG2Marshal(t *testing.T) {
 			t.Error(err)
 			continue
 		}
-		t.Logf("%d: %x\n", n, g2.Marshal())
+		t.Logf("%v: %x\n", n, g2.Marshal())
 	}
 }
 
diff --git a/internal/build/util.go b/internal/build/util.go
index a41ecfbed3a903351c66634e133f758ef8ec7e15..b34371c2dd59ce703135c9a00a2b2c20d5a80613 100644
--- a/internal/build/util.go
+++ b/internal/build/util.go
@@ -143,9 +143,9 @@ func CopyFile(dst, src string, mode os.FileMode) {
 // so that go commands executed by build use the same version of Go as the 'host' that runs
 // build code. e.g.
 //
-//     /usr/lib/go-1.11/bin/go run build/ci.go ...
+//     /usr/lib/go-1.12/bin/go run build/ci.go ...
 //
-// runs using go 1.11 and invokes go 1.11 tools from the same GOROOT. This is also important
+// runs using go 1.12 and invokes go 1.12 tools from the same GOROOT. This is also important
 // because runtime.Version checks on the host should match the tools that are run.
 func GoTool(tool string, args ...string) *exec.Cmd {
 	args = append([]string{tool}, args...)