stratum

package module
v0.0.0-...-7180bd2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 29, 2018 License: GPL-3.0 Imports: 16 Imported by: 3

README

Stratum

A collection of client and server RPC codecs for interacting with Monero miners and pools.

Installation

go get github.com/trey-jones/stratum

Usage

GoDoc

Check out the full documentation on godoc

There are some differences between JSON RPC 2.0 and (typical?) Monero mining communication. Each end of the connection has some features of a client and a server.

Client embeds a rpc.Client and Server embeds rpc.Server. Learn more about their capabilities from the official documentation.

  • Clients receive notifications (especially jobs) from the server.
  • Servers broadcast notifications to clients, rather than simply responding to calls.
  • Method names don't include a service name.

This means usage is a little different than most RPC codecs for net/rpc. For a more thorough usage example check out the project that spawned this one.

Client

You can get a client with Dial:

c, err := stratum.Dial("tcp", "xmrpool.eu:3333")

If you want to specify a timeout:

c, err := stratum.DialTimeout("tcp", "xmrpool.eu", 10 * time.Second)

Since clients can receive unsolicited notifications from the server you must handle these, even if you don't need them (hint: you need them).

notifs := c.Notifications()
go func() {
    for n := range notifs {
        // it's possible the pool sends more than just jobs
        // but that's the main thing
        parseJob(n)
    }
}()

Use the client to call the remote service. One difference from the standard library rpc.Client is that calls have a timeout (30s by default). This can be adjusted by setting stratum.CallTimeout.

// I recommend not using map[string]interface{}
reply := make(map[string]interface{})

// Call will block until finished
err := c.Call("login", params, &reply)
if err != nil {
    // handle it!
}

JSON RPC 2.0 allows the client to send Notifications to the server without expecting a reply. I don't know of a common use case for this with Monero mining strata, but the functionality is there if you need it!

err := c.Notify("methodname", params)

Server

Create a server and Register a struct that will provide the service methods. You must register your service with the name "mining".*

s := stratum.NewServer() s.RegisterName("mining", &Mining{})

Mining should be an instance of something like this:

type Mining struct{}

// Auth is special login method for Coinhive miners
func (m *Mining) Auth(p Params, resp Reply) error {
    return nil
}

func (m *Mining) Login(p Params, resp Reply) error {
    return nil
}

func (m *Mining) Getjob(p Params, resp Reply) error {
    return nil
}

func (m *Mining) Submit(p Params, resp Reply) error {
    return nil
}

func (m *Mining) Keepalived(p Params, resp Reply) error {
    return nil
}

Again, you can check out a mostly complete implementation in this project.

Codecs

There are currently 2 server codecs included here. DefaultServerCodec will handle typical Monero stratum+tcp connections.

CoinhiveServerCodec will handle what I will refer to as "coinhive-style" connections typical to browser miners. One FOSS variant is CryptoNoter. Note well that the connection used to serve the codec must be an io.ReadWriteCloser. One library that exposes such a connection for websockets is this one. Full Disclosure: I am the author.

Create the appropriate codec for your application:

codec := stratum.NewDefaultServerCodecContext(ctx, conn)

OR

codec := stratum.NewCoinhiveServerCodecContext(ctx, conn)

Serve it up, usually in a separate goroutine:

go s.ServeCodec(codec)

Support this Project

If you find the project useful, consider helping me out. If crypto keeps it up, maybe it will help pay for my daughters' weddings or education, or something.

  • Monero: 47sfBPDL9qbDuF5stdrE8C6gVQXf15SeTN4BNxBZ3Ahs6LTayo2Kia2YES7MeN5FU7MKUrWAYPhmeFUYQ3v4JBAvKSPjigi
  • Bitcoin: 1NwemnZSLhJLnNUbzXvER6yNX55pv9tAcv

I will also review any issues or pull requests that come through here.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (

	// CallTimeout is the amount of time we wait for a response before we return an error
	CallTimeout = 30 * time.Second

	// ErrCallTimedOut means that call did not succeed within CallTimeout
	ErrCallTimedOut = errors.New("rpc call timeout")
)

Functions

func NewCoinhiveServerCodec

func NewCoinhiveServerCodec(conn io.ReadWriteCloser) rpc.ServerCodec

NewCoinhiveServerCodec returns a new rpc.ServerCodec for handling requests from the Coinhive Miner

func NewCoinhiveServerCodecContext

func NewCoinhiveServerCodecContext(ctx context.Context, conn io.ReadWriteCloser) rpc.ServerCodec

NewCoinhiveServerCodecContext is NewCoinhiveServerCodec with given context provided within parameters for compatible RPC methods.

func NewDefaultServerCodec

func NewDefaultServerCodec(conn io.ReadWriteCloser) rpc.ServerCodec

NewDefaultServerCodec returns a new rpc.ServerCodec for handling from a miner implementing the (standard?) xmr stratum+tcp protocol

func NewDefaultServerCodecContext

func NewDefaultServerCodecContext(ctx context.Context, conn io.ReadWriteCloser) rpc.ServerCodec

NewDefaultServerCodecContext is NewDefaultServerCodec with given context provided within parameters for compatible RPC methods.

Types

type Client

type Client struct {
	*rpc.Client
	// contains filtered or unexported fields
}

func Dial

func Dial(network, address string) (*Client, error)

Dial connects to a JSON-RPC 2.0 server at the specified network address.

func DialTimeout

func DialTimeout(network, address string, timeout time.Duration) (*Client, error)

DialTimeout is Dial, but with the timeout specified

func NewClient

func NewClient(conn io.ReadWriteCloser) *Client

NewClient returns a new Client to handle requests to the set of services at the other end of the connection.

func (*Client) Call

func (c *Client) Call(serviceMethod string, args interface{}, reply interface{}) error

Call wraps rpc.Call to provide a timeout - otherwise functionality is the same

func (*Client) Notifications

func (c *Client) Notifications() chan Notification

func (*Client) Notify

func (c *Client) Notify(serviceMethod string, args interface{}) error

Notify tries to invoke the named function. It return error only in case it wasn't able to send request.

type CoinhiveServerCodec

type CoinhiveServerCodec struct {
	// contains filtered or unexported fields
}

func (*CoinhiveServerCodec) Close

func (c *CoinhiveServerCodec) Close() error

Close implements rpc.ServerCodec

func (*CoinhiveServerCodec) Notify

func (c *CoinhiveServerCodec) Notify(method string, args interface{}) error

func (*CoinhiveServerCodec) ReadRequestBody

func (c *CoinhiveServerCodec) ReadRequestBody(x interface{}) error

ReadRequestBody implements rpc.ServerCodec

func (*CoinhiveServerCodec) ReadRequestHeader

func (c *CoinhiveServerCodec) ReadRequestHeader(r *rpc.Request) (err error)

ReadRequestHeader implements rpc.ServerCodec

func (*CoinhiveServerCodec) WriteResponse

func (c *CoinhiveServerCodec) WriteResponse(r *rpc.Response, x interface{}) error

WriteResponse implements rpc.ServerCodec

type DefaultServerCodec

type DefaultServerCodec struct {
	// contains filtered or unexported fields
}

DefaultServerCodec handles xmr stratum+tcp requests and is capabable of sending a notification to the connection using it.

func (*DefaultServerCodec) Close

func (c *DefaultServerCodec) Close() error

Close implements rpc.ServerCodec

func (*DefaultServerCodec) Notify

func (d *DefaultServerCodec) Notify(method string, args interface{}) error

func (*DefaultServerCodec) ReadRequestBody

func (c *DefaultServerCodec) ReadRequestBody(x interface{}) error

ReadRequestBody implements rpc.ServerCodec

func (*DefaultServerCodec) ReadRequestHeader

func (c *DefaultServerCodec) ReadRequestHeader(r *rpc.Request) (err error)

ReadRequestHeader implements rpc.ServerCodec

func (*DefaultServerCodec) WriteResponse

func (c *DefaultServerCodec) WriteResponse(r *rpc.Response, x interface{}) error

WriteResponse implements rpc.ServerCodec

type Notification

type Notification clientRequest

type Server

type Server struct {
	*rpc.Server
}

func NewServer

func NewServer() *Server

func (*Server) ServeCodec

func (s *Server) ServeCodec(codec rpc.ServerCodec)

func (*Server) ServeConn

func (s *Server) ServeConn(ctx context.Context, conn io.ReadWriteCloser)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL