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-libp2p-record/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2016 libp2p
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.

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

@@ -0,0 +1,36 @@
# go-libp2p-record
[![](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)
[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io)
> signed records for use with routing systems
## Documentation
See https://godoc.org/github.com/libp2p/go-libp2p-record.
## Testing
This package has some tests that rely on generating weak RSA keys (for speed).
In order to successfully run the tests, one must set the environment variable,
`LIBP2P_ALLOW_WEAK_RSA_KEYS` to any non-empty value, such as `1`.
## Contribute
Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/go-key/issues)!
This repository falls under the libp2p [Code of Conduct](https://github.com/libp2p/community/blob/master/code-of-conduct.md).
### Want to hack on libp2p?
[![](https://cdn.rawgit.com/libp2p/community/master/img/contribute.gif)](https://github.com/libp2p/community/blob/master/CONTRIBUTE.md)
## License
MIT
---
The last gx published version of this module was: 4.1.15: QmbeHtaBy9nZsW4cHRcvgVY4CnDhXudE2Dr6qDxS7yg9rX

View File

@@ -0,0 +1,3 @@
coverage:
range: "50...100"
comment: off

11
vendor/github.com/libp2p/go-libp2p-record/pb/Makefile generated vendored Normal file
View File

@@ -0,0 +1,11 @@
PB = $(wildcard *.proto)
GO = $(PB:.proto=.pb.go)
all: $(GO)
%.pb.go: %.proto
protoc --proto_path=$(GOPATH)/src:. --gogofast_out=. $<
clean:
rm -f *.pb.go
rm -f *.go

View File

@@ -0,0 +1,437 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: record.proto
package record_pb
import (
fmt "fmt"
proto "github.com/gogo/protobuf/proto"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// Record represents a dht record that contains a value
// for a key value pair
type Record struct {
// The key that references this record
Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
// The actual value this record is storing
Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
// Time the record was received, set by receiver
TimeReceived string `protobuf:"bytes,5,opt,name=timeReceived,proto3" json:"timeReceived,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Record) Reset() { *m = Record{} }
func (m *Record) String() string { return proto.CompactTextString(m) }
func (*Record) ProtoMessage() {}
func (*Record) Descriptor() ([]byte, []int) {
return fileDescriptor_bf94fd919e302a1d, []int{0}
}
func (m *Record) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *Record) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_Record.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *Record) XXX_Merge(src proto.Message) {
xxx_messageInfo_Record.Merge(m, src)
}
func (m *Record) XXX_Size() int {
return m.Size()
}
func (m *Record) XXX_DiscardUnknown() {
xxx_messageInfo_Record.DiscardUnknown(m)
}
var xxx_messageInfo_Record proto.InternalMessageInfo
func (m *Record) GetKey() []byte {
if m != nil {
return m.Key
}
return nil
}
func (m *Record) GetValue() []byte {
if m != nil {
return m.Value
}
return nil
}
func (m *Record) GetTimeReceived() string {
if m != nil {
return m.TimeReceived
}
return ""
}
func init() {
proto.RegisterType((*Record)(nil), "record.pb.Record")
}
func init() { proto.RegisterFile("record.proto", fileDescriptor_bf94fd919e302a1d) }
var fileDescriptor_bf94fd919e302a1d = []byte{
// 125 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0x4a, 0x4d, 0xce,
0x2f, 0x4a, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x84, 0xf1, 0x92, 0x94, 0x42, 0xb8,
0xd8, 0x82, 0xc0, 0x1c, 0x21, 0x01, 0x2e, 0xe6, 0xec, 0xd4, 0x4a, 0x09, 0x46, 0x05, 0x46, 0x0d,
0x9e, 0x20, 0x10, 0x53, 0x48, 0x84, 0x8b, 0xb5, 0x2c, 0x31, 0xa7, 0x34, 0x55, 0x82, 0x09, 0x2c,
0x06, 0xe1, 0x08, 0x29, 0x71, 0xf1, 0x94, 0x64, 0xe6, 0xa6, 0x06, 0xa5, 0x26, 0xa7, 0x66, 0x96,
0xa5, 0xa6, 0x48, 0xb0, 0x2a, 0x30, 0x6a, 0x70, 0x06, 0xa1, 0x88, 0x39, 0xf1, 0x9c, 0x78, 0x24,
0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x49, 0x6c, 0x60, 0x5b, 0x8d, 0x01,
0x01, 0x00, 0x00, 0xff, 0xff, 0x64, 0x43, 0x08, 0x1c, 0x85, 0x00, 0x00, 0x00,
}
func (m *Record) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Record) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *Record) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.XXX_unrecognized != nil {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if len(m.TimeReceived) > 0 {
i -= len(m.TimeReceived)
copy(dAtA[i:], m.TimeReceived)
i = encodeVarintRecord(dAtA, i, uint64(len(m.TimeReceived)))
i--
dAtA[i] = 0x2a
}
if len(m.Value) > 0 {
i -= len(m.Value)
copy(dAtA[i:], m.Value)
i = encodeVarintRecord(dAtA, i, uint64(len(m.Value)))
i--
dAtA[i] = 0x12
}
if len(m.Key) > 0 {
i -= len(m.Key)
copy(dAtA[i:], m.Key)
i = encodeVarintRecord(dAtA, i, uint64(len(m.Key)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func encodeVarintRecord(dAtA []byte, offset int, v uint64) int {
offset -= sovRecord(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *Record) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Key)
if l > 0 {
n += 1 + l + sovRecord(uint64(l))
}
l = len(m.Value)
if l > 0 {
n += 1 + l + sovRecord(uint64(l))
}
l = len(m.TimeReceived)
if l > 0 {
n += 1 + l + sovRecord(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func sovRecord(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozRecord(x uint64) (n int) {
return sovRecord(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *Record) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRecord
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Record: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Record: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRecord
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthRecord
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthRecord
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...)
if m.Key == nil {
m.Key = []byte{}
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRecord
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthRecord
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthRecord
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Value = append(m.Value[:0], dAtA[iNdEx:postIndex]...)
if m.Value == nil {
m.Value = []byte{}
}
iNdEx = postIndex
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field TimeReceived", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRecord
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthRecord
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthRecord
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.TimeReceived = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipRecord(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthRecord
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthRecord
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipRecord(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowRecord
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowRecord
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowRecord
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthRecord
}
iNdEx += length
if iNdEx < 0 {
return 0, ErrInvalidLengthRecord
}
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupRecord
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthRecord = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowRecord = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupRecord = fmt.Errorf("proto: unexpected end of group")
)

View File

@@ -0,0 +1,27 @@
// In order to re-generate the golang packages for `Record` you will need...
// 1. Protobuf binary (tested with protoc 3.0.0). - https://github.com/gogo/protobuf/releases
// 2. Gogo Protobuf (tested with gogo 0.3). - https://github.com/gogo/protobuf
// Now from `libp2p/go-libp2p-record/pb` you can run...
// `protoc --gogo_out=. record.proto`
syntax = "proto3";
package record.pb;
// Record represents a dht record that contains a value
// for a key value pair
message Record {
// The key that references this record
bytes key = 1;
// The actual value this record is storing
bytes value = 2;
// Note: These fields were removed from the Record message
// hash of the authors public key
//optional string author = 3;
// A PKI signature for the key+value+author
//optional bytes signature = 4;
// Time the record was received, set by receiver
string timeReceived = 5;
}

55
vendor/github.com/libp2p/go-libp2p-record/pubkey.go generated vendored Normal file
View File

@@ -0,0 +1,55 @@
package record
import (
"bytes"
"errors"
"fmt"
"github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/peer"
mh "github.com/multiformats/go-multihash"
)
// PublicKeyValidator is a Validator that validates public keys.
type PublicKeyValidator struct{}
// Validate conforms to the Validator interface.
//
// It verifies that the passed in record value is the PublicKey that matches the
// passed in key.
func (pkv PublicKeyValidator) Validate(key string, value []byte) error {
ns, key, err := SplitKey(key)
if err != nil {
return err
}
if ns != "pk" {
return errors.New("namespace not 'pk'")
}
keyhash := []byte(key)
if _, err := mh.Cast(keyhash); err != nil {
return fmt.Errorf("key did not contain valid multihash: %s", err)
}
pk, err := crypto.UnmarshalPublicKey(value)
if err != nil {
return err
}
id, err := peer.IDFromPublicKey(pk)
if err != nil {
return err
}
if !bytes.Equal(keyhash, []byte(id)) {
return errors.New("public key does not match storage key")
}
return nil
}
// Select conforms to the Validator interface.
//
// It always returns 0 as all public keys are equivalently valid.
func (pkv PublicKeyValidator) Select(k string, vals [][]byte) (int, error) {
return 0, nil
}
var _ Validator = PublicKeyValidator{}

13
vendor/github.com/libp2p/go-libp2p-record/record.go generated vendored Normal file
View File

@@ -0,0 +1,13 @@
package record
import (
pb "github.com/libp2p/go-libp2p-record/pb"
)
// MakePutRecord creates a dht record for the given key/value pair
func MakePutRecord(key string, value []byte) *pb.Record {
record := new(pb.Record)
record.Key = []byte(key)
record.Value = value
return record
}

22
vendor/github.com/libp2p/go-libp2p-record/util.go generated vendored Normal file
View File

@@ -0,0 +1,22 @@
package record
import (
"strings"
)
// SplitKey takes a key in the form `/$namespace/$path` and splits it into
// `$namespace` and `$path`.
func SplitKey(key string) (string, string, error) {
if len(key) == 0 || key[0] != '/' {
return "", "", ErrInvalidRecordType
}
key = key[1:]
i := strings.IndexByte(key, '/')
if i <= 0 {
return "", "", ErrInvalidRecordType
}
return key[:i], key[i+1:], nil
}

74
vendor/github.com/libp2p/go-libp2p-record/validator.go generated vendored Normal file
View File

@@ -0,0 +1,74 @@
package record
import (
"errors"
"fmt"
)
// ErrInvalidRecordType is returned if a DHTRecord keys prefix
// is not found in the Validator map of the DHT.
var ErrInvalidRecordType = errors.New("invalid record keytype")
// ErrBetterRecord is returned by a subsystem when it fails because it found a
// better record.
type ErrBetterRecord struct {
// Key is the key associated with the record.
Key string
// Value is the best value that was found, according to the record's
// validator.
Value []byte
}
func (e *ErrBetterRecord) Error() string {
return fmt.Sprintf("found better value for %q", e.Key)
}
// Validator is an interface that should be implemented by record validators.
type Validator interface {
// Validate validates the given record, returning an error if it's
// invalid (e.g., expired, signed by the wrong key, etc.).
Validate(key string, value []byte) error
// Select selects the best record from the set of records (e.g., the
// newest).
//
// Decisions made by select should be stable.
Select(key string, values [][]byte) (int, error)
}
// NamespacedValidator is a validator that delegates to sub-validators by
// namespace.
type NamespacedValidator map[string]Validator
// ValidatorByKey looks up the validator responsible for validating the given
// key.
func (v NamespacedValidator) ValidatorByKey(key string) Validator {
ns, _, err := SplitKey(key)
if err != nil {
return nil
}
return v[ns]
}
// Validate conforms to the Validator interface.
func (v NamespacedValidator) Validate(key string, value []byte) error {
vi := v.ValidatorByKey(key)
if vi == nil {
return ErrInvalidRecordType
}
return vi.Validate(key, value)
}
// Select conforms to the Validator interface.
func (v NamespacedValidator) Select(key string, values [][]byte) (int, error) {
if len(values) == 0 {
return 0, errors.New("can't select from no values")
}
vi := v.ValidatorByKey(key)
if vi == nil {
return 0, ErrInvalidRecordType
}
return vi.Select(key, values)
}
var _ Validator = NamespacedValidator{}

View File

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