Skip to content

Commit

Permalink
chore: remove CodeError
Browse files Browse the repository at this point in the history
  • Loading branch information
achingbrain committed Sep 9, 2024
1 parent a993667 commit 2949a4f
Show file tree
Hide file tree
Showing 10 changed files with 3,260 additions and 2,023 deletions.
5,105 changes: 3,170 additions & 1,935 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
"it-pipe": "^3.0.1",
"it-pushable": "^3.2.3",
"multiformats": "^13.0.1",
"protons-runtime": "5.4.0",
"protons-runtime": "^5.5.0",
"uint8arraylist": "^2.4.8",
"uint8arrays": "^5.0.1"
},
Expand All @@ -100,8 +100,8 @@
"aegir": "^42.2.2",
"datastore-core": "^9.2.7",
"delay": "^6.0.0",
"mkdirp": "^3.0.1",
"it-all": "^3.0.6",
"mkdirp": "^3.0.1",
"p-defer": "^4.0.0",
"p-event": "^6.0.0",
"p-retry": "^6.2.0",
Expand Down
17 changes: 17 additions & 0 deletions src/errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export class InvalidPeerScoreParamsError extends Error {
static name = 'InvalidPeerScoreParamsError'

constructor (message = 'Invalid peer score params') {
super(message)
this.name = 'InvalidPeerScoreParamsError'
}
}

export class InvalidPeerScoreThresholdsError extends Error {
static name = 'InvalidPeerScoreThresholdsError'

constructor (message = 'Invalid peer score thresholds') {
super(message)
this.name = 'InvalidPeerScoreThresholdsError'
}
}
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2613,7 +2613,7 @@ export class GossipSub extends TypedEventEmitter<GossipsubEvents> implements Pub
try {
peerInfo = await this.components.peerStore.get(id)
} catch (err: any) {
if (err.code !== 'ERR_NOT_FOUND') {
if (err.name !== 'NotFoundError') {
throw err
}
}
Expand Down
52 changes: 34 additions & 18 deletions src/message/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
/* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
/* eslint-disable @typescript-eslint/no-empty-interface */

import { type Codec, CodeError, decodeMessage, type DecodeOptions, encodeMessage, message } from 'protons-runtime'
import { type Codec, decodeMessage, type DecodeOptions, encodeMessage, MaxLengthError, message } from 'protons-runtime'
import type { Uint8ArrayList } from 'uint8arraylist'

export interface RPC {
Expand Down Expand Up @@ -256,34 +256,42 @@ export namespace RPC {
switch (tag >>> 3) {
case 1: {
if (opts.limits?.ihave != null && obj.ihave.length === opts.limits.ihave) {
throw new CodeError('decode error - map field "ihave" had too many elements', 'ERR_MAX_LENGTH')
throw new MaxLengthError('Decode error - map field "ihave" had too many elements')
}

obj.ihave.push(RPC.ControlIHave.codec().decode(reader, reader.uint32()))
obj.ihave.push(RPC.ControlIHave.codec().decode(reader, reader.uint32(), {
limits: opts.limits?.ihave$
}))
break
}
case 2: {
if (opts.limits?.iwant != null && obj.iwant.length === opts.limits.iwant) {
throw new CodeError('decode error - map field "iwant" had too many elements', 'ERR_MAX_LENGTH')
throw new MaxLengthError('Decode error - map field "iwant" had too many elements')
}

obj.iwant.push(RPC.ControlIWant.codec().decode(reader, reader.uint32()))
obj.iwant.push(RPC.ControlIWant.codec().decode(reader, reader.uint32(), {
limits: opts.limits?.iwant$
}))
break
}
case 3: {
if (opts.limits?.graft != null && obj.graft.length === opts.limits.graft) {
throw new CodeError('decode error - map field "graft" had too many elements', 'ERR_MAX_LENGTH')
throw new MaxLengthError('Decode error - map field "graft" had too many elements')
}

obj.graft.push(RPC.ControlGraft.codec().decode(reader, reader.uint32()))
obj.graft.push(RPC.ControlGraft.codec().decode(reader, reader.uint32(), {
limits: opts.limits?.graft$
}))
break
}
case 4: {
if (opts.limits?.prune != null && obj.prune.length === opts.limits.prune) {
throw new CodeError('decode error - map field "prune" had too many elements', 'ERR_MAX_LENGTH')
throw new MaxLengthError('Decode error - map field "prune" had too many elements')
}

obj.prune.push(RPC.ControlPrune.codec().decode(reader, reader.uint32()))
obj.prune.push(RPC.ControlPrune.codec().decode(reader, reader.uint32(), {
limits: opts.limits?.prune$
}))
break
}
default: {
Expand Down Expand Up @@ -356,7 +364,7 @@ export namespace RPC {
}
case 2: {
if (opts.limits?.messageIDs != null && obj.messageIDs.length === opts.limits.messageIDs) {
throw new CodeError('decode error - map field "messageIDs" had too many elements', 'ERR_MAX_LENGTH')
throw new MaxLengthError('Decode error - map field "messageIDs" had too many elements')
}

obj.messageIDs.push(reader.bytes())
Expand Down Expand Up @@ -422,7 +430,7 @@ export namespace RPC {
switch (tag >>> 3) {
case 1: {
if (opts.limits?.messageIDs != null && obj.messageIDs.length === opts.limits.messageIDs) {
throw new CodeError('decode error - map field "messageIDs" had too many elements', 'ERR_MAX_LENGTH')
throw new MaxLengthError('Decode error - map field "messageIDs" had too many elements')
}

obj.messageIDs.push(reader.bytes())
Expand Down Expand Up @@ -562,10 +570,12 @@ export namespace RPC {
}
case 2: {
if (opts.limits?.peers != null && obj.peers.length === opts.limits.peers) {
throw new CodeError('decode error - map field "peers" had too many elements', 'ERR_MAX_LENGTH')
throw new MaxLengthError('Decode error - map field "peers" had too many elements')
}

obj.peers.push(RPC.PeerInfo.codec().decode(reader, reader.uint32()))
obj.peers.push(RPC.PeerInfo.codec().decode(reader, reader.uint32(), {
limits: opts.limits?.peers$
}))
break
}
case 3: {
Expand Down Expand Up @@ -708,22 +718,28 @@ export namespace RPC {
switch (tag >>> 3) {
case 1: {
if (opts.limits?.subscriptions != null && obj.subscriptions.length === opts.limits.subscriptions) {
throw new CodeError('decode error - map field "subscriptions" had too many elements', 'ERR_MAX_LENGTH')
throw new MaxLengthError('Decode error - map field "subscriptions" had too many elements')
}

obj.subscriptions.push(RPC.SubOpts.codec().decode(reader, reader.uint32()))
obj.subscriptions.push(RPC.SubOpts.codec().decode(reader, reader.uint32(), {
limits: opts.limits?.subscriptions$
}))
break
}
case 2: {
if (opts.limits?.messages != null && obj.messages.length === opts.limits.messages) {
throw new CodeError('decode error - map field "messages" had too many elements', 'ERR_MAX_LENGTH')
throw new MaxLengthError('Decode error - map field "messages" had too many elements')
}

obj.messages.push(RPC.Message.codec().decode(reader, reader.uint32()))
obj.messages.push(RPC.Message.codec().decode(reader, reader.uint32(), {
limits: opts.limits?.messages$
}))
break
}
case 3: {
obj.control = RPC.ControlMessage.codec().decode(reader, reader.uint32())
obj.control = RPC.ControlMessage.codec().decode(reader, reader.uint32(), {
limits: opts.limits?.control
})
break
}
default: {
Expand Down
2 changes: 0 additions & 2 deletions src/score/constants.ts

This file was deleted.

78 changes: 28 additions & 50 deletions src/score/peer-score-params.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { CodeError } from '@libp2p/interface'
import { ERR_INVALID_PEER_SCORE_PARAMS } from './constants.js'
import { InvalidPeerScoreParamsError } from '../errors.js'

// This file defines PeerScoreParams and TopicScoreParams interfaces
// as well as constructors, default constructors, and validation functions
Expand Down Expand Up @@ -203,51 +202,42 @@ export function validatePeerScoreParams (p: PeerScoreParams): void {
try {
validateTopicScoreParams(params)
} catch (e) {
throw new CodeError(
`invalid score parameters for topic ${topic}: ${(e as Error).message}`,
ERR_INVALID_PEER_SCORE_PARAMS
)
throw new InvalidPeerScoreParamsError(`invalid score parameters for topic ${topic}: ${(e as Error).message}`)
}
}

// check that the topic score is 0 or something positive
if (p.topicScoreCap < 0) {
throw new CodeError('invalid topic score cap; must be positive (or 0 for no cap)', ERR_INVALID_PEER_SCORE_PARAMS)
throw new InvalidPeerScoreParamsError('invalid topic score cap; must be positive (or 0 for no cap)')
}

// check that we have an app specific score; the weight can be anything (but expected positive)
if (p.appSpecificScore === null || p.appSpecificScore === undefined) {
throw new CodeError('missing application specific score function', ERR_INVALID_PEER_SCORE_PARAMS)
throw new InvalidPeerScoreParamsError('missing application specific score function')
}

// check the IP colocation factor
if (p.IPColocationFactorWeight > 0) {
throw new CodeError(
'invalid IPColocationFactorWeight; must be negative (or 0 to disable)',
ERR_INVALID_PEER_SCORE_PARAMS
)
throw new InvalidPeerScoreParamsError('invalid IPColocationFactorWeight; must be negative (or 0 to disable)')
}
if (p.IPColocationFactorWeight !== 0 && p.IPColocationFactorThreshold < 1) {
throw new CodeError('invalid IPColocationFactorThreshold; must be at least 1', ERR_INVALID_PEER_SCORE_PARAMS)
throw new InvalidPeerScoreParamsError('invalid IPColocationFactorThreshold; must be at least 1')
}

// check the behaviour penalty
if (p.behaviourPenaltyWeight > 0) {
throw new CodeError(
'invalid BehaviourPenaltyWeight; must be negative (or 0 to disable)',
ERR_INVALID_PEER_SCORE_PARAMS
)
throw new InvalidPeerScoreParamsError('invalid BehaviourPenaltyWeight; must be negative (or 0 to disable)')
}
if (p.behaviourPenaltyWeight !== 0 && (p.behaviourPenaltyDecay <= 0 || p.behaviourPenaltyDecay >= 1)) {
throw new CodeError('invalid BehaviourPenaltyDecay; must be between 0 and 1', ERR_INVALID_PEER_SCORE_PARAMS)
throw new InvalidPeerScoreParamsError('invalid BehaviourPenaltyDecay; must be between 0 and 1')
}

// check the decay parameters
if (p.decayInterval < 1000) {
throw new CodeError('invalid DecayInterval; must be at least 1s', ERR_INVALID_PEER_SCORE_PARAMS)
throw new InvalidPeerScoreParamsError('invalid DecayInterval; must be at least 1s')
}
if (p.decayToZero <= 0 || p.decayToZero >= 1) {
throw new CodeError('invalid DecayToZero; must be between 0 and 1', ERR_INVALID_PEER_SCORE_PARAMS)
throw new InvalidPeerScoreParamsError('invalid DecayToZero; must be between 0 and 1')
}

// no need to check the score retention; a value of 0 means that we don't retain scores
Expand All @@ -257,82 +247,70 @@ export function validatePeerScoreParams (p: PeerScoreParams): void {
export function validateTopicScoreParams (p: TopicScoreParams): void {
// make sure we have a sane topic weight
if (p.topicWeight < 0) {
throw new CodeError('invalid topic weight; must be >= 0', ERR_INVALID_PEER_SCORE_PARAMS)
throw new InvalidPeerScoreParamsError('invalid topic weight; must be >= 0')
}

// check P1
if (p.timeInMeshQuantum === 0) {
throw new CodeError('invalid TimeInMeshQuantum; must be non zero', ERR_INVALID_PEER_SCORE_PARAMS)
throw new InvalidPeerScoreParamsError('invalid TimeInMeshQuantum; must be non zero')
}
if (p.timeInMeshWeight < 0) {
throw new CodeError('invalid TimeInMeshWeight; must be positive (or 0 to disable)', ERR_INVALID_PEER_SCORE_PARAMS)
throw new InvalidPeerScoreParamsError('invalid TimeInMeshWeight; must be positive (or 0 to disable)')
}
if (p.timeInMeshWeight !== 0 && p.timeInMeshQuantum <= 0) {
throw new CodeError('invalid TimeInMeshQuantum; must be positive', ERR_INVALID_PEER_SCORE_PARAMS)
throw new InvalidPeerScoreParamsError('invalid TimeInMeshQuantum; must be positive')
}
if (p.timeInMeshWeight !== 0 && p.timeInMeshCap <= 0) {
throw new CodeError('invalid TimeInMeshCap; must be positive', ERR_INVALID_PEER_SCORE_PARAMS)
throw new InvalidPeerScoreParamsError('invalid TimeInMeshCap; must be positive')
}

// check P2
if (p.firstMessageDeliveriesWeight < 0) {
throw new CodeError(
'invallid FirstMessageDeliveriesWeight; must be positive (or 0 to disable)',
ERR_INVALID_PEER_SCORE_PARAMS
)
throw new InvalidPeerScoreParamsError('invallid FirstMessageDeliveriesWeight; must be positive (or 0 to disable)')
}
if (
p.firstMessageDeliveriesWeight !== 0 &&
(p.firstMessageDeliveriesDecay <= 0 || p.firstMessageDeliveriesDecay >= 1)
) {
throw new CodeError('invalid FirstMessageDeliveriesDecay; must be between 0 and 1', ERR_INVALID_PEER_SCORE_PARAMS)
throw new InvalidPeerScoreParamsError('invalid FirstMessageDeliveriesDecay; must be between 0 and 1')
}
if (p.firstMessageDeliveriesWeight !== 0 && p.firstMessageDeliveriesCap <= 0) {
throw new CodeError('invalid FirstMessageDeliveriesCap; must be positive', ERR_INVALID_PEER_SCORE_PARAMS)
throw new InvalidPeerScoreParamsError('invalid FirstMessageDeliveriesCap; must be positive')
}

// check P3
if (p.meshMessageDeliveriesWeight > 0) {
throw new CodeError(
'invalid MeshMessageDeliveriesWeight; must be negative (or 0 to disable)',
ERR_INVALID_PEER_SCORE_PARAMS
)
throw new InvalidPeerScoreParamsError('invalid MeshMessageDeliveriesWeight; must be negative (or 0 to disable)')
}
if (p.meshMessageDeliveriesWeight !== 0 && (p.meshMessageDeliveriesDecay <= 0 || p.meshMessageDeliveriesDecay >= 1)) {
throw new CodeError('invalid MeshMessageDeliveriesDecay; must be between 0 and 1', ERR_INVALID_PEER_SCORE_PARAMS)
throw new InvalidPeerScoreParamsError('invalid MeshMessageDeliveriesDecay; must be between 0 and 1')
}
if (p.meshMessageDeliveriesWeight !== 0 && p.meshMessageDeliveriesCap <= 0) {
throw new CodeError('invalid MeshMessageDeliveriesCap; must be positive', ERR_INVALID_PEER_SCORE_PARAMS)
throw new InvalidPeerScoreParamsError('invalid MeshMessageDeliveriesCap; must be positive')
}
if (p.meshMessageDeliveriesWeight !== 0 && p.meshMessageDeliveriesThreshold <= 0) {
throw new CodeError('invalid MeshMessageDeliveriesThreshold; must be positive', ERR_INVALID_PEER_SCORE_PARAMS)
throw new InvalidPeerScoreParamsError('invalid MeshMessageDeliveriesThreshold; must be positive')
}
if (p.meshMessageDeliveriesWindow < 0) {
throw new CodeError('invalid MeshMessageDeliveriesWindow; must be non-negative', ERR_INVALID_PEER_SCORE_PARAMS)
throw new InvalidPeerScoreParamsError('invalid MeshMessageDeliveriesWindow; must be non-negative')
}
if (p.meshMessageDeliveriesWeight !== 0 && p.meshMessageDeliveriesActivation < 1000) {
throw new CodeError('invalid MeshMessageDeliveriesActivation; must be at least 1s', ERR_INVALID_PEER_SCORE_PARAMS)
throw new InvalidPeerScoreParamsError('invalid MeshMessageDeliveriesActivation; must be at least 1s')
}

// check P3b
if (p.meshFailurePenaltyWeight > 0) {
throw new CodeError(
'invalid MeshFailurePenaltyWeight; must be negative (or 0 to disable)',
ERR_INVALID_PEER_SCORE_PARAMS
)
throw new InvalidPeerScoreParamsError('invalid MeshFailurePenaltyWeight; must be negative (or 0 to disable)')
}
if (p.meshFailurePenaltyWeight !== 0 && (p.meshFailurePenaltyDecay <= 0 || p.meshFailurePenaltyDecay >= 1)) {
throw new CodeError('invalid MeshFailurePenaltyDecay; must be between 0 and 1', ERR_INVALID_PEER_SCORE_PARAMS)
throw new InvalidPeerScoreParamsError('invalid MeshFailurePenaltyDecay; must be between 0 and 1')
}

// check P4
if (p.invalidMessageDeliveriesWeight > 0) {
throw new CodeError(
'invalid InvalidMessageDeliveriesWeight; must be negative (or 0 to disable)',
ERR_INVALID_PEER_SCORE_PARAMS
)
throw new InvalidPeerScoreParamsError('invalid InvalidMessageDeliveriesWeight; must be negative (or 0 to disable)')
}
if (p.invalidMessageDeliveriesDecay <= 0 || p.invalidMessageDeliveriesDecay >= 1) {
throw new CodeError('invalid InvalidMessageDeliveriesDecay; must be between 0 and 1', ERR_INVALID_PEER_SCORE_PARAMS)
throw new InvalidPeerScoreParamsError('invalid InvalidMessageDeliveriesDecay; must be between 0 and 1')
}
}
19 changes: 6 additions & 13 deletions src/score/peer-score-thresholds.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { CodeError } from '@libp2p/interface'
import { ERR_INVALID_PEER_SCORE_THRESHOLDS } from './constants.js'
import { InvalidPeerScoreThresholdsError } from '../errors.js'

// This file defines PeerScoreThresholds interface
// as well as a constructor, default constructor, and validation function
Expand Down Expand Up @@ -54,24 +53,18 @@ export function createPeerScoreThresholds (p: Partial<PeerScoreThresholds> = {})

export function validatePeerScoreThresholds (p: PeerScoreThresholds): void {
if (p.gossipThreshold > 0) {
throw new CodeError('invalid gossip threshold; it must be <= 0', ERR_INVALID_PEER_SCORE_THRESHOLDS)
throw new InvalidPeerScoreThresholdsError('invalid gossip threshold; it must be <= 0')
}
if (p.publishThreshold > 0 || p.publishThreshold > p.gossipThreshold) {
throw new CodeError(
'invalid publish threshold; it must be <= 0 and <= gossip threshold',
ERR_INVALID_PEER_SCORE_THRESHOLDS
)
throw new InvalidPeerScoreThresholdsError('invalid publish threshold; it must be <= 0 and <= gossip threshold')
}
if (p.graylistThreshold > 0 || p.graylistThreshold > p.publishThreshold) {
throw new CodeError(
'invalid graylist threshold; it must be <= 0 and <= publish threshold',
ERR_INVALID_PEER_SCORE_THRESHOLDS
)
throw new InvalidPeerScoreThresholdsError('invalid graylist threshold; it must be <= 0 and <= publish threshold')
}
if (p.acceptPXThreshold < 0) {
throw new CodeError('invalid accept PX threshold; it must be >= 0', ERR_INVALID_PEER_SCORE_THRESHOLDS)
throw new InvalidPeerScoreThresholdsError('invalid accept PX threshold; it must be >= 0')
}
if (p.opportunisticGraftThreshold < 0) {
throw new CodeError('invalid opportunistic grafting threshold; it must be >= 0', ERR_INVALID_PEER_SCORE_THRESHOLDS)
throw new InvalidPeerScoreThresholdsError('invalid opportunistic grafting threshold; it must be >= 0')
}
}
2 changes: 1 addition & 1 deletion test/floodsub.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ describe('gossipsub fallbacks to floodsub', () => {
await connectPubsubNodes(nodeGs, nodeFs)
expect.fail('Dial should not have succeed')
} catch (err) {
expect((err as { code: string }).code).to.be.equal('ERR_UNSUPPORTED_PROTOCOL')
expect(err).to.have.property('name', 'UnsupportedProtocolError')
}
})
})
Expand Down
2 changes: 1 addition & 1 deletion test/gossip.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ describe('gossip', () => {
await nodeA.pubsub.publish(topic, new Uint8Array(5000000))
await pEvent(nodeA.pubsub, 'gossipsub:heartbeat')
const expectedError = nodeBSpy.handlePeerReadStreamError.getCalls()[0]?.args[0]
expect(expectedError !== undefined && (expectedError as unknown as { code: string }).code, 'ERR_MSG_DATA_TOO_LONG')
expect(expectedError).to.have.property('name', 'InvalidDataLengthError')

// unset spy
nodeBSpy.handlePeerReadStreamError.restore()
Expand Down

0 comments on commit 2949a4f

Please sign in to comment.