refactor(node): AX error names and levin protocol cleanup
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
commit
51b3cf120b
12 changed files with 180 additions and 108 deletions
|
|
@ -118,7 +118,7 @@ func (c *Controller) sendRequest(peerID string, msg *Message, timeout time.Durat
|
|||
func (c *Controller) GetRemoteStats(peerID string) (*StatsPayload, error) {
|
||||
identity := c.node.GetIdentity()
|
||||
if identity == nil {
|
||||
return nil, ErrIdentityNotInitialized
|
||||
return nil, ErrorIdentityNotInitialized
|
||||
}
|
||||
|
||||
msg, err := NewMessage(MsgGetStats, identity.ID, peerID, nil)
|
||||
|
|
@ -143,7 +143,7 @@ func (c *Controller) GetRemoteStats(peerID string) (*StatsPayload, error) {
|
|||
func (c *Controller) StartRemoteMiner(peerID, minerType, profileID string, configOverride RawMessage) error {
|
||||
identity := c.node.GetIdentity()
|
||||
if identity == nil {
|
||||
return ErrIdentityNotInitialized
|
||||
return ErrorIdentityNotInitialized
|
||||
}
|
||||
|
||||
if minerType == "" {
|
||||
|
|
@ -182,7 +182,7 @@ func (c *Controller) StartRemoteMiner(peerID, minerType, profileID string, confi
|
|||
func (c *Controller) StopRemoteMiner(peerID, minerName string) error {
|
||||
identity := c.node.GetIdentity()
|
||||
if identity == nil {
|
||||
return ErrIdentityNotInitialized
|
||||
return ErrorIdentityNotInitialized
|
||||
}
|
||||
|
||||
payload := StopMinerPayload{
|
||||
|
|
@ -215,7 +215,7 @@ func (c *Controller) StopRemoteMiner(peerID, minerName string) error {
|
|||
func (c *Controller) GetRemoteLogs(peerID, minerName string, lines int) ([]string, error) {
|
||||
identity := c.node.GetIdentity()
|
||||
if identity == nil {
|
||||
return nil, ErrIdentityNotInitialized
|
||||
return nil, ErrorIdentityNotInitialized
|
||||
}
|
||||
|
||||
payload := GetLogsPayload{
|
||||
|
|
@ -274,7 +274,7 @@ func (c *Controller) GetAllStats() map[string]*StatsPayload {
|
|||
func (c *Controller) PingPeer(peerID string) (float64, error) {
|
||||
identity := c.node.GetIdentity()
|
||||
if identity == nil {
|
||||
return 0, ErrIdentityNotInitialized
|
||||
return 0, ErrorIdentityNotInitialized
|
||||
}
|
||||
sentAt := time.Now()
|
||||
|
||||
|
|
|
|||
|
|
@ -100,16 +100,16 @@ func (d *Dispatcher) Handlers() iter.Seq2[byte, IntentHandler] {
|
|||
// and then to the appropriate intent handler.
|
||||
//
|
||||
// Behaviour:
|
||||
// - Returns ErrThreatScoreExceeded if the packet's ThreatScore exceeds the
|
||||
// - Returns ErrorThreatScoreExceeded if the packet's ThreatScore exceeds the
|
||||
// threshold (packet is dropped and logged).
|
||||
// - Returns ErrUnknownIntent if no handler is registered for the IntentID
|
||||
// - Returns ErrorUnknownIntent if no handler is registered for the IntentID
|
||||
// (packet is dropped and logged).
|
||||
// - Returns nil on successful delivery to a handler, or any error the
|
||||
// handler itself returns.
|
||||
// - A nil packet returns ErrNilPacket immediately.
|
||||
// - A nil packet returns ErrorNilPacket immediately.
|
||||
func (d *Dispatcher) Dispatch(pkt *ueps.ParsedPacket) error {
|
||||
if pkt == nil {
|
||||
return ErrNilPacket
|
||||
return ErrorNilPacket
|
||||
}
|
||||
|
||||
// 1. Threat circuit breaker (L5 guard)
|
||||
|
|
@ -120,7 +120,7 @@ func (d *Dispatcher) Dispatch(pkt *ueps.ParsedPacket) error {
|
|||
"intent_id": core.Sprintf("0x%02X", pkt.Header.IntentID),
|
||||
"version": pkt.Header.Version,
|
||||
})
|
||||
return ErrThreatScoreExceeded
|
||||
return ErrorThreatScoreExceeded
|
||||
}
|
||||
|
||||
// 2. Intent routing (L9 semantic)
|
||||
|
|
@ -133,7 +133,7 @@ func (d *Dispatcher) Dispatch(pkt *ueps.ParsedPacket) error {
|
|||
"intent_id": core.Sprintf("0x%02X", pkt.Header.IntentID),
|
||||
"version": pkt.Header.Version,
|
||||
})
|
||||
return ErrUnknownIntent
|
||||
return ErrorUnknownIntent
|
||||
}
|
||||
|
||||
return handler(pkt)
|
||||
|
|
@ -141,14 +141,23 @@ func (d *Dispatcher) Dispatch(pkt *ueps.ParsedPacket) error {
|
|||
|
||||
// Sentinel errors returned by Dispatch.
|
||||
var (
|
||||
// ErrThreatScoreExceeded is returned when a packet's ThreatScore exceeds
|
||||
// ErrorThreatScoreExceeded is returned when a packet's ThreatScore exceeds
|
||||
// the safety threshold.
|
||||
ErrThreatScoreExceeded = core.E("Dispatcher.Dispatch", core.Sprintf("packet rejected: threat score exceeds safety threshold (%d)", ThreatScoreThreshold), nil)
|
||||
ErrorThreatScoreExceeded = core.E("Dispatcher.Dispatch", core.Sprintf("packet rejected: threat score exceeds safety threshold (%d)", ThreatScoreThreshold), nil)
|
||||
|
||||
// ErrUnknownIntent is returned when no handler is registered for the
|
||||
// Deprecated: use ErrorThreatScoreExceeded.
|
||||
ErrThreatScoreExceeded = ErrorThreatScoreExceeded
|
||||
|
||||
// ErrorUnknownIntent is returned when no handler is registered for the
|
||||
// packet's IntentID.
|
||||
ErrUnknownIntent = core.E("Dispatcher.Dispatch", "packet dropped: unknown intent", nil)
|
||||
ErrorUnknownIntent = core.E("Dispatcher.Dispatch", "packet dropped: unknown intent", nil)
|
||||
|
||||
// ErrNilPacket is returned when a nil packet is passed to Dispatch.
|
||||
ErrNilPacket = core.E("Dispatcher.Dispatch", "nil packet", nil)
|
||||
// Deprecated: use ErrorUnknownIntent.
|
||||
ErrUnknownIntent = ErrorUnknownIntent
|
||||
|
||||
// ErrorNilPacket is returned when a nil packet is passed to Dispatch.
|
||||
ErrorNilPacket = core.E("Dispatcher.Dispatch", "nil packet", nil)
|
||||
|
||||
// Deprecated: use ErrorNilPacket.
|
||||
ErrNilPacket = ErrorNilPacket
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,13 +2,19 @@ package node
|
|||
|
||||
import core "dappco.re/go/core"
|
||||
|
||||
// Sentinel errors shared across the node package.
|
||||
// Shared error sentinels for the node package.
|
||||
var (
|
||||
// ErrIdentityNotInitialized is returned when a node operation requires
|
||||
// ErrorIdentityNotInitialized is returned when a node operation requires
|
||||
// a node identity but none has been generated or loaded.
|
||||
ErrIdentityNotInitialized = core.E("node", "node identity not initialized", nil)
|
||||
ErrorIdentityNotInitialized = core.E("node", "node identity not initialized", nil)
|
||||
|
||||
// ErrMinerManagerNotConfigured is returned when a miner operation is
|
||||
// Deprecated: use ErrorIdentityNotInitialized.
|
||||
ErrIdentityNotInitialized = ErrorIdentityNotInitialized
|
||||
|
||||
// ErrorMinerManagerNotConfigured is returned when a miner operation is
|
||||
// attempted but no MinerManager has been set on the Worker.
|
||||
ErrMinerManagerNotConfigured = core.E("node", "miner manager not configured", nil)
|
||||
ErrorMinerManagerNotConfigured = core.E("node", "miner manager not configured", nil)
|
||||
|
||||
// Deprecated: use ErrorMinerManagerNotConfigured.
|
||||
ErrMinerManagerNotConfigured = ErrorMinerManagerNotConfigured
|
||||
)
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ func (n *NodeManager) DeriveSharedSecret(peerPubKeyBase64 string) ([]byte, error
|
|||
defer n.mu.RUnlock()
|
||||
|
||||
if n.privateKey == nil {
|
||||
return nil, ErrIdentityNotInitialized
|
||||
return nil, ErrorIdentityNotInitialized
|
||||
}
|
||||
|
||||
// Load peer's public key
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ func (c *Connection) ReadPacket() (Header, []byte, error) {
|
|||
|
||||
// Check against the connection-specific payload limit.
|
||||
if h.PayloadSize > c.MaxPayloadSize {
|
||||
return Header{}, nil, ErrPayloadTooBig
|
||||
return Header{}, nil, ErrorPayloadTooBig
|
||||
}
|
||||
|
||||
// Empty payload is valid — return nil data without allocation.
|
||||
|
|
|
|||
|
|
@ -22,10 +22,19 @@ const MaxPayloadSize uint64 = 100 * 1024 * 1024
|
|||
|
||||
// Return-code constants carried in every Levin response.
|
||||
const (
|
||||
ReturnOK int32 = 0
|
||||
ReturnErrConnection int32 = -1
|
||||
ReturnErrFormat int32 = -7
|
||||
ReturnErrSignature int32 = -13
|
||||
ReturnOK int32 = 0
|
||||
ReturnErrorConnection int32 = -1
|
||||
ReturnErrorFormat int32 = -7
|
||||
ReturnErrorSignature int32 = -13
|
||||
|
||||
// Deprecated: use ReturnErrorConnection.
|
||||
ReturnErrConnection = ReturnErrorConnection
|
||||
|
||||
// Deprecated: use ReturnErrorFormat.
|
||||
ReturnErrFormat = ReturnErrorFormat
|
||||
|
||||
// Deprecated: use ReturnErrorSignature.
|
||||
ReturnErrSignature = ReturnErrorSignature
|
||||
)
|
||||
|
||||
// Command IDs for the CryptoNote P2P layer.
|
||||
|
|
@ -43,8 +52,14 @@ const (
|
|||
|
||||
// Sentinel errors returned by DecodeHeader.
|
||||
var (
|
||||
ErrBadSignature = core.E("levin", "bad signature", nil)
|
||||
ErrPayloadTooBig = core.E("levin", "payload exceeds maximum size", nil)
|
||||
ErrorBadSignature = core.E("levin", "bad signature", nil)
|
||||
ErrorPayloadTooBig = core.E("levin", "payload exceeds maximum size", nil)
|
||||
|
||||
// Deprecated: use ErrorBadSignature.
|
||||
ErrBadSignature = ErrorBadSignature
|
||||
|
||||
// Deprecated: use ErrorPayloadTooBig.
|
||||
ErrPayloadTooBig = ErrorPayloadTooBig
|
||||
)
|
||||
|
||||
// Header is the 33-byte packed header that prefixes every Levin message.
|
||||
|
|
@ -87,11 +102,11 @@ func DecodeHeader(buf [HeaderSize]byte) (Header, error) {
|
|||
var h Header
|
||||
h.Signature = binary.LittleEndian.Uint64(buf[0:8])
|
||||
if h.Signature != Signature {
|
||||
return Header{}, ErrBadSignature
|
||||
return Header{}, ErrorBadSignature
|
||||
}
|
||||
h.PayloadSize = binary.LittleEndian.Uint64(buf[8:16])
|
||||
if h.PayloadSize > MaxPayloadSize {
|
||||
return Header{}, ErrPayloadTooBig
|
||||
return Header{}, ErrorPayloadTooBig
|
||||
}
|
||||
h.ExpectResponse = buf[16] == 0x01
|
||||
h.Command = binary.LittleEndian.Uint32(buf[17:21])
|
||||
|
|
|
|||
|
|
@ -40,12 +40,30 @@ const (
|
|||
|
||||
// Sentinel errors for storage encoding and decoding.
|
||||
var (
|
||||
ErrStorageBadSignature = core.E("levin.storage", "bad storage signature", nil)
|
||||
ErrStorageTruncated = core.E("levin.storage", "truncated storage data", nil)
|
||||
ErrStorageBadVersion = core.E("levin.storage", "unsupported storage version", nil)
|
||||
ErrStorageNameTooLong = core.E("levin.storage", "entry name exceeds 255 bytes", nil)
|
||||
ErrStorageTypeMismatch = core.E("levin.storage", "value type mismatch", nil)
|
||||
ErrStorageUnknownType = core.E("levin.storage", "unknown type tag", nil)
|
||||
ErrorStorageBadSignature = core.E("levin.storage", "bad storage signature", nil)
|
||||
ErrorStorageTruncated = core.E("levin.storage", "truncated storage data", nil)
|
||||
ErrorStorageBadVersion = core.E("levin.storage", "unsupported storage version", nil)
|
||||
ErrorStorageNameTooLong = core.E("levin.storage", "entry name exceeds 255 bytes", nil)
|
||||
ErrorStorageTypeMismatch = core.E("levin.storage", "value type mismatch", nil)
|
||||
ErrorStorageUnknownType = core.E("levin.storage", "unknown type tag", nil)
|
||||
|
||||
// Deprecated: use ErrorStorageBadSignature.
|
||||
ErrStorageBadSignature = ErrorStorageBadSignature
|
||||
|
||||
// Deprecated: use ErrorStorageTruncated.
|
||||
ErrStorageTruncated = ErrorStorageTruncated
|
||||
|
||||
// Deprecated: use ErrorStorageBadVersion.
|
||||
ErrStorageBadVersion = ErrorStorageBadVersion
|
||||
|
||||
// Deprecated: use ErrorStorageNameTooLong.
|
||||
ErrStorageNameTooLong = ErrorStorageNameTooLong
|
||||
|
||||
// Deprecated: use ErrorStorageTypeMismatch.
|
||||
ErrStorageTypeMismatch = ErrorStorageTypeMismatch
|
||||
|
||||
// Deprecated: use ErrorStorageUnknownType.
|
||||
ErrStorageUnknownType = ErrorStorageUnknownType
|
||||
)
|
||||
|
||||
// Section is an ordered map of named values forming a portable storage section.
|
||||
|
|
@ -179,7 +197,7 @@ func ObjectArrayVal(vs []Section) Value {
|
|||
// AsUint64 returns the uint64 value or an error on type mismatch.
|
||||
func (v Value) AsUint64() (uint64, error) {
|
||||
if v.Type != TypeUint64 {
|
||||
return 0, ErrStorageTypeMismatch
|
||||
return 0, ErrorStorageTypeMismatch
|
||||
}
|
||||
return v.uintVal, nil
|
||||
}
|
||||
|
|
@ -187,7 +205,7 @@ func (v Value) AsUint64() (uint64, error) {
|
|||
// AsUint32 returns the uint32 value or an error on type mismatch.
|
||||
func (v Value) AsUint32() (uint32, error) {
|
||||
if v.Type != TypeUint32 {
|
||||
return 0, ErrStorageTypeMismatch
|
||||
return 0, ErrorStorageTypeMismatch
|
||||
}
|
||||
return uint32(v.uintVal), nil
|
||||
}
|
||||
|
|
@ -195,7 +213,7 @@ func (v Value) AsUint32() (uint32, error) {
|
|||
// AsUint16 returns the uint16 value or an error on type mismatch.
|
||||
func (v Value) AsUint16() (uint16, error) {
|
||||
if v.Type != TypeUint16 {
|
||||
return 0, ErrStorageTypeMismatch
|
||||
return 0, ErrorStorageTypeMismatch
|
||||
}
|
||||
return uint16(v.uintVal), nil
|
||||
}
|
||||
|
|
@ -203,7 +221,7 @@ func (v Value) AsUint16() (uint16, error) {
|
|||
// AsUint8 returns the uint8 value or an error on type mismatch.
|
||||
func (v Value) AsUint8() (uint8, error) {
|
||||
if v.Type != TypeUint8 {
|
||||
return 0, ErrStorageTypeMismatch
|
||||
return 0, ErrorStorageTypeMismatch
|
||||
}
|
||||
return uint8(v.uintVal), nil
|
||||
}
|
||||
|
|
@ -211,7 +229,7 @@ func (v Value) AsUint8() (uint8, error) {
|
|||
// AsInt64 returns the int64 value or an error on type mismatch.
|
||||
func (v Value) AsInt64() (int64, error) {
|
||||
if v.Type != TypeInt64 {
|
||||
return 0, ErrStorageTypeMismatch
|
||||
return 0, ErrorStorageTypeMismatch
|
||||
}
|
||||
return v.intVal, nil
|
||||
}
|
||||
|
|
@ -219,7 +237,7 @@ func (v Value) AsInt64() (int64, error) {
|
|||
// AsInt32 returns the int32 value or an error on type mismatch.
|
||||
func (v Value) AsInt32() (int32, error) {
|
||||
if v.Type != TypeInt32 {
|
||||
return 0, ErrStorageTypeMismatch
|
||||
return 0, ErrorStorageTypeMismatch
|
||||
}
|
||||
return int32(v.intVal), nil
|
||||
}
|
||||
|
|
@ -227,7 +245,7 @@ func (v Value) AsInt32() (int32, error) {
|
|||
// AsInt16 returns the int16 value or an error on type mismatch.
|
||||
func (v Value) AsInt16() (int16, error) {
|
||||
if v.Type != TypeInt16 {
|
||||
return 0, ErrStorageTypeMismatch
|
||||
return 0, ErrorStorageTypeMismatch
|
||||
}
|
||||
return int16(v.intVal), nil
|
||||
}
|
||||
|
|
@ -235,7 +253,7 @@ func (v Value) AsInt16() (int16, error) {
|
|||
// AsInt8 returns the int8 value or an error on type mismatch.
|
||||
func (v Value) AsInt8() (int8, error) {
|
||||
if v.Type != TypeInt8 {
|
||||
return 0, ErrStorageTypeMismatch
|
||||
return 0, ErrorStorageTypeMismatch
|
||||
}
|
||||
return int8(v.intVal), nil
|
||||
}
|
||||
|
|
@ -243,7 +261,7 @@ func (v Value) AsInt8() (int8, error) {
|
|||
// AsBool returns the bool value or an error on type mismatch.
|
||||
func (v Value) AsBool() (bool, error) {
|
||||
if v.Type != TypeBool {
|
||||
return false, ErrStorageTypeMismatch
|
||||
return false, ErrorStorageTypeMismatch
|
||||
}
|
||||
return v.boolVal, nil
|
||||
}
|
||||
|
|
@ -251,7 +269,7 @@ func (v Value) AsBool() (bool, error) {
|
|||
// AsDouble returns the float64 value or an error on type mismatch.
|
||||
func (v Value) AsDouble() (float64, error) {
|
||||
if v.Type != TypeDouble {
|
||||
return 0, ErrStorageTypeMismatch
|
||||
return 0, ErrorStorageTypeMismatch
|
||||
}
|
||||
return v.floatVal, nil
|
||||
}
|
||||
|
|
@ -259,7 +277,7 @@ func (v Value) AsDouble() (float64, error) {
|
|||
// AsString returns the byte-string value or an error on type mismatch.
|
||||
func (v Value) AsString() ([]byte, error) {
|
||||
if v.Type != TypeString {
|
||||
return nil, ErrStorageTypeMismatch
|
||||
return nil, ErrorStorageTypeMismatch
|
||||
}
|
||||
return v.bytesVal, nil
|
||||
}
|
||||
|
|
@ -267,7 +285,7 @@ func (v Value) AsString() ([]byte, error) {
|
|||
// AsSection returns the nested Section or an error on type mismatch.
|
||||
func (v Value) AsSection() (Section, error) {
|
||||
if v.Type != TypeObject {
|
||||
return nil, ErrStorageTypeMismatch
|
||||
return nil, ErrorStorageTypeMismatch
|
||||
}
|
||||
return v.objectVal, nil
|
||||
}
|
||||
|
|
@ -279,7 +297,7 @@ func (v Value) AsSection() (Section, error) {
|
|||
// AsUint64Array returns the []uint64 array or an error on type mismatch.
|
||||
func (v Value) AsUint64Array() ([]uint64, error) {
|
||||
if v.Type != (ArrayFlag | TypeUint64) {
|
||||
return nil, ErrStorageTypeMismatch
|
||||
return nil, ErrorStorageTypeMismatch
|
||||
}
|
||||
return v.uint64Array, nil
|
||||
}
|
||||
|
|
@ -287,7 +305,7 @@ func (v Value) AsUint64Array() ([]uint64, error) {
|
|||
// AsUint32Array returns the []uint32 array or an error on type mismatch.
|
||||
func (v Value) AsUint32Array() ([]uint32, error) {
|
||||
if v.Type != (ArrayFlag | TypeUint32) {
|
||||
return nil, ErrStorageTypeMismatch
|
||||
return nil, ErrorStorageTypeMismatch
|
||||
}
|
||||
return v.uint32Array, nil
|
||||
}
|
||||
|
|
@ -295,7 +313,7 @@ func (v Value) AsUint32Array() ([]uint32, error) {
|
|||
// AsStringArray returns the [][]byte array or an error on type mismatch.
|
||||
func (v Value) AsStringArray() ([][]byte, error) {
|
||||
if v.Type != (ArrayFlag | TypeString) {
|
||||
return nil, ErrStorageTypeMismatch
|
||||
return nil, ErrorStorageTypeMismatch
|
||||
}
|
||||
return v.stringArray, nil
|
||||
}
|
||||
|
|
@ -303,7 +321,7 @@ func (v Value) AsStringArray() ([][]byte, error) {
|
|||
// AsSectionArray returns the []Section array or an error on type mismatch.
|
||||
func (v Value) AsSectionArray() ([]Section, error) {
|
||||
if v.Type != (ArrayFlag | TypeObject) {
|
||||
return nil, ErrStorageTypeMismatch
|
||||
return nil, ErrorStorageTypeMismatch
|
||||
}
|
||||
return v.objectArray, nil
|
||||
}
|
||||
|
|
@ -348,7 +366,7 @@ func encodeSection(buf []byte, s Section) ([]byte, error) {
|
|||
|
||||
// Name: uint8 length + raw bytes.
|
||||
if len(name) > 255 {
|
||||
return nil, ErrStorageNameTooLong
|
||||
return nil, ErrorStorageNameTooLong
|
||||
}
|
||||
buf = append(buf, byte(len(name)))
|
||||
buf = append(buf, name...)
|
||||
|
|
@ -431,7 +449,7 @@ func encodeValue(buf []byte, v Value) ([]byte, error) {
|
|||
return encodeSection(buf, v.objectVal)
|
||||
|
||||
default:
|
||||
return nil, core.E("levin.encodeValue", core.Sprintf("unknown type tag: 0x%02x", v.Type), ErrStorageUnknownType)
|
||||
return nil, core.E("levin.encodeValue", core.Sprintf("unknown type tag: 0x%02x", v.Type), ErrorStorageUnknownType)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -478,7 +496,7 @@ func encodeArray(buf []byte, v Value) ([]byte, error) {
|
|||
return buf, nil
|
||||
|
||||
default:
|
||||
return nil, core.E("levin.encodeArray", core.Sprintf("unknown type tag: array of 0x%02x", elemType), ErrStorageUnknownType)
|
||||
return nil, core.E("levin.encodeArray", core.Sprintf("unknown type tag: array of 0x%02x", elemType), ErrorStorageUnknownType)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -492,7 +510,7 @@ func encodeArray(buf []byte, v Value) ([]byte, error) {
|
|||
// section, err := DecodeStorage(data)
|
||||
func DecodeStorage(data []byte) (Section, error) {
|
||||
if len(data) < StorageHeaderSize {
|
||||
return nil, ErrStorageTruncated
|
||||
return nil, ErrorStorageTruncated
|
||||
}
|
||||
|
||||
sigA := binary.LittleEndian.Uint32(data[0:4])
|
||||
|
|
@ -500,10 +518,10 @@ func DecodeStorage(data []byte) (Section, error) {
|
|||
ver := data[8]
|
||||
|
||||
if sigA != StorageSignatureA || sigB != StorageSignatureB {
|
||||
return nil, ErrStorageBadSignature
|
||||
return nil, ErrorStorageBadSignature
|
||||
}
|
||||
if ver != StorageVersion {
|
||||
return nil, ErrStorageBadVersion
|
||||
return nil, ErrorStorageBadVersion
|
||||
}
|
||||
|
||||
s, _, err := decodeSection(data[StorageHeaderSize:])
|
||||
|
|
@ -524,21 +542,21 @@ func decodeSection(buf []byte) (Section, int, error) {
|
|||
for range count {
|
||||
// Name length (1 byte).
|
||||
if off >= len(buf) {
|
||||
return nil, 0, ErrStorageTruncated
|
||||
return nil, 0, ErrorStorageTruncated
|
||||
}
|
||||
nameLen := int(buf[off])
|
||||
off++
|
||||
|
||||
// Name bytes.
|
||||
if off+nameLen > len(buf) {
|
||||
return nil, 0, ErrStorageTruncated
|
||||
return nil, 0, ErrorStorageTruncated
|
||||
}
|
||||
name := string(buf[off : off+nameLen])
|
||||
off += nameLen
|
||||
|
||||
// Type tag (1 byte).
|
||||
if off >= len(buf) {
|
||||
return nil, 0, ErrStorageTruncated
|
||||
return nil, 0, ErrorStorageTruncated
|
||||
}
|
||||
tag := buf[off]
|
||||
off++
|
||||
|
|
@ -567,68 +585,68 @@ func decodeValue(buf []byte, tag uint8) (Value, int, error) {
|
|||
switch tag {
|
||||
case TypeUint64:
|
||||
if len(buf) < 8 {
|
||||
return Value{}, 0, ErrStorageTruncated
|
||||
return Value{}, 0, ErrorStorageTruncated
|
||||
}
|
||||
v := binary.LittleEndian.Uint64(buf[:8])
|
||||
return Value{Type: TypeUint64, uintVal: v}, 8, nil
|
||||
|
||||
case TypeInt64:
|
||||
if len(buf) < 8 {
|
||||
return Value{}, 0, ErrStorageTruncated
|
||||
return Value{}, 0, ErrorStorageTruncated
|
||||
}
|
||||
v := int64(binary.LittleEndian.Uint64(buf[:8]))
|
||||
return Value{Type: TypeInt64, intVal: v}, 8, nil
|
||||
|
||||
case TypeDouble:
|
||||
if len(buf) < 8 {
|
||||
return Value{}, 0, ErrStorageTruncated
|
||||
return Value{}, 0, ErrorStorageTruncated
|
||||
}
|
||||
bits := binary.LittleEndian.Uint64(buf[:8])
|
||||
return Value{Type: TypeDouble, floatVal: math.Float64frombits(bits)}, 8, nil
|
||||
|
||||
case TypeUint32:
|
||||
if len(buf) < 4 {
|
||||
return Value{}, 0, ErrStorageTruncated
|
||||
return Value{}, 0, ErrorStorageTruncated
|
||||
}
|
||||
v := binary.LittleEndian.Uint32(buf[:4])
|
||||
return Value{Type: TypeUint32, uintVal: uint64(v)}, 4, nil
|
||||
|
||||
case TypeInt32:
|
||||
if len(buf) < 4 {
|
||||
return Value{}, 0, ErrStorageTruncated
|
||||
return Value{}, 0, ErrorStorageTruncated
|
||||
}
|
||||
v := int32(binary.LittleEndian.Uint32(buf[:4]))
|
||||
return Value{Type: TypeInt32, intVal: int64(v)}, 4, nil
|
||||
|
||||
case TypeUint16:
|
||||
if len(buf) < 2 {
|
||||
return Value{}, 0, ErrStorageTruncated
|
||||
return Value{}, 0, ErrorStorageTruncated
|
||||
}
|
||||
v := binary.LittleEndian.Uint16(buf[:2])
|
||||
return Value{Type: TypeUint16, uintVal: uint64(v)}, 2, nil
|
||||
|
||||
case TypeInt16:
|
||||
if len(buf) < 2 {
|
||||
return Value{}, 0, ErrStorageTruncated
|
||||
return Value{}, 0, ErrorStorageTruncated
|
||||
}
|
||||
v := int16(binary.LittleEndian.Uint16(buf[:2]))
|
||||
return Value{Type: TypeInt16, intVal: int64(v)}, 2, nil
|
||||
|
||||
case TypeUint8:
|
||||
if len(buf) < 1 {
|
||||
return Value{}, 0, ErrStorageTruncated
|
||||
return Value{}, 0, ErrorStorageTruncated
|
||||
}
|
||||
return Value{Type: TypeUint8, uintVal: uint64(buf[0])}, 1, nil
|
||||
|
||||
case TypeInt8:
|
||||
if len(buf) < 1 {
|
||||
return Value{}, 0, ErrStorageTruncated
|
||||
return Value{}, 0, ErrorStorageTruncated
|
||||
}
|
||||
return Value{Type: TypeInt8, intVal: int64(int8(buf[0]))}, 1, nil
|
||||
|
||||
case TypeBool:
|
||||
if len(buf) < 1 {
|
||||
return Value{}, 0, ErrStorageTruncated
|
||||
return Value{}, 0, ErrorStorageTruncated
|
||||
}
|
||||
return Value{Type: TypeBool, boolVal: buf[0] != 0}, 1, nil
|
||||
|
||||
|
|
@ -638,7 +656,7 @@ func decodeValue(buf []byte, tag uint8) (Value, int, error) {
|
|||
return Value{}, 0, err
|
||||
}
|
||||
if uint64(len(buf)-n) < strLen {
|
||||
return Value{}, 0, ErrStorageTruncated
|
||||
return Value{}, 0, ErrorStorageTruncated
|
||||
}
|
||||
data := make([]byte, strLen)
|
||||
copy(data, buf[n:n+int(strLen)])
|
||||
|
|
@ -652,7 +670,7 @@ func decodeValue(buf []byte, tag uint8) (Value, int, error) {
|
|||
return Value{Type: TypeObject, objectVal: sec}, consumed, nil
|
||||
|
||||
default:
|
||||
return Value{}, 0, core.E("levin.decodeValue", core.Sprintf("unknown type tag: 0x%02x", tag), ErrStorageUnknownType)
|
||||
return Value{}, 0, core.E("levin.decodeValue", core.Sprintf("unknown type tag: 0x%02x", tag), ErrorStorageUnknownType)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -671,7 +689,7 @@ func decodeArray(buf []byte, tag uint8) (Value, int, error) {
|
|||
arr := make([]uint64, count)
|
||||
for i := range count {
|
||||
if off+8 > len(buf) {
|
||||
return Value{}, 0, ErrStorageTruncated
|
||||
return Value{}, 0, ErrorStorageTruncated
|
||||
}
|
||||
arr[i] = binary.LittleEndian.Uint64(buf[off : off+8])
|
||||
off += 8
|
||||
|
|
@ -682,7 +700,7 @@ func decodeArray(buf []byte, tag uint8) (Value, int, error) {
|
|||
arr := make([]uint32, count)
|
||||
for i := range count {
|
||||
if off+4 > len(buf) {
|
||||
return Value{}, 0, ErrStorageTruncated
|
||||
return Value{}, 0, ErrorStorageTruncated
|
||||
}
|
||||
arr[i] = binary.LittleEndian.Uint32(buf[off : off+4])
|
||||
off += 4
|
||||
|
|
@ -698,7 +716,7 @@ func decodeArray(buf []byte, tag uint8) (Value, int, error) {
|
|||
}
|
||||
off += sn
|
||||
if uint64(len(buf)-off) < strLen {
|
||||
return Value{}, 0, ErrStorageTruncated
|
||||
return Value{}, 0, ErrorStorageTruncated
|
||||
}
|
||||
data := make([]byte, strLen)
|
||||
copy(data, buf[off:off+int(strLen)])
|
||||
|
|
@ -720,6 +738,6 @@ func decodeArray(buf []byte, tag uint8) (Value, int, error) {
|
|||
return Value{Type: tag, objectArray: arr}, off, nil
|
||||
|
||||
default:
|
||||
return Value{}, 0, core.E("levin.decodeArray", core.Sprintf("unknown type tag: array of 0x%02x", elemType), ErrStorageUnknownType)
|
||||
return Value{}, 0, core.E("levin.decodeArray", core.Sprintf("unknown type tag: array of 0x%02x", elemType), ErrorStorageUnknownType)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,11 +22,17 @@ const (
|
|||
varintMax8 = 4_611_686_018_427_387_903
|
||||
)
|
||||
|
||||
// ErrVarintTruncated is returned when the buffer is too short.
|
||||
var ErrVarintTruncated = core.E("levin", "truncated varint", nil)
|
||||
// ErrorVarintTruncated is returned when the buffer is too short.
|
||||
var ErrorVarintTruncated = core.E("levin", "truncated varint", nil)
|
||||
|
||||
// ErrVarintOverflow is returned when the value is too large to encode.
|
||||
var ErrVarintOverflow = core.E("levin", "varint overflow", nil)
|
||||
// Deprecated: use ErrorVarintTruncated.
|
||||
var ErrVarintTruncated = ErrorVarintTruncated
|
||||
|
||||
// ErrorVarintOverflow is returned when the value is too large to encode.
|
||||
var ErrorVarintOverflow = core.E("levin", "varint overflow", nil)
|
||||
|
||||
// Deprecated: use ErrorVarintOverflow.
|
||||
var ErrVarintOverflow = ErrorVarintOverflow
|
||||
|
||||
// PackVarint encodes v using the epee portable-storage varint scheme.
|
||||
// The low two bits of the first byte indicate the total encoded width;
|
||||
|
|
@ -61,7 +67,7 @@ func PackVarint(v uint64) []byte {
|
|||
// value, err := UnpackVarint(data)
|
||||
func UnpackVarint(buf []byte) (value uint64, bytesConsumed int, err error) {
|
||||
if len(buf) == 0 {
|
||||
return 0, 0, ErrVarintTruncated
|
||||
return 0, 0, ErrorVarintTruncated
|
||||
}
|
||||
|
||||
mark := buf[0] & varintMask
|
||||
|
|
@ -72,27 +78,27 @@ func UnpackVarint(buf []byte) (value uint64, bytesConsumed int, err error) {
|
|||
return value, 1, nil
|
||||
case varintMark2:
|
||||
if len(buf) < 2 {
|
||||
return 0, 0, ErrVarintTruncated
|
||||
return 0, 0, ErrorVarintTruncated
|
||||
}
|
||||
raw := binary.LittleEndian.Uint16(buf[:2])
|
||||
value = uint64(raw) >> 2
|
||||
return value, 2, nil
|
||||
case varintMark4:
|
||||
if len(buf) < 4 {
|
||||
return 0, 0, ErrVarintTruncated
|
||||
return 0, 0, ErrorVarintTruncated
|
||||
}
|
||||
raw := binary.LittleEndian.Uint32(buf[:4])
|
||||
value = uint64(raw) >> 2
|
||||
return value, 4, nil
|
||||
case varintMark8:
|
||||
if len(buf) < 8 {
|
||||
return 0, 0, ErrVarintTruncated
|
||||
return 0, 0, ErrorVarintTruncated
|
||||
}
|
||||
raw := binary.LittleEndian.Uint64(buf[:8])
|
||||
value = raw >> 2
|
||||
return value, 8, nil
|
||||
default:
|
||||
// Unreachable — mark is masked to 2 bits.
|
||||
return 0, 0, ErrVarintTruncated
|
||||
return 0, 0, ErrorVarintTruncated
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@ import (
|
|||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// Protocol version constants
|
||||
// Protocol version constants.
|
||||
const (
|
||||
// ProtocolVersion is the current protocol version
|
||||
// ProtocolVersion is the current protocol version.
|
||||
ProtocolVersion = "1.0"
|
||||
// MinProtocolVersion is the minimum supported version
|
||||
// MinProtocolVersion is the minimum supported version.
|
||||
MinProtocolVersion = "1.0"
|
||||
)
|
||||
|
||||
|
|
@ -273,26 +273,44 @@ type DeployAckPayload struct {
|
|||
|
||||
// ErrorPayload contains error information.
|
||||
//
|
||||
// payload := ErrorPayload{Code: ErrCodeOperationFailed, Message: "start failed"}
|
||||
// payload := ErrorPayload{Code: ErrorCodeOperationFailed, Message: "start failed"}
|
||||
type ErrorPayload struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Details string `json:"details,omitempty"`
|
||||
}
|
||||
|
||||
// Common error codes
|
||||
// Common error codes.
|
||||
const (
|
||||
ErrCodeUnknown = 1000
|
||||
ErrCodeInvalidMessage = 1001
|
||||
ErrCodeUnauthorized = 1002
|
||||
ErrCodeNotFound = 1003
|
||||
ErrCodeOperationFailed = 1004
|
||||
ErrCodeTimeout = 1005
|
||||
ErrorCodeUnknown = 1000
|
||||
ErrorCodeInvalidMessage = 1001
|
||||
ErrorCodeUnauthorized = 1002
|
||||
ErrorCodeNotFound = 1003
|
||||
ErrorCodeOperationFailed = 1004
|
||||
ErrorCodeTimeout = 1005
|
||||
|
||||
// Deprecated: use ErrorCodeUnknown.
|
||||
ErrCodeUnknown = ErrorCodeUnknown
|
||||
|
||||
// Deprecated: use ErrorCodeInvalidMessage.
|
||||
ErrCodeInvalidMessage = ErrorCodeInvalidMessage
|
||||
|
||||
// Deprecated: use ErrorCodeUnauthorized.
|
||||
ErrCodeUnauthorized = ErrorCodeUnauthorized
|
||||
|
||||
// Deprecated: use ErrorCodeNotFound.
|
||||
ErrCodeNotFound = ErrorCodeNotFound
|
||||
|
||||
// Deprecated: use ErrorCodeOperationFailed.
|
||||
ErrCodeOperationFailed = ErrorCodeOperationFailed
|
||||
|
||||
// Deprecated: use ErrorCodeTimeout.
|
||||
ErrCodeTimeout = ErrorCodeTimeout
|
||||
)
|
||||
|
||||
// NewErrorMessage creates an error response message.
|
||||
//
|
||||
// msg, err := NewErrorMessage("worker", "controller", ErrCodeOperationFailed, "miner start failed", "req-1")
|
||||
// msg, err := NewErrorMessage("worker", "controller", ErrorCodeOperationFailed, "miner start failed", "req-1")
|
||||
func NewErrorMessage(from, to string, code int, message string, replyTo string) (*Message, error) {
|
||||
msg, err := NewMessage(MsgError, from, to, ErrorPayload{
|
||||
Code: code,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import (
|
|||
|
||||
// ProtocolError represents an error from the remote peer.
|
||||
//
|
||||
// err := &ProtocolError{Code: ErrCodeOperationFailed, Message: "start failed"}
|
||||
// err := &ProtocolError{Code: ErrorCodeOperationFailed, Message: "start failed"}
|
||||
type ProtocolError struct {
|
||||
Code int
|
||||
Message string
|
||||
|
|
@ -35,7 +35,7 @@ func (h *ResponseHandler) ValidateResponse(resp *Message, expectedType MessageTy
|
|||
if resp.Type == MsgError {
|
||||
var errPayload ErrorPayload
|
||||
if err := resp.ParsePayload(&errPayload); err != nil {
|
||||
return &ProtocolError{Code: ErrCodeUnknown, Message: "unable to parse error response"}
|
||||
return &ProtocolError{Code: ErrorCodeUnknown, Message: "unable to parse error response"}
|
||||
}
|
||||
return &ProtocolError{Code: errPayload.Code, Message: errPayload.Message}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -641,7 +641,7 @@ func (t *Transport) performHandshake(pc *PeerConnection) error {
|
|||
|
||||
identity := t.node.GetIdentity()
|
||||
if identity == nil {
|
||||
return ErrIdentityNotInitialized
|
||||
return ErrorIdentityNotInitialized
|
||||
}
|
||||
|
||||
// Generate challenge for the server to prove it has the matching private key
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ func (w *Worker) HandleMessage(conn *PeerConnection, msg *Message) {
|
|||
errMsg, _ := NewErrorMessage(
|
||||
identity.ID,
|
||||
msg.From,
|
||||
ErrCodeOperationFailed,
|
||||
ErrorCodeOperationFailed,
|
||||
err.Error(),
|
||||
msg.ID,
|
||||
)
|
||||
|
|
@ -141,7 +141,7 @@ func (w *Worker) handlePing(msg *Message) (*Message, error) {
|
|||
func (w *Worker) handleGetStats(msg *Message) (*Message, error) {
|
||||
identity := w.node.GetIdentity()
|
||||
if identity == nil {
|
||||
return nil, ErrIdentityNotInitialized
|
||||
return nil, ErrorIdentityNotInitialized
|
||||
}
|
||||
|
||||
stats := StatsPayload{
|
||||
|
|
@ -204,7 +204,7 @@ func convertMinerStats(miner MinerInstance, rawStats any) MinerStatsItem {
|
|||
// handleStartMiner starts a miner with the given profile.
|
||||
func (w *Worker) handleStartMiner(msg *Message) (*Message, error) {
|
||||
if w.minerManager == nil {
|
||||
return nil, ErrMinerManagerNotConfigured
|
||||
return nil, ErrorMinerManagerNotConfigured
|
||||
}
|
||||
|
||||
var payload StartMinerPayload
|
||||
|
|
@ -251,7 +251,7 @@ func (w *Worker) handleStartMiner(msg *Message) (*Message, error) {
|
|||
// handleStopMiner stops a running miner.
|
||||
func (w *Worker) handleStopMiner(msg *Message) (*Message, error) {
|
||||
if w.minerManager == nil {
|
||||
return nil, ErrMinerManagerNotConfigured
|
||||
return nil, ErrorMinerManagerNotConfigured
|
||||
}
|
||||
|
||||
var payload StopMinerPayload
|
||||
|
|
@ -274,7 +274,7 @@ func (w *Worker) handleStopMiner(msg *Message) (*Message, error) {
|
|||
// handleGetLogs returns console logs from a miner.
|
||||
func (w *Worker) handleGetLogs(msg *Message) (*Message, error) {
|
||||
if w.minerManager == nil {
|
||||
return nil, ErrMinerManagerNotConfigured
|
||||
return nil, ErrorMinerManagerNotConfigured
|
||||
}
|
||||
|
||||
var payload GetLogsPayload
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue