Integrate BACKBEAT SDK and resolve KACHING license validation

Major integrations and fixes:
- Added BACKBEAT SDK integration for P2P operation timing
- Implemented beat-aware status tracking for distributed operations
- Added Docker secrets support for secure license management
- Resolved KACHING license validation via HTTPS/TLS
- Updated docker-compose configuration for clean stack deployment
- Disabled rollback policies to prevent deployment failures
- Added license credential storage (CHORUS-DEV-MULTI-001)

Technical improvements:
- BACKBEAT P2P operation tracking with phase management
- Enhanced configuration system with file-based secrets
- Improved error handling for license validation
- Clean separation of KACHING and CHORUS deployment stacks

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
anthonyrawlins
2025-09-06 07:56:26 +10:00
parent 543ab216f9
commit 9bdcbe0447
4730 changed files with 1480093 additions and 1916 deletions

21
vendor/github.com/libp2p/go-msgio/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Juan Batiz-Benet
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.

70
vendor/github.com/libp2p/go-msgio/README.md generated vendored Normal file
View File

@@ -0,0 +1,70 @@
# go-msgio - Message IO
[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai)
[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/)
[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p)
[![codecov](https://codecov.io/gh/libp2p/go-libp2p-netutil/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-msgio)
[![Travis CI](https://travis-ci.org/libp2p/go-libp2p-netutil.svg?branch=master)](https://travis-ci.org/libp2p/go-msgio)
[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io)
This is a simple package that helps read and write length-delimited slices. It's helpful for building wire protocols.
## Usage
### Reading
```go
import "github.com/libp2p/go-msgio"
rdr := ... // some reader from a wire
mrdr := msgio.NewReader(rdr)
for {
msg, err := mrdr.ReadMsg()
if err != nil {
return err
}
doSomething(msg)
}
```
### Writing
```go
import "github.com/libp2p/go-msgio"
wtr := genReader()
mwtr := msgio.NewWriter(wtr)
for {
msg := genMessage()
err := mwtr.WriteMsg(msg)
if err != nil {
return err
}
}
```
### Duplex
```go
import "github.com/libp2p/go-msgio"
rw := genReadWriter()
mrw := msgio.NewReadWriter(rw)
for {
msg, err := mrdr.ReadMsg()
if err != nil {
return err
}
// echo it back :)
err = mwtr.WriteMsg(msg)
if err != nil {
return err
}
}
```
---
The last gx published version of this module was: 0.0.6: QmcxL9MDzSU5Mj1GcWZD8CXkAFuJXjdbjotZ93o371bKSf

23
vendor/github.com/libp2p/go-msgio/fuzz.go generated vendored Normal file
View File

@@ -0,0 +1,23 @@
//go:build gofuzz
package msgio
import "bytes"
// get the go-fuzz tools and build a fuzzer
// $ go get -u github.com/dvyukov/go-fuzz/...
// $ go-fuzz-build github.com/libp2p/go-msgio
// put a corpus of random (even better if actual, structured) data in a corpus directry
// $ go-fuzz -bin ./msgio-fuzz -corpus corpus -workdir=wdir -timeout=15
func Fuzz(data []byte) int {
rc := NewReader(bytes.NewReader(data))
// rc := NewVarintReader(bytes.NewReader(data))
if _, err := rc.ReadMsg(); err != nil {
return 0
}
return 1
}

45
vendor/github.com/libp2p/go-msgio/limit.go generated vendored Normal file
View File

@@ -0,0 +1,45 @@
package msgio
import (
"bytes"
"io"
"sync"
)
// LimitedReader wraps an io.Reader with a msgio framed reader. The LimitedReader
// will return a reader which will io.EOF when the msg length is done.
func LimitedReader(r io.Reader) (io.Reader, error) {
l, err := ReadLen(r, nil)
return io.LimitReader(r, int64(l)), err
}
// LimitedWriter wraps an io.Writer with a msgio framed writer. It is the inverse
// of LimitedReader: it will buffer all writes until "Flush" is called. When Flush
// is called, it will write the size of the buffer first, flush the buffer, reset
// the buffer, and begin accept more incoming writes.
func NewLimitedWriter(w io.Writer) *LimitedWriter {
return &LimitedWriter{W: w}
}
type LimitedWriter struct {
W io.Writer
B bytes.Buffer
M sync.Mutex
}
func (w *LimitedWriter) Write(buf []byte) (n int, err error) {
w.M.Lock()
n, err = w.B.Write(buf)
w.M.Unlock()
return n, err
}
func (w *LimitedWriter) Flush() error {
w.M.Lock()
defer w.M.Unlock()
if err := WriteLen(w.W, w.B.Len()); err != nil {
return err
}
_, err := w.B.WriteTo(w.W)
return err
}

305
vendor/github.com/libp2p/go-msgio/msgio.go generated vendored Normal file
View File

@@ -0,0 +1,305 @@
package msgio
import (
"errors"
"io"
"sync"
pool "github.com/libp2p/go-buffer-pool"
)
// ErrMsgTooLarge is returned when the message length is exessive
var ErrMsgTooLarge = errors.New("message too large")
const (
lengthSize = 4
defaultMaxSize = 8 * 1024 * 1024 // 8mb
)
// Writer is the msgio Writer interface. It writes len-framed messages.
type Writer interface {
// Write writes passed in buffer as a single message.
Write([]byte) (int, error)
// WriteMsg writes the msg in the passed in buffer.
WriteMsg([]byte) error
}
// WriteCloser is a Writer + Closer interface. Like in `golang/pkg/io`
type WriteCloser interface {
Writer
io.Closer
}
// Reader is the msgio Reader interface. It reads len-framed messages.
type Reader interface {
// Read reads the next message from the Reader.
// The client must pass a buffer large enough, or io.ErrShortBuffer will be
// returned.
Read([]byte) (int, error)
// ReadMsg reads the next message from the Reader.
// Uses a pool.BufferPool internally to reuse buffers. User may call
// ReleaseMsg(msg) to signal a buffer can be reused.
ReadMsg() ([]byte, error)
// ReleaseMsg signals a buffer can be reused.
ReleaseMsg([]byte)
// NextMsgLen returns the length of the next (peeked) message. Does
// not destroy the message or have other adverse effects
NextMsgLen() (int, error)
}
// ReadCloser combines a Reader and Closer.
type ReadCloser interface {
Reader
io.Closer
}
// ReadWriter combines a Reader and Writer.
type ReadWriter interface {
Reader
Writer
}
// ReadWriteCloser combines a Reader, a Writer, and Closer.
type ReadWriteCloser interface {
Reader
Writer
io.Closer
}
// writer is the underlying type that implements the Writer interface.
type writer struct {
W io.Writer
pool *pool.BufferPool
lock sync.Mutex
}
// NewWriter wraps an io.Writer with a msgio framed writer. The msgio.Writer
// will write the length prefix of every message written.
func NewWriter(w io.Writer) WriteCloser {
return NewWriterWithPool(w, pool.GlobalPool)
}
// NewWriterWithPool is identical to NewWriter but allows the user to pass a
// custom buffer pool.
func NewWriterWithPool(w io.Writer, p *pool.BufferPool) WriteCloser {
return &writer{W: w, pool: p}
}
func (s *writer) Write(msg []byte) (int, error) {
err := s.WriteMsg(msg)
if err != nil {
return 0, err
}
return len(msg), nil
}
func (s *writer) WriteMsg(msg []byte) (err error) {
s.lock.Lock()
defer s.lock.Unlock()
buf := s.pool.Get(len(msg) + lengthSize)
NBO.PutUint32(buf, uint32(len(msg)))
copy(buf[lengthSize:], msg)
_, err = s.W.Write(buf)
s.pool.Put(buf)
return err
}
func (s *writer) Close() error {
if c, ok := s.W.(io.Closer); ok {
return c.Close()
}
return nil
}
// reader is the underlying type that implements the Reader interface.
type reader struct {
R io.Reader
lbuf [lengthSize]byte
next int
pool *pool.BufferPool
lock sync.Mutex
max int // the maximal message size (in bytes) this reader handles
}
// NewReader wraps an io.Reader with a msgio framed reader. The msgio.Reader
// will read whole messages at a time (using the length). Assumes an equivalent
// writer on the other side.
func NewReader(r io.Reader) ReadCloser {
return NewReaderWithPool(r, pool.GlobalPool)
}
// NewReaderSize is equivalent to NewReader but allows one to
// specify a max message size.
func NewReaderSize(r io.Reader, maxMessageSize int) ReadCloser {
return NewReaderSizeWithPool(r, maxMessageSize, pool.GlobalPool)
}
// NewReaderWithPool is the same as NewReader but allows one to specify a buffer
// pool.
func NewReaderWithPool(r io.Reader, p *pool.BufferPool) ReadCloser {
return NewReaderSizeWithPool(r, defaultMaxSize, p)
}
// NewReaderWithPool is the same as NewReader but allows one to specify a buffer
// pool and a max message size.
func NewReaderSizeWithPool(r io.Reader, maxMessageSize int, p *pool.BufferPool) ReadCloser {
if p == nil {
panic("nil pool")
}
return &reader{
R: r,
next: -1,
pool: p,
max: maxMessageSize,
}
}
// NextMsgLen reads the length of the next msg into s.lbuf, and returns it.
// WARNING: like Read, NextMsgLen is destructive. It reads from the internal
// reader.
func (s *reader) NextMsgLen() (int, error) {
s.lock.Lock()
defer s.lock.Unlock()
return s.nextMsgLen()
}
func (s *reader) nextMsgLen() (int, error) {
if s.next == -1 {
n, err := ReadLen(s.R, s.lbuf[:])
if err != nil {
return 0, err
}
s.next = n
}
return s.next, nil
}
func (s *reader) Read(msg []byte) (int, error) {
s.lock.Lock()
defer s.lock.Unlock()
length, err := s.nextMsgLen()
if err != nil {
return 0, err
}
if length > len(msg) {
return 0, io.ErrShortBuffer
}
read, err := io.ReadFull(s.R, msg[:length])
if read < length {
s.next = length - read // we only partially consumed the message.
} else {
s.next = -1 // signal we've consumed this msg
}
return read, err
}
func (s *reader) ReadMsg() ([]byte, error) {
s.lock.Lock()
defer s.lock.Unlock()
length, err := s.nextMsgLen()
if err != nil {
return nil, err
}
if length == 0 {
s.next = -1
return nil, nil
}
if length > s.max || length < 0 {
return nil, ErrMsgTooLarge
}
msg := s.pool.Get(length)
read, err := io.ReadFull(s.R, msg)
if read < length {
s.next = length - read // we only partially consumed the message.
} else {
s.next = -1 // signal we've consumed this msg
}
return msg[:read], err
}
func (s *reader) ReleaseMsg(msg []byte) {
s.pool.Put(msg)
}
func (s *reader) Close() error {
if c, ok := s.R.(io.Closer); ok {
return c.Close()
}
return nil
}
// readWriter is the underlying type that implements a ReadWriter.
type readWriter struct {
Reader
Writer
}
// NewReadWriter wraps an io.ReadWriter with a msgio.ReadWriter. Writing
// and Reading will be appropriately framed.
func NewReadWriter(rw io.ReadWriter) ReadWriteCloser {
return &readWriter{
Reader: NewReader(rw),
Writer: NewWriter(rw),
}
}
// Combine wraps a pair of msgio.Writer and msgio.Reader with a msgio.ReadWriter.
func Combine(w Writer, r Reader) ReadWriteCloser {
return &readWriter{Reader: r, Writer: w}
}
func (rw *readWriter) Close() error {
var errs []error
if w, ok := rw.Writer.(WriteCloser); ok {
if err := w.Close(); err != nil {
errs = append(errs, err)
}
}
if r, ok := rw.Reader.(ReadCloser); ok {
if err := r.Close(); err != nil {
errs = append(errs, err)
}
}
if len(errs) > 0 {
return multiErr(errs)
}
return nil
}
// multiErr is a util to return multiple errors
type multiErr []error
func (m multiErr) Error() string {
if len(m) == 0 {
return "no errors"
}
s := "Multiple errors: "
for i, e := range m {
if i != 0 {
s += ", "
}
s += e.Error()
}
return s
}

34
vendor/github.com/libp2p/go-msgio/num.go generated vendored Normal file
View File

@@ -0,0 +1,34 @@
package msgio
import (
"encoding/binary"
"io"
)
// NBO is NetworkByteOrder
var NBO = binary.BigEndian
// WriteLen writes a length to the given writer.
func WriteLen(w io.Writer, l int) error {
ul := uint32(l)
return binary.Write(w, NBO, &ul)
}
// ReadLen reads a length from the given reader.
// if buf is non-nil, it reuses the buffer. Ex:
//
// l, err := ReadLen(r, nil)
// _, err := ReadLen(r, buf)
func ReadLen(r io.Reader, buf []byte) (int, error) {
if len(buf) < 4 {
buf = make([]byte, 4)
}
buf = buf[:4]
if _, err := io.ReadFull(r, buf); err != nil {
return 0, err
}
n := int(NBO.Uint32(buf))
return n, nil
}

40
vendor/github.com/libp2p/go-msgio/pbio/interfaces.go generated vendored Normal file
View File

@@ -0,0 +1,40 @@
// Package pbio reads and writes varint-prefix protobufs, using Google's Protobuf package.
package pbio
import (
"io"
"google.golang.org/protobuf/proto"
)
type Writer interface {
WriteMsg(proto.Message) error
}
type WriteCloser interface {
Writer
io.Closer
}
type Reader interface {
ReadMsg(msg proto.Message) error
}
type ReadCloser interface {
Reader
io.Closer
}
func getSize(v interface{}) (int, bool) {
if sz, ok := v.(interface {
Size() (n int)
}); ok {
return sz.Size(), true
} else if sz, ok := v.(interface {
ProtoSize() (n int)
}); ok {
return sz.ProtoSize(), true
} else {
return 0, false
}
}

View File

@@ -0,0 +1,93 @@
// Adapted from gogo/protobuf to use multiformats/go-varint for
// efficient, interoperable length-prefixing.
//
// # Protocol Buffers for Go with Gadgets
//
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
// http://github.com/gogo/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// - Redistributions of source code must retain the above copyright
//
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above
//
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package pbio
import (
"bufio"
"fmt"
"io"
"os"
"runtime/debug"
"google.golang.org/protobuf/proto"
"github.com/multiformats/go-varint"
)
type uvarintReader struct {
r *bufio.Reader
buf []byte
maxSize int
closer io.Closer
}
func NewDelimitedReader(r io.Reader, maxSize int) ReadCloser {
var closer io.Closer
if c, ok := r.(io.Closer); ok {
closer = c
}
return &uvarintReader{bufio.NewReader(r), nil, maxSize, closer}
}
func (ur *uvarintReader) ReadMsg(msg proto.Message) (err error) {
defer func() {
if rerr := recover(); rerr != nil {
fmt.Fprintf(os.Stderr, "caught panic: %s\n%s\n", rerr, debug.Stack())
err = fmt.Errorf("panic reading message: %s", rerr)
}
}()
length64, err := varint.ReadUvarint(ur.r)
if err != nil {
return err
}
length := int(length64)
if length < 0 || length > ur.maxSize {
return io.ErrShortBuffer
}
if len(ur.buf) < length {
ur.buf = make([]byte, length)
}
buf := ur.buf[:length]
if _, err := io.ReadFull(ur.r, buf); err != nil {
return err
}
return proto.Unmarshal(buf, msg)
}
func (ur *uvarintReader) Close() error {
if ur.closer != nil {
return ur.closer.Close()
}
return nil
}

View File

@@ -0,0 +1,103 @@
// Adapted from gogo/protobuf to use multiformats/go-varint for
// efficient, interoperable length-prefixing.
//
// # Protocol Buffers for Go with Gadgets
//
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
// http://github.com/gogo/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// - Redistributions of source code must retain the above copyright
//
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above
//
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package pbio
import (
"fmt"
"io"
"os"
"runtime/debug"
"google.golang.org/protobuf/proto"
"github.com/multiformats/go-varint"
)
type uvarintWriter struct {
w io.Writer
lenBuf []byte
buffer []byte
}
func NewDelimitedWriter(w io.Writer) WriteCloser {
return &uvarintWriter{w, make([]byte, varint.MaxLenUvarint63), nil}
}
func (uw *uvarintWriter) WriteMsg(msg proto.Message) (err error) {
defer func() {
if rerr := recover(); rerr != nil {
fmt.Fprintf(os.Stderr, "caught panic: %s\n%s\n", rerr, debug.Stack())
err = fmt.Errorf("panic reading message: %s", rerr)
}
}()
var data []byte
if m, ok := msg.(interface {
MarshalTo(data []byte) (n int, err error)
}); ok {
n, ok := getSize(m)
if ok {
if n+varint.MaxLenUvarint63 >= len(uw.buffer) {
uw.buffer = make([]byte, n+varint.MaxLenUvarint63)
}
lenOff := varint.PutUvarint(uw.buffer, uint64(n))
_, err = m.MarshalTo(uw.buffer[lenOff:])
if err != nil {
return err
}
_, err = uw.w.Write(uw.buffer[:lenOff+n])
return err
}
}
// fallback
data, err = proto.Marshal(msg)
if err != nil {
return err
}
length := uint64(len(data))
n := varint.PutUvarint(uw.lenBuf, length)
_, err = uw.w.Write(uw.lenBuf[:n])
if err != nil {
return err
}
_, err = uw.w.Write(data)
return err
}
func (uw *uvarintWriter) Close() error {
if closer, ok := uw.w.(io.Closer); ok {
return closer.Close()
}
return nil
}

View File

@@ -0,0 +1,73 @@
// Adapted from gogo/protobuf to use multiformats/go-varint for
// efficient, interoperable length-prefixing.
//
// # Protocol Buffers for Go with Gadgets
//
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
// http://github.com/gogo/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// - Redistributions of source code must retain the above copyright
//
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above
//
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Deprecated: GoGo Protobuf is deprecated and unmaintained.
package protoio
import (
"io"
"github.com/gogo/protobuf/proto"
)
type Writer interface {
WriteMsg(proto.Message) error
}
type WriteCloser interface {
Writer
io.Closer
}
type Reader interface {
ReadMsg(msg proto.Message) error
}
type ReadCloser interface {
Reader
io.Closer
}
func getSize(v interface{}) (int, bool) {
if sz, ok := v.(interface {
Size() (n int)
}); ok {
return sz.Size(), true
} else if sz, ok := v.(interface {
ProtoSize() (n int)
}); ok {
return sz.ProtoSize(), true
} else {
return 0, false
}
}

View File

@@ -0,0 +1,93 @@
// Adapted from gogo/protobuf to use multiformats/go-varint for
// efficient, interoperable length-prefixing.
//
// # Protocol Buffers for Go with Gadgets
//
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
// http://github.com/gogo/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// - Redistributions of source code must retain the above copyright
//
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above
//
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package protoio
import (
"bufio"
"fmt"
"io"
"os"
"runtime/debug"
"github.com/gogo/protobuf/proto"
"github.com/multiformats/go-varint"
)
type uvarintReader struct {
r *bufio.Reader
buf []byte
maxSize int
closer io.Closer
}
func NewDelimitedReader(r io.Reader, maxSize int) ReadCloser {
var closer io.Closer
if c, ok := r.(io.Closer); ok {
closer = c
}
return &uvarintReader{bufio.NewReader(r), nil, maxSize, closer}
}
func (ur *uvarintReader) ReadMsg(msg proto.Message) (err error) {
defer func() {
if rerr := recover(); rerr != nil {
fmt.Fprintf(os.Stderr, "caught panic: %s\n%s\n", rerr, debug.Stack())
err = fmt.Errorf("panic reading message: %s", rerr)
}
}()
length64, err := varint.ReadUvarint(ur.r)
if err != nil {
return err
}
length := int(length64)
if length < 0 || length > ur.maxSize {
return io.ErrShortBuffer
}
if len(ur.buf) < length {
ur.buf = make([]byte, length)
}
buf := ur.buf[:length]
if _, err := io.ReadFull(ur.r, buf); err != nil {
return err
}
return proto.Unmarshal(buf, msg)
}
func (ur *uvarintReader) Close() error {
if ur.closer != nil {
return ur.closer.Close()
}
return nil
}

View File

@@ -0,0 +1,103 @@
// Adapted from gogo/protobuf to use multiformats/go-varint for
// efficient, interoperable length-prefixing.
//
// # Protocol Buffers for Go with Gadgets
//
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
// http://github.com/gogo/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// - Redistributions of source code must retain the above copyright
//
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above
//
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package protoio
import (
"fmt"
"io"
"os"
"runtime/debug"
"github.com/gogo/protobuf/proto"
"github.com/multiformats/go-varint"
)
type uvarintWriter struct {
w io.Writer
lenBuf []byte
buffer []byte
}
func NewDelimitedWriter(w io.Writer) WriteCloser {
return &uvarintWriter{w, make([]byte, varint.MaxLenUvarint63), nil}
}
func (uw *uvarintWriter) WriteMsg(msg proto.Message) (err error) {
defer func() {
if rerr := recover(); rerr != nil {
fmt.Fprintf(os.Stderr, "caught panic: %s\n%s\n", rerr, debug.Stack())
err = fmt.Errorf("panic reading message: %s", rerr)
}
}()
var data []byte
if m, ok := msg.(interface {
MarshalTo(data []byte) (n int, err error)
}); ok {
n, ok := getSize(m)
if ok {
if n+varint.MaxLenUvarint63 >= len(uw.buffer) {
uw.buffer = make([]byte, n+varint.MaxLenUvarint63)
}
lenOff := varint.PutUvarint(uw.buffer, uint64(n))
_, err = m.MarshalTo(uw.buffer[lenOff:])
if err != nil {
return err
}
_, err = uw.w.Write(uw.buffer[:lenOff+n])
return err
}
}
// fallback
data, err = proto.Marshal(msg)
if err != nil {
return err
}
length := uint64(len(data))
n := varint.PutUvarint(uw.lenBuf, length)
_, err = uw.w.Write(uw.lenBuf[:n])
if err != nil {
return err
}
_, err = uw.w.Write(data)
return err
}
func (uw *uvarintWriter) Close() error {
if closer, ok := uw.w.(io.Closer); ok {
return closer.Close()
}
return nil
}

189
vendor/github.com/libp2p/go-msgio/varint.go generated vendored Normal file
View File

@@ -0,0 +1,189 @@
package msgio
import (
"encoding/binary"
"io"
"sync"
pool "github.com/libp2p/go-buffer-pool"
"github.com/multiformats/go-varint"
)
// varintWriter is the underlying type that implements the Writer interface.
type varintWriter struct {
W io.Writer
pool *pool.BufferPool
lock sync.Mutex // for threadsafe writes
}
// NewVarintWriter wraps an io.Writer with a varint msgio framed writer.
// The msgio.Writer will write the length prefix of every message written
// as a varint, using https://golang.org/pkg/encoding/binary/#PutUvarint
func NewVarintWriter(w io.Writer) WriteCloser {
return NewVarintWriterWithPool(w, pool.GlobalPool)
}
func NewVarintWriterWithPool(w io.Writer, p *pool.BufferPool) WriteCloser {
return &varintWriter{
pool: p,
W: w,
}
}
func (s *varintWriter) Write(msg []byte) (int, error) {
err := s.WriteMsg(msg)
if err != nil {
return 0, err
}
return len(msg), nil
}
func (s *varintWriter) WriteMsg(msg []byte) error {
s.lock.Lock()
defer s.lock.Unlock()
buf := s.pool.Get(len(msg) + binary.MaxVarintLen64)
n := binary.PutUvarint(buf, uint64(len(msg)))
n += copy(buf[n:], msg)
_, err := s.W.Write(buf[:n])
s.pool.Put(buf)
return err
}
func (s *varintWriter) Close() error {
if c, ok := s.W.(io.Closer); ok {
return c.Close()
}
return nil
}
// varintReader is the underlying type that implements the Reader interface.
type varintReader struct {
R io.Reader
br io.ByteReader // for reading varints.
next int
pool *pool.BufferPool
lock sync.Mutex
max int // the maximal message size (in bytes) this reader handles
}
// NewVarintReader wraps an io.Reader with a varint msgio framed reader.
// The msgio.Reader will read whole messages at a time (using the length).
// Varints read according to https://golang.org/pkg/encoding/binary/#ReadUvarint
// Assumes an equivalent writer on the other side.
func NewVarintReader(r io.Reader) ReadCloser {
return NewVarintReaderSize(r, defaultMaxSize)
}
// NewVarintReaderSize is equivalent to NewVarintReader but allows one to
// specify a max message size.
func NewVarintReaderSize(r io.Reader, maxMessageSize int) ReadCloser {
return NewVarintReaderSizeWithPool(r, maxMessageSize, pool.GlobalPool)
}
// NewVarintReaderWithPool is the same as NewVarintReader but allows one to
// specify a buffer pool.
func NewVarintReaderWithPool(r io.Reader, p *pool.BufferPool) ReadCloser {
return NewVarintReaderSizeWithPool(r, defaultMaxSize, p)
}
// NewVarintReaderWithPool is the same as NewVarintReader but allows one to
// specify a buffer pool and a max message size.
func NewVarintReaderSizeWithPool(r io.Reader, maxMessageSize int, p *pool.BufferPool) ReadCloser {
if p == nil {
panic("nil pool")
}
return &varintReader{
R: r,
br: &simpleByteReader{R: r},
next: -1,
pool: p,
max: maxMessageSize,
}
}
// NextMsgLen reads the length of the next msg into s.lbuf, and returns it.
// WARNING: like Read, NextMsgLen is destructive. It reads from the internal
// reader.
func (s *varintReader) NextMsgLen() (int, error) {
s.lock.Lock()
defer s.lock.Unlock()
return s.nextMsgLen()
}
func (s *varintReader) nextMsgLen() (int, error) {
if s.next == -1 {
length, err := varint.ReadUvarint(s.br)
if err != nil {
return 0, err
}
s.next = int(length)
}
return s.next, nil
}
func (s *varintReader) Read(msg []byte) (int, error) {
s.lock.Lock()
defer s.lock.Unlock()
length, err := s.nextMsgLen()
if err != nil {
return 0, err
}
if length > len(msg) {
return 0, io.ErrShortBuffer
}
_, err = io.ReadFull(s.R, msg[:length])
s.next = -1 // signal we've consumed this msg
return length, err
}
func (s *varintReader) ReadMsg() ([]byte, error) {
s.lock.Lock()
defer s.lock.Unlock()
length, err := s.nextMsgLen()
if err != nil {
return nil, err
}
if length == 0 {
s.next = -1
return nil, nil
}
if length > s.max {
return nil, ErrMsgTooLarge
}
msg := s.pool.Get(length)
_, err = io.ReadFull(s.R, msg)
s.next = -1 // signal we've consumed this msg
return msg, err
}
func (s *varintReader) ReleaseMsg(msg []byte) {
s.pool.Put(msg)
}
func (s *varintReader) Close() error {
if c, ok := s.R.(io.Closer); ok {
return c.Close()
}
return nil
}
type simpleByteReader struct {
R io.Reader
buf [1]byte
}
func (r *simpleByteReader) ReadByte() (c byte, err error) {
if _, err := io.ReadFull(r.R, r.buf[:]); err != nil {
return 0, err
}
return r.buf[0], nil
}

3
vendor/github.com/libp2p/go-msgio/version.json generated vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"version": "v0.3.0"
}