update dependencies to work with update eth-block-extractor

This commit is contained in:
Ian Norden
2019-12-02 13:24:49 -06:00
parent 31a9017c4f
commit d702cb720c
3000 changed files with 433987 additions and 182448 deletions
+32
View File
@@ -0,0 +1,32 @@
os:
- linux
language: go
go:
- 1.11.x
env:
global:
- GOTFLAGS="-race"
matrix:
- BUILD_DEPTYPE=gx
- BUILD_DEPTYPE=gomod
# disable travis install
install:
- true
script:
- bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh)
cache:
directories:
- $GOPATH/src/gx
- $GOPATH/pkg/mod
- /home/travis/.cache/go-build
notifications:
email: false
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Jeromy Johnson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+13
View File
@@ -0,0 +1,13 @@
export IPFS_API ?= v04x.ipfs.io
gx:
go get github.com/whyrusleeping/gx
go get github.com/whyrusleeping/gx-go
deps: gx
gx --verbose install --global
gx-go rewrite
publish:
gx-go rewrite --undo
+153
View File
@@ -0,0 +1,153 @@
# go-multistream
[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io)
[![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)](https://github.com/multiformats/multiformats)
[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](https://webchat.freenode.net/?channels=%23ipfs)
[![](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)
[![GoDoc](https://godoc.org/github.com/multiformats/go-multistream?status.svg)](https://godoc.org/github.com/multiformats/go-multistream)
[![Travis CI](https://img.shields.io/travis/multiformats/go-multistream.svg?style=flat-square&branch=master)](https://travis-ci.org/multiformats/go-multistream)
[![codecov.io](https://img.shields.io/codecov/c/github/multiformats/go-multistream.svg?style=flat-square&branch=master)](https://codecov.io/github/multiformats/go-multistream?branch=master)
> an implementation of the multistream protocol in go
This package implements a simple stream router for the multistream-select protocol.
The protocol is defined [here](https://github.com/multiformats/multistream-select).
## Table of Contents
- [Install](#install)
- [Usage](#usage)
- [Maintainers](#maintainers)
- [Contribute](#contribute)
- [License](#license)
## Install
`go-multistream` is a standard Go module which can be installed with:
```sh
go get github.com/multiformats/go-multistream
```
Note that `go-multistream` is packaged with Gx, so it is recommended to use Gx to install and use it (see Usage section).
## Usage
### Using Gx and Gx-go
This module is packaged with [Gx](https://github.com/whyrusleeping/gx). In order to use it in your own project do:
```sh
go get -u github.com/whyrusleeping/gx
go get -u github.com/whyrusleeping/gx-go
cd <your-project-repository>
gx init
gx import github.com/multiformats/go-multistream
gx install --global
gx-go --rewrite
```
Please check [Gx](https://github.com/whyrusleeping/gx) and [Gx-go](https://github.com/whyrusleeping/gx-go) documentation for more information.
### Example
This example shows how to use a multistream muxer. A muxer uses user-added handlers to handle different "protocols". The first step when interacting with a connection handler by the muxer is to select the protocol (the example uses `SelectProtoOrFail`). This will then let the muxer use the right handler.
```go
package main
import (
"fmt"
"io"
"io/ioutil"
"net"
ms "github.com/multiformats/go-multistream"
)
// This example creates a multistream muxer, adds handlers for the protocols
// "/cats" and "/dogs" and exposes it on a localhost:8765. It then opens connections
// to that port, selects the protocols and tests that the handlers are working.
func main() {
mux := ms.NewMultistreamMuxer()
mux.AddHandler("/cats", func(proto string, rwc io.ReadWriteCloser) error {
fmt.Fprintln(rwc, proto, ": HELLO I LIKE CATS")
return rwc.Close()
})
mux.AddHandler("/dogs", func(proto string, rwc io.ReadWriteCloser) error {
fmt.Fprintln(rwc, proto, ": HELLO I LIKE DOGS")
return rwc.Close()
})
list, err := net.Listen("tcp", ":8765")
if err != nil {
panic(err)
}
go func() {
for {
con, err := list.Accept()
if err != nil {
panic(err)
}
go mux.Handle(con)
}
}()
// The Muxer is ready, let's test it
conn, err := net.Dial("tcp", ":8765")
if err != nil {
panic(err)
}
// Create a new multistream to talk to the muxer
// which will negotiate that we want to talk with /cats
mstream := ms.NewMSSelect(conn, "/cats")
cats, err := ioutil.ReadAll(mstream)
if err != nil {
panic(err)
}
fmt.Printf("%s", cats)
mstream.Close()
// A different way of talking to the muxer
// is to manually selecting the protocol ourselves
conn, err = net.Dial("tcp", ":8765")
if err != nil {
panic(err)
}
defer conn.Close()
err = ms.SelectProtoOrFail("/dogs", conn)
if err != nil {
panic(err)
}
dogs, err := ioutil.ReadAll(conn)
if err != nil {
panic(err)
}
fmt.Printf("%s", dogs)
conn.Close()
}
```
## Maintainers
Captain: [@whyrusleeping](https://github.com/whyrusleeping).
## Contribute
Contributions welcome. Please check out [the issues](https://github.com/multiformats/go-multistream/issues).
Check out our [contributing document](https://github.com/multiformats/multiformats/blob/master/contributing.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to multiformats are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).
Small note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.
## License
[MIT](LICENSE) © 2016 Jeromy Johnson
+87
View File
@@ -0,0 +1,87 @@
package multistream
import (
"errors"
"io"
)
// ErrNotSupported is the error returned when the muxer does not support
// the protocol specified for the handshake.
var ErrNotSupported = errors.New("protocol not supported")
// SelectProtoOrFail performs the initial multistream handshake
// to inform the muxer of the protocol that will be used to communicate
// on this ReadWriteCloser. It returns an error if, for example,
// the muxer does not know how to handle this protocol.
func SelectProtoOrFail(proto string, rwc io.ReadWriteCloser) error {
err := handshake(rwc)
if err != nil {
return err
}
return trySelect(proto, rwc)
}
// SelectOneOf will perform handshakes with the protocols on the given slice
// until it finds one which is supported by the muxer.
func SelectOneOf(protos []string, rwc io.ReadWriteCloser) (string, error) {
err := handshake(rwc)
if err != nil {
return "", err
}
for _, p := range protos {
err := trySelect(p, rwc)
switch err {
case nil:
return p, nil
case ErrNotSupported:
default:
return "", err
}
}
return "", ErrNotSupported
}
func handshake(rwc io.ReadWriteCloser) error {
errCh := make(chan error, 1)
go func() {
errCh <- delimWriteBuffered(rwc, []byte(ProtocolID))
}()
tok, readErr := ReadNextToken(rwc)
writeErr := <-errCh
if writeErr != nil {
return writeErr
}
if readErr != nil {
return readErr
}
if tok != ProtocolID {
return errors.New("received mismatch in protocol id")
}
return nil
}
func trySelect(proto string, rwc io.ReadWriteCloser) error {
err := delimWriteBuffered(rwc, []byte(proto))
if err != nil {
return err
}
tok, err := ReadNextToken(rwc)
if err != nil {
return err
}
switch tok {
case proto:
return nil
case "na":
return ErrNotSupported
default:
return errors.New("unrecognized response: " + tok)
}
}
+1
View File
@@ -0,0 +1 @@
module github.com/multiformats/go-multistream
+142
View File
@@ -0,0 +1,142 @@
package multistream
import (
"bufio"
"fmt"
"io"
"sync"
)
// Multistream represents in essense a ReadWriteCloser, or a single
// communication wire which supports multiple streams on it. Each
// stream is identified by a protocol tag.
type Multistream interface {
io.ReadWriteCloser
}
// NewMSSelect returns a new Multistream which is able to perform
// protocol selection with a MultistreamMuxer.
func NewMSSelect(c io.ReadWriteCloser, proto string) Multistream {
return &lazyClientConn{
protos: []string{ProtocolID, proto},
con: c,
}
}
// NewMultistream returns a multistream for the given protocol. This will not
// perform any protocol selection. If you are using a MultistreamMuxer, use
// NewMSSelect.
func NewMultistream(c io.ReadWriteCloser, proto string) Multistream {
return &lazyClientConn{
protos: []string{proto},
con: c,
}
}
// lazyClientConn is a ReadWriteCloser adapter that lazily negotiates a protocol
// using multistream-select on first use.
//
// It *does not* block writes waiting for the other end to respond. Instead, it
// simply assumes the negotiation went successfully and starts writing data.
// See: https://github.com/multiformats/go-multistream/issues/20
type lazyClientConn struct {
// Used to ensure we only trigger the write half of the handshake once.
rhandshakeOnce sync.Once
rerr error
// Used to ensure we only trigger the read half of the handshake once.
whandshakeOnce sync.Once
werr error
// The sequence of protocols to negotiate.
protos []string
// The inner connection.
con io.ReadWriteCloser
}
// Read reads data from the io.ReadWriteCloser.
//
// If the protocol hasn't yet been negotiated, this method triggers the write
// half of the handshake and then waits for the read half to complete.
//
// It returns an error if the read half of the handshake fails.
func (l *lazyClientConn) Read(b []byte) (int, error) {
l.rhandshakeOnce.Do(func() {
go l.whandshakeOnce.Do(l.doWriteHandshake)
l.doReadHandshake()
})
if l.rerr != nil {
return 0, l.rerr
}
if len(b) == 0 {
return 0, nil
}
return l.con.Read(b)
}
func (l *lazyClientConn) doReadHandshake() {
for _, proto := range l.protos {
// read protocol
tok, err := ReadNextToken(l.con)
if err != nil {
l.rerr = err
return
}
if tok != proto {
l.rerr = fmt.Errorf("protocol mismatch in lazy handshake ( %s != %s )", tok, proto)
return
}
}
}
func (l *lazyClientConn) doWriteHandshake() {
l.doWriteHandshakeWithData(nil)
}
// Perform the write handshake but *also* write some extra data.
func (l *lazyClientConn) doWriteHandshakeWithData(extra []byte) int {
buf := bufio.NewWriter(l.con)
for _, proto := range l.protos {
l.werr = delimWrite(buf, []byte(proto))
if l.werr != nil {
return 0
}
}
n := 0
if len(extra) > 0 {
n, l.werr = buf.Write(extra)
if l.werr != nil {
return n
}
}
l.werr = buf.Flush()
return n
}
// Write writes the given buffer to the underlying connection.
//
// If the protocol has not yet been negotiated, write waits for the write half
// of the handshake to complete triggers (but does not wait for) the read half.
//
// Write *also* ignores errors from the read half of the handshake (in case the
// stream is actually write only).
func (l *lazyClientConn) Write(b []byte) (int, error) {
n := 0
l.whandshakeOnce.Do(func() {
go l.rhandshakeOnce.Do(l.doReadHandshake)
n = l.doWriteHandshakeWithData(b)
})
if l.werr != nil || n > 0 {
return n, l.werr
}
return l.con.Write(b)
}
// Close closes the underlying io.ReadWriteCloser
func (l *lazyClientConn) Close() error {
return l.con.Close()
}
+37
View File
@@ -0,0 +1,37 @@
package multistream
import (
"io"
"sync"
)
// lazyServerConn is an io.ReadWriteCloser adapter used for negotiating inbound
// streams (see NegotiateLazy).
//
// This is "lazy" because it doesn't wait for the write half to succeed before
// allowing us to read from the stream.
type lazyServerConn struct {
waitForHandshake sync.Once
werr error
con io.ReadWriteCloser
}
func (l *lazyServerConn) Write(b []byte) (int, error) {
l.waitForHandshake.Do(func() { panic("didn't initiate handshake") })
if l.werr != nil {
return 0, l.werr
}
return l.con.Write(b)
}
func (l *lazyServerConn) Read(b []byte) (int, error) {
if len(b) == 0 {
return 0, nil
}
return l.con.Read(b)
}
func (l *lazyServerConn) Close() error {
return l.con.Close()
}
+440
View File
@@ -0,0 +1,440 @@
// Package multistream implements a simple stream router for the
// multistream-select protocoli. The protocol is defined at
// https://github.com/multiformats/multistream-select
package multistream
import (
"bufio"
"bytes"
"encoding/binary"
"errors"
"io"
"sync"
)
// ErrTooLarge is an error to signal that an incoming message was too large
var ErrTooLarge = errors.New("incoming message was too large")
// ProtocolID identifies the multistream protocol itself and makes sure
// the multistream muxers on both sides of a channel can work with each other.
const ProtocolID = "/multistream/1.0.0"
// HandlerFunc is a user-provided function used by the MultistreamMuxer to
// handle a protocol/stream.
type HandlerFunc func(protocol string, rwc io.ReadWriteCloser) error
// Handler is a wrapper to HandlerFunc which attaches a name (protocol) and a
// match function which can optionally be used to select a handler by other
// means than the name.
type Handler struct {
MatchFunc func(string) bool
Handle HandlerFunc
AddName string
}
// MultistreamMuxer is a muxer for multistream. Depending on the stream
// protocol tag it will select the right handler and hand the stream off to it.
type MultistreamMuxer struct {
handlerlock sync.Mutex
handlers []Handler
}
// NewMultistreamMuxer creates a muxer.
func NewMultistreamMuxer() *MultistreamMuxer {
return new(MultistreamMuxer)
}
func writeUvarint(w io.Writer, i uint64) error {
varintbuf := make([]byte, 16)
n := binary.PutUvarint(varintbuf, i)
_, err := w.Write(varintbuf[:n])
if err != nil {
return err
}
return nil
}
func delimWriteBuffered(w io.Writer, mes []byte) error {
bw := bufio.NewWriter(w)
err := delimWrite(bw, mes)
if err != nil {
return err
}
return bw.Flush()
}
func delimWrite(w io.Writer, mes []byte) error {
err := writeUvarint(w, uint64(len(mes)+1))
if err != nil {
return err
}
_, err = w.Write(mes)
if err != nil {
return err
}
_, err = w.Write([]byte{'\n'})
if err != nil {
return err
}
return nil
}
// Ls is a Multistream muxer command which returns the list of handler names
// available on a muxer.
func Ls(rw io.ReadWriter) ([]string, error) {
err := delimWriteBuffered(rw, []byte("ls"))
if err != nil {
return nil, err
}
n, err := binary.ReadUvarint(&byteReader{rw})
if err != nil {
return nil, err
}
var out []string
for i := uint64(0); i < n; i++ {
val, err := lpReadBuf(rw)
if err != nil {
return nil, err
}
out = append(out, string(val))
}
return out, nil
}
func fulltextMatch(s string) func(string) bool {
return func(a string) bool {
return a == s
}
}
// AddHandler attaches a new protocol handler to the muxer.
func (msm *MultistreamMuxer) AddHandler(protocol string, handler HandlerFunc) {
msm.AddHandlerWithFunc(protocol, fulltextMatch(protocol), handler)
}
// AddHandlerWithFunc attaches a new protocol handler to the muxer with a match.
// If the match function returns true for a given protocol tag, the protocol
// will be selected even if the handler name and protocol tags are different.
func (msm *MultistreamMuxer) AddHandlerWithFunc(protocol string, match func(string) bool, handler HandlerFunc) {
msm.handlerlock.Lock()
msm.removeHandler(protocol)
msm.handlers = append(msm.handlers, Handler{
MatchFunc: match,
Handle: handler,
AddName: protocol,
})
msm.handlerlock.Unlock()
}
// RemoveHandler removes the handler with the given name from the muxer.
func (msm *MultistreamMuxer) RemoveHandler(protocol string) {
msm.handlerlock.Lock()
defer msm.handlerlock.Unlock()
msm.removeHandler(protocol)
}
func (msm *MultistreamMuxer) removeHandler(protocol string) {
for i, h := range msm.handlers {
if h.AddName == protocol {
msm.handlers = append(msm.handlers[:i], msm.handlers[i+1:]...)
return
}
}
}
// Protocols returns the list of handler-names added to this this muxer.
func (msm *MultistreamMuxer) Protocols() []string {
var out []string
msm.handlerlock.Lock()
for _, h := range msm.handlers {
out = append(out, h.AddName)
}
msm.handlerlock.Unlock()
return out
}
// ErrIncorrectVersion is an error reported when the muxer protocol negotiation
// fails because of a ProtocolID mismatch.
var ErrIncorrectVersion = errors.New("client connected with incorrect version")
func (msm *MultistreamMuxer) findHandler(proto string) *Handler {
msm.handlerlock.Lock()
defer msm.handlerlock.Unlock()
for _, h := range msm.handlers {
if h.MatchFunc(proto) {
return &h
}
}
return nil
}
// NegotiateLazy performs protocol selection and returns
// a multistream, the protocol used, the handler and an error. It is lazy
// because the write-handshake is performed on a subroutine, allowing this
// to return before that handshake is completed.
func (msm *MultistreamMuxer) NegotiateLazy(rwc io.ReadWriteCloser) (Multistream, string, HandlerFunc, error) {
pval := make(chan string, 1)
writeErr := make(chan error, 1)
defer close(pval)
lzc := &lazyServerConn{
con: rwc,
}
started := make(chan struct{})
go lzc.waitForHandshake.Do(func() {
close(started)
defer close(writeErr)
if err := delimWriteBuffered(rwc, []byte(ProtocolID)); err != nil {
lzc.werr = err
writeErr <- err
return
}
for proto := range pval {
if err := delimWriteBuffered(rwc, []byte(proto)); err != nil {
lzc.werr = err
writeErr <- err
return
}
}
})
<-started
line, err := ReadNextToken(rwc)
if err != nil {
return nil, "", nil, err
}
if line != ProtocolID {
rwc.Close()
return nil, "", nil, ErrIncorrectVersion
}
loop:
for {
// Now read and respond to commands until they send a valid protocol id
tok, err := ReadNextToken(rwc)
if err != nil {
rwc.Close()
return nil, "", nil, err
}
switch tok {
case "ls":
select {
case pval <- "ls":
case err := <-writeErr:
rwc.Close()
return nil, "", nil, err
}
default:
h := msm.findHandler(tok)
if h == nil {
select {
case pval <- "na":
case err := <-writeErr:
rwc.Close()
return nil, "", nil, err
}
continue loop
}
select {
case pval <- tok:
case <-writeErr:
// explicitly ignore this error. It will be returned to any
// writers and if we don't plan on writing anything, we still
// want to complete the handshake
}
// hand off processing to the sub-protocol handler
return lzc, tok, h.Handle, nil
}
}
}
// Negotiate performs protocol selection and returns the protocol name and
// the matching handler function for it (or an error).
func (msm *MultistreamMuxer) Negotiate(rwc io.ReadWriteCloser) (string, HandlerFunc, error) {
// Send our protocol ID
err := delimWriteBuffered(rwc, []byte(ProtocolID))
if err != nil {
return "", nil, err
}
line, err := ReadNextToken(rwc)
if err != nil {
return "", nil, err
}
if line != ProtocolID {
rwc.Close()
return "", nil, ErrIncorrectVersion
}
loop:
for {
// Now read and respond to commands until they send a valid protocol id
tok, err := ReadNextToken(rwc)
if err != nil {
return "", nil, err
}
switch tok {
case "ls":
err := msm.Ls(rwc)
if err != nil {
return "", nil, err
}
default:
h := msm.findHandler(tok)
if h == nil {
err := delimWriteBuffered(rwc, []byte("na"))
if err != nil {
return "", nil, err
}
continue loop
}
err := delimWriteBuffered(rwc, []byte(tok))
if err != nil {
return "", nil, err
}
// hand off processing to the sub-protocol handler
return tok, h.Handle, nil
}
}
}
// Ls implements the "ls" command which writes the list of
// supported protocols to the given Writer.
func (msm *MultistreamMuxer) Ls(w io.Writer) error {
buf := new(bytes.Buffer)
msm.handlerlock.Lock()
err := writeUvarint(buf, uint64(len(msm.handlers)))
if err != nil {
return err
}
for _, h := range msm.handlers {
err := delimWrite(buf, []byte(h.AddName))
if err != nil {
msm.handlerlock.Unlock()
return err
}
}
msm.handlerlock.Unlock()
ll := make([]byte, 16)
nw := binary.PutUvarint(ll, uint64(buf.Len()))
r := io.MultiReader(bytes.NewReader(ll[:nw]), buf)
_, err = io.Copy(w, r)
return err
}
// Handle performs protocol negotiation on a ReadWriteCloser
// (i.e. a connection). It will find a matching handler for the
// incoming protocol and pass the ReadWriteCloser to it.
func (msm *MultistreamMuxer) Handle(rwc io.ReadWriteCloser) error {
p, h, err := msm.Negotiate(rwc)
if err != nil {
return err
}
return h(p, rwc)
}
// ReadNextToken extracts a token from a ReadWriter. It is used during
// protocol negotiation and returns a string.
func ReadNextToken(rw io.ReadWriter) (string, error) {
tok, err := ReadNextTokenBytes(rw)
if err != nil {
return "", err
}
return string(tok), nil
}
// ReadNextTokenBytes extracts a token from a ReadWriter. It is used
// during protocol negotiation and returns a byte slice.
func ReadNextTokenBytes(rw io.ReadWriter) ([]byte, error) {
data, err := lpReadBuf(rw)
switch err {
case nil:
return data, nil
case ErrTooLarge:
err := delimWriteBuffered(rw, []byte("messages over 64k are not allowed"))
if err != nil {
return nil, err
}
return nil, ErrTooLarge
default:
return nil, err
}
}
func lpReadBuf(r io.Reader) ([]byte, error) {
br, ok := r.(io.ByteReader)
if !ok {
br = &byteReader{r}
}
length, err := binary.ReadUvarint(br)
if err != nil {
return nil, err
}
if length > 64*1024 {
return nil, ErrTooLarge
}
buf := make([]byte, length)
_, err = io.ReadFull(r, buf)
if err != nil {
return nil, err
}
if len(buf) == 0 || buf[length-1] != '\n' {
return nil, errors.New("message did not have trailing newline")
}
// slice off the trailing newline
buf = buf[:length-1]
return buf, nil
}
// byteReader implements the ByteReader interface that ReadUVarint requires
type byteReader struct {
io.Reader
}
func (br *byteReader) ReadByte() (byte, error) {
var b [1]byte
n, err := br.Read(b[:])
if n == 1 {
return b[0], nil
}
if err == nil {
if n != 0 {
panic("read more bytes than buffer size")
}
err = io.ErrNoProgress
}
return 0, err
}
+16
View File
@@ -0,0 +1,16 @@
{
"author": "whyrusleeping",
"bugs": {
"url": "https://github.com/multiformats/go-multistream"
},
"gx": {
"dvcsimport": "github.com/multiformats/go-multistream"
},
"gxVersion": "0.7.0",
"language": "go",
"license": "",
"name": "go-multistream",
"releaseCmd": "git commit -a -m \"gx publish $VERSION\"",
"version": "0.3.9"
}