diff --git a/rpc/client_test.go b/rpc/client_test.go
index 315bd6d7d14d0d1a3c57dc5bc781af35a5ba7647..0d551402228ee262e4f9840b95df0a847dbdb6c1 100644
--- a/rpc/client_test.go
+++ b/rpc/client_test.go
@@ -40,11 +40,11 @@ func TestClientRequest(t *testing.T) {
 	client := DialInProc(server)
 	defer client.Close()
 
-	var resp Result
-	if err := client.Call(&resp, "test_echo", "hello", 10, &Args{"world"}); err != nil {
+	var resp echoResult
+	if err := client.Call(&resp, "test_echo", "hello", 10, &echoArgs{"world"}); err != nil {
 		t.Fatal(err)
 	}
-	if !reflect.DeepEqual(resp, Result{"hello", 10, &Args{"world"}}) {
+	if !reflect.DeepEqual(resp, echoResult{"hello", 10, &echoArgs{"world"}}) {
 		t.Errorf("incorrect result %#v", resp)
 	}
 }
@@ -58,13 +58,13 @@ func TestClientBatchRequest(t *testing.T) {
 	batch := []BatchElem{
 		{
 			Method: "test_echo",
-			Args:   []interface{}{"hello", 10, &Args{"world"}},
-			Result: new(Result),
+			Args:   []interface{}{"hello", 10, &echoArgs{"world"}},
+			Result: new(echoResult),
 		},
 		{
 			Method: "test_echo",
-			Args:   []interface{}{"hello2", 11, &Args{"world"}},
-			Result: new(Result),
+			Args:   []interface{}{"hello2", 11, &echoArgs{"world"}},
+			Result: new(echoResult),
 		},
 		{
 			Method: "no_such_method",
@@ -78,13 +78,13 @@ func TestClientBatchRequest(t *testing.T) {
 	wantResult := []BatchElem{
 		{
 			Method: "test_echo",
-			Args:   []interface{}{"hello", 10, &Args{"world"}},
-			Result: &Result{"hello", 10, &Args{"world"}},
+			Args:   []interface{}{"hello", 10, &echoArgs{"world"}},
+			Result: &echoResult{"hello", 10, &echoArgs{"world"}},
 		},
 		{
 			Method: "test_echo",
-			Args:   []interface{}{"hello2", 11, &Args{"world"}},
-			Result: &Result{"hello2", 11, &Args{"world"}},
+			Args:   []interface{}{"hello2", 11, &echoArgs{"world"}},
+			Result: &echoResult{"hello2", 11, &echoArgs{"world"}},
 		},
 		{
 			Method: "no_such_method",
@@ -104,7 +104,7 @@ func TestClientNotify(t *testing.T) {
 	client := DialInProc(server)
 	defer client.Close()
 
-	if err := client.Notify(context.Background(), "test_echo", "hello", 10, &Args{"world"}); err != nil {
+	if err := client.Notify(context.Background(), "test_echo", "hello", 10, &echoArgs{"world"}); err != nil {
 		t.Fatal(err)
 	}
 }
@@ -393,9 +393,9 @@ func TestClientHTTP(t *testing.T) {
 
 	// Launch concurrent requests.
 	var (
-		results    = make([]Result, 100)
+		results    = make([]echoResult, 100)
 		errc       = make(chan error)
-		wantResult = Result{"a", 1, new(Args)}
+		wantResult = echoResult{"a", 1, new(echoArgs)}
 	)
 	defer client.Close()
 	for i := range results {
@@ -450,7 +450,7 @@ func TestClientReconnect(t *testing.T) {
 	}
 
 	// Perform a call. This should work because the server is up.
-	var resp Result
+	var resp echoResult
 	if err := client.CallContext(ctx, &resp, "test_echo", "", 1, nil); err != nil {
 		t.Fatal(err)
 	}
@@ -478,7 +478,7 @@ func TestClientReconnect(t *testing.T) {
 	for i := 0; i < cap(errors); i++ {
 		go func() {
 			<-start
-			var resp Result
+			var resp echoResult
 			errors <- client.CallContext(ctx, &resp, "test_echo", "", 3, nil)
 		}()
 	}
diff --git a/rpc/doc.go b/rpc/doc.go
index c9eaef54f07f8ffca869d4b05ef901b9f5bc85ac..e0a6324675e685bb22fb5c5611ef82603be19aaa 100644
--- a/rpc/doc.go
+++ b/rpc/doc.go
@@ -29,8 +29,6 @@ Methods that satisfy the following criteria are made available for remote access
 
  - method must be exported
  - method returns 0, 1 (response or error) or 2 (response and error) values
- - method argument(s) must be exported or builtin types
- - method returned value(s) must be exported or builtin types
 
 An example method:
 
@@ -74,13 +72,8 @@ An example server which uses the JSON codec:
  calculator := new(CalculatorService)
  server := NewServer()
  server.RegisterName("calculator", calculator)
-
  l, _ := net.ListenUnix("unix", &net.UnixAddr{Net: "unix", Name: "/tmp/calculator.sock"})
- for {
-	c, _ := l.AcceptUnix()
-	codec := v2.NewJSONCodec(c)
-	go server.ServeCodec(codec, 0)
- }
+ server.ServeListener(l)
 
 Subscriptions
 
@@ -90,7 +83,6 @@ criteria:
 
  - method must be exported
  - first method argument type must be context.Context
- - method argument(s) must be exported or builtin types
  - method must have return types (rpc.Subscription, error)
 
 An example method:
diff --git a/rpc/handler.go b/rpc/handler.go
index 461a88060982c8fa0962b30390ebef6ec63650ba..ab32cf47e4bbc63b9d54fe762cacd5ab0885674c 100644
--- a/rpc/handler.go
+++ b/rpc/handler.go
@@ -189,7 +189,7 @@ func (h *handler) cancelAllRequests(err error, inflightReq *requestOp) {
 	}
 	for id, sub := range h.clientSubs {
 		delete(h.clientSubs, id)
-		sub.quitWithError(err, false)
+		sub.quitWithError(false, err)
 	}
 }
 
diff --git a/rpc/json.go b/rpc/json.go
index ad7294d3156070eb377009946ef383646f62a392..61631a3d766004a96e32492be41dd6c2e320a9f7 100644
--- a/rpc/json.go
+++ b/rpc/json.go
@@ -153,14 +153,6 @@ type ConnRemoteAddr interface {
 	RemoteAddr() string
 }
 
-// connWithRemoteAddr overrides the remote address of a connection.
-type connWithRemoteAddr struct {
-	Conn
-	addr string
-}
-
-func (c connWithRemoteAddr) RemoteAddr() string { return c.addr }
-
 // jsonCodec reads and writes JSON-RPC messages to the underlying connection. It also has
 // support for parsing arguments and serializing (result) objects.
 type jsonCodec struct {
diff --git a/rpc/service.go b/rpc/service.go
index 81e65f810b7172231057b5f47b546abfcfbd31e4..bef891ea112528cde0ce13a32ba15ceacbfa3d3b 100644
--- a/rpc/service.go
+++ b/rpc/service.go
@@ -25,7 +25,6 @@ import (
 	"strings"
 	"sync"
 	"unicode"
-	"unicode/utf8"
 
 	"github.com/ethereum/go-ethereum/log"
 )
@@ -139,16 +138,14 @@ func newCallback(receiver, fn reflect.Value) *callback {
 	c := &callback{fn: fn, rcvr: receiver, errPos: -1, isSubscribe: isPubSub(fntype)}
 	// Determine parameter types. They must all be exported or builtin types.
 	c.makeArgTypes()
-	if !allExportedOrBuiltin(c.argTypes) {
-		return nil
-	}
+
 	// Verify return types. The function must return at most one error
 	// and/or one other non-error value.
 	outs := make([]reflect.Type, fntype.NumOut())
 	for i := 0; i < fntype.NumOut(); i++ {
 		outs[i] = fntype.Out(i)
 	}
-	if len(outs) > 2 || !allExportedOrBuiltin(outs) {
+	if len(outs) > 2 {
 		return nil
 	}
 	// If an error is returned, it must be the last returned value.
@@ -218,27 +215,6 @@ func (c *callback) call(ctx context.Context, method string, args []reflect.Value
 	return results[0].Interface(), nil
 }
 
-// Is this an exported - upper case - name?
-func isExported(name string) bool {
-	rune, _ := utf8.DecodeRuneInString(name)
-	return unicode.IsUpper(rune)
-}
-
-// Are all those types exported or built-in?
-func allExportedOrBuiltin(types []reflect.Type) bool {
-	for _, typ := range types {
-		for typ.Kind() == reflect.Ptr {
-			typ = typ.Elem()
-		}
-		// PkgPath will be non-empty even for an exported type,
-		// so we need to check the type name as well.
-		if !isExported(typ.Name()) && typ.PkgPath() != "" {
-			return false
-		}
-	}
-	return true
-}
-
 // Is t context.Context or *context.Context?
 func isContextType(t reflect.Type) bool {
 	for t.Kind() == reflect.Ptr {
diff --git a/rpc/subscription.go b/rpc/subscription.go
index 153e24063e77f34360936f5d868575a22ed78778..8992bfc5e19a30ee4c664b497015279ba1c55369 100644
--- a/rpc/subscription.go
+++ b/rpc/subscription.go
@@ -241,11 +241,11 @@ func (sub *ClientSubscription) Err() <-chan error {
 // Unsubscribe unsubscribes the notification and closes the error channel.
 // It can safely be called more than once.
 func (sub *ClientSubscription) Unsubscribe() {
-	sub.quitWithError(nil, true)
+	sub.quitWithError(true, nil)
 	sub.errOnce.Do(func() { close(sub.err) })
 }
 
-func (sub *ClientSubscription) quitWithError(err error, unsubscribeServer bool) {
+func (sub *ClientSubscription) quitWithError(unsubscribeServer bool, err error) {
 	sub.quitOnce.Do(func() {
 		// The dispatch loop won't be able to execute the unsubscribe call
 		// if it is blocked on deliver. Close sub.quit first because it
@@ -276,7 +276,7 @@ func (sub *ClientSubscription) start() {
 	sub.quitWithError(sub.forward())
 }
 
-func (sub *ClientSubscription) forward() (err error, unsubscribeServer bool) {
+func (sub *ClientSubscription) forward() (unsubscribeServer bool, err error) {
 	cases := []reflect.SelectCase{
 		{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(sub.quit)},
 		{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(sub.in)},
@@ -298,14 +298,14 @@ func (sub *ClientSubscription) forward() (err error, unsubscribeServer bool) {
 
 		switch chosen {
 		case 0: // <-sub.quit
-			return nil, false
+			return false, nil
 		case 1: // <-sub.in
 			val, err := sub.unmarshal(recv.Interface().(json.RawMessage))
 			if err != nil {
-				return err, true
+				return true, err
 			}
 			if buffer.Len() == maxClientSubscriptionBuffer {
-				return ErrSubscriptionQueueOverflow, true
+				return true, ErrSubscriptionQueueOverflow
 			}
 			buffer.PushBack(val)
 		case 2: // sub.channel<-
diff --git a/rpc/testservice_test.go b/rpc/testservice_test.go
index 98871b5d6cfc743b1654a31f886c3b18e118660d..010fc4f0bb761c65e36551ca436ed433d3c404a3 100644
--- a/rpc/testservice_test.go
+++ b/rpc/testservice_test.go
@@ -53,24 +53,24 @@ func sequentialIDGenerator() func() ID {
 
 type testService struct{}
 
-type Args struct {
+type echoArgs struct {
 	S string
 }
 
-type Result struct {
+type echoResult struct {
 	String string
 	Int    int
-	Args   *Args
+	Args   *echoArgs
 }
 
 func (s *testService) NoArgsRets() {}
 
-func (s *testService) Echo(str string, i int, args *Args) Result {
-	return Result{str, i, args}
+func (s *testService) Echo(str string, i int, args *echoArgs) echoResult {
+	return echoResult{str, i, args}
 }
 
-func (s *testService) EchoWithCtx(ctx context.Context, str string, i int, args *Args) Result {
-	return Result{str, i, args}
+func (s *testService) EchoWithCtx(ctx context.Context, str string, i int, args *echoArgs) echoResult {
+	return echoResult{str, i, args}
 }
 
 func (s *testService) Sleep(ctx context.Context, duration time.Duration) {
@@ -81,6 +81,7 @@ func (s *testService) Rets() (string, error) {
 	return "", nil
 }
 
+//lint:ignore ST1008 returns error first on purpose.
 func (s *testService) InvalidRets1() (error, string) {
 	return nil, ""
 }
diff --git a/rpc/types.go b/rpc/types.go
index fd783137ea1167e5ef219fb96adace8bc0f9d908..dc9248d0feb8b8bc7d5257a01262b4882a8ba4a1 100644
--- a/rpc/types.go
+++ b/rpc/types.go
@@ -97,9 +97,8 @@ func (bn *BlockNumber) UnmarshalJSON(data []byte) error {
 		return err
 	}
 	if blckNum > math.MaxInt64 {
-		return fmt.Errorf("Blocknumber too high")
+		return fmt.Errorf("block number larger than int64")
 	}
-
 	*bn = BlockNumber(blckNum)
 	return nil
 }
diff --git a/rpc/websocket_test.go b/rpc/websocket_test.go
index 9dc1084797966e20740b1d9aaf7a1cf9a59446b0..f2a8438d7ce95971b648566309953461a04a373e 100644
--- a/rpc/websocket_test.go
+++ b/rpc/websocket_test.go
@@ -96,7 +96,7 @@ func TestWebsocketLargeCall(t *testing.T) {
 	defer client.Close()
 
 	// This call sends slightly less than the limit and should work.
-	var result Result
+	var result echoResult
 	arg := strings.Repeat("x", maxRequestContentLength-200)
 	if err := client.Call(&result, "test_echo", arg, 1); err != nil {
 		t.Fatalf("valid call didn't work: %v", err)