antelope_ship_client

package module
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Jan 17, 2023 License: MIT Imports: 6 Imported by: 2

README

Antelope SHIP Client

Test Go Reference

Client Implementation of Antelope state-history websocket.

Install package
go get -u github.com/eosswedenorg-go/antelope-ship-client@latest
Documentation

Documentation can be found over at pkg.go.dev

Examples
Author

Henrik Hautakoski - Sw/eden - henrik@eossweden.org

Documentation

Overview

Callback functions

This library uses callback functions to allow the users to execute the code needed when certain events are triggered.

the Client struct accepts the following callback functions

InitHandler func(*eos.ABI)

Called when the client receives the first message from the SHIP node on connection. This message contains the abi with all the information about the functions/types exposed by the websocket api.

BlockHandler func(*ship.GetBlocksResultV0)

Called when the client reveives a block message from the server.

TraceHandler func([]*ship.TransactionTraceV0)

When the client reveives a block message from the server and the Block has any traces attached to it. these traces are then passed to this callback.

StatusHandler func(*ship.GetStatusResultV0)

Called when the client reveives a status message.

CloseHandler func()

Called when a client has closed the socket connection (in `(*ShipClient) Close()` function)

Example (Basic)
package main

import (
	"context"
	"log"
	"os"
	"os/signal"
	"time"

	eos "github.com/eoscanada/eos-go"
	"github.com/eoscanada/eos-go/ship"
	shipclient "github.com/eosswedenorg-go/antelope-ship-client"
)

// -----------------------------
//  Config variables
// -----------------------------

// IP and port to the ship node.
var shipHost string = "127.0.0.1:8089"

// Url to the antelope api on the same node as ship is running.
// Use this to fetch a sane value for `startBlock`
var APIURL string // = "http://127.0.0.1:8088"

// If `APIURL` is not set, this is the block
// where we request ship to start sending blocks from.
// This should be something other than zero. check a block explorer or /v1/chain/get_info for the latest block number.
// or use APIURL to make the code fetch it itself.
var startBlock uint32 = 0

// True if the client should request a status message from the ship server on startup.
var sendStatus bool = true

// True if traces should be printed (this can get spammy)
var printTraces bool = false

func initHandler(abi *eos.ABI) {
	log.Println("Server abi:", abi.Version)
}

func processBlock(block *ship.GetBlocksResultV0) {
	if block.ThisBlock.BlockNum%100 == 0 {
		log.Printf("Current: %d, Head: %d\n", block.ThisBlock.BlockNum, block.Head.BlockNum)
	}
}

func processTraces(traces []*ship.TransactionTraceV0) {
	for _, trace := range traces {
		log.Println("Trace ID:", trace.ID)
	}
}

func processStatus(status *ship.GetStatusResultV0) {
	log.Println("-- Status --")
	log.Println("Head", status.Head.BlockNum, status.Head.BlockID)
	log.Println("ChainStateBeginBlock", status.ChainStateBeginBlock, "ChainStateEndBlock", status.ChainStateEndBlock)
}

func main() {
	// Create done and interrupt channels.
	done := make(chan bool)
	interrupt := make(chan os.Signal, 1)

	// Register interrupt channel to receive interrupt messages
	signal.Notify(interrupt, os.Interrupt)

	// Get start block from chain info
	if APIURL != "" {
		chainInfo, err := eos.New(APIURL).GetInfo(context.Background())
		if err == nil {
			startBlock = chainInfo.HeadBlockNum
		} else {
			log.Println("Failed to get info:", err)
			return
		}
	}

	log.Println("Connecting to ship starting at block:", startBlock)

	client := shipclient.NewClient(shipclient.WithStartBlock(startBlock))
	client.InitHandler = initHandler
	client.BlockHandler = processBlock
	client.StatusHandler = processStatus

	// Only assign trace handler if printTraces is true.
	if printTraces {
		client.TraceHandler = processTraces
	}

	// Connect to SHIP client
	err := client.Connect(shipHost)
	if err != nil {
		log.Println(err)
		return
	}

	// Request streaming of blocks from ship
	err = client.SendBlocksRequest()
	if err != nil {
		log.Println(err)
		return
	}

	// Request status message from ship
	if sendStatus {
		err = client.SendStatusRequest()
		if err != nil {
			log.Println(err)
			return
		}
	}

	// Spawn message read loop in another thread.
	go func() {
		for {
			err := client.Read()
			if err != nil {
				log.Print(err)

				if e, ok := err.(shipclient.ShipClientError); ok {
					if e.Type == shipclient.ErrSockRead {
						break
					}
				}
			}
		}

		client.Close()

		// Client exited. signal that we are done.
		done <- true
	}()

	// Enter event loop in main thread
	for {
		select {
		case <-interrupt:
			log.Println("Interrupt, closing")

			// Cleanly close the connection by sending a close message and then
			// waiting (with timeout) for the server to close the connection.
			err := client.SendCloseMessage()
			if err != nil {
				log.Println("Failed to send close message", err)
			}

			select {
			case <-done:
				log.Println("Closed")
			case <-time.After(time.Second * 4):
				log.Println("Timeout")
			}
			return
		case <-done:
			log.Println("Closed")
			return
		}
	}
}

Index

Examples

Constants

View Source
const (
	ErrNotConnected = iota
	ErrSockRead
	ErrSockClosed
	ErrSendClose
	ErrACK
	ErrParse
)
View Source
const NULL_BLOCK_NUMBER uint32 = 0xffffffff

Variables

This section is empty.

Functions

This section is empty.

Types

type BlockFn added in v0.2.1

type BlockFn func(*ship.GetBlocksResultV0)

type Client added in v0.2.1

type Client struct {

	// Block to start receiving notifications on.
	StartBlock uint32

	// Block to end receiving notifications on.
	EndBlock uint32

	// if only irreversible blocks should be sent.
	IrreversibleOnly bool

	// Max number of non-ACKed messages that may be sent.
	MaxMessagesInFlight uint32

	// Callback functions
	InitHandler   InitFn
	BlockHandler  BlockFn
	TraceHandler  TraceFn
	StatusHandler StatusFn
	CloseHandler  CloseFn
	// contains filtered or unexported fields
}

func NewClient

func NewClient(options ...Option) *Client

Create a new client

func (*Client) Close added in v0.2.1

func (c *Client) Close() error

Close the socket on the client side.

NOTE: This method closes the underlying network connection without sending or waiting for a close message.

func (*Client) Connect added in v0.2.1

func (c *Client) Connect(host string) error

Connect the client to a ship node

Returns an error if the connection fails, nil otherwise.

NOTE: this is equivalent to calling

c.ConnectURL(url.URL{Scheme: "ws", Host: host, Path: "/"})

func (*Client) ConnectURL added in v0.2.1

func (c *Client) ConnectURL(url url.URL) error

Connect the client to a ship node

Returns an error if the connection fails, nil otherwise.

func (*Client) IsOpen added in v0.2.1

func (c *Client) IsOpen() bool

Returns true if the websocket connection is open. false otherwise.

func (*Client) Read added in v0.2.1

func (c *Client) Read() error

Read messages from the client and calls the appropriate callback function.

This function will block until atleast one valid message is processed or an error occured.

func (*Client) ReadRaw added in v0.2.1

func (c *Client) ReadRaw() (int, []byte, error)

func (*Client) SendACK added in v0.2.1

func (c *Client) SendACK() error

Sends an Acknowledgment message that tells th server that we have received X number of messages where X is the number returned by c.UnconfirmedMessages().

This is normally called internally by Read() So only use this manually if you know that you need to.

func (*Client) SendBlocksRequest added in v0.2.1

func (c *Client) SendBlocksRequest() error

Send a blocks request to the ship server. This tells the server to start sending block message to the client.

func (*Client) SendCloseMessage added in v0.2.1

func (c *Client) SendCloseMessage() error

Sends a close message to the server indicating that the client wants to terminate the connection.

func (*Client) SendStatusRequest added in v0.2.1

func (c *Client) SendStatusRequest() error

Send a status request to the ship server. This tells the server to start sending status message to the client.

func (Client) UnconfirmedMessages added in v0.2.1

func (c Client) UnconfirmedMessages() uint32

Returns the number of messages the client has received but have not yet been confirmed as having been received by the client

type CloseFn added in v0.2.1

type CloseFn func()

type InitFn added in v0.2.1

type InitFn func(*eos.ABI)

type Option added in v0.2.1

type Option func(*Client)

func WithBlockHandler added in v0.2.1

func WithBlockHandler(value BlockFn) Option

Option to set Client.BlockHandler

func WithCloseHandler added in v0.2.1

func WithCloseHandler(value CloseFn) Option

Option to set Client.CloseHandler

func WithEndBlock added in v0.2.1

func WithEndBlock(value uint32) Option

Option to set Client.EndBlock

func WithInitHandler added in v0.2.1

func WithInitHandler(value InitFn) Option

Option to set Client.InitHandler

func WithIrreversibleOnly added in v0.2.1

func WithIrreversibleOnly(value bool) Option

Option to set Client.IrreversibleOnly

func WithMaxMessagesInFlight added in v0.2.1

func WithMaxMessagesInFlight(value uint32) Option

Option to set Client.MaxMessagesInFlight

func WithStartBlock added in v0.2.1

func WithStartBlock(value uint32) Option

Option to set Client.StartBlock

func WithStatusHandler added in v0.2.1

func WithStatusHandler(value StatusFn) Option

Option to set Client.StatusHandler

func WithTraceHandler added in v0.2.1

func WithTraceHandler(value TraceFn) Option

Option to set Client.TraceHandler

type ShipClientError

type ShipClientError struct {
	Type int
	Text string
}

func (ShipClientError) Error

func (e ShipClientError) Error() string

type StatusFn added in v0.2.1

type StatusFn func(*ship.GetStatusResultV0)

type TraceFn added in v0.2.1

type TraceFn func([]*ship.TransactionTraceV0)

Jump to

Keyboard shortcuts

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