Skip to content

Commit

Permalink
feat!: update to [email protected]
Browse files Browse the repository at this point in the history
Incorporates API changes from the upcoming [email protected] release.

BREAKING CHANGE: Can only be used with [email protected] or later
  • Loading branch information
achingbrain committed Sep 2, 2024
1 parent 9e57215 commit a993667
Show file tree
Hide file tree
Showing 12 changed files with 86 additions and 85 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@
"@libp2p/floodsub": "^9.0.9",
"@libp2p/interface-compliance-tests": "^5.2.0",
"@libp2p/logger": "^4.0.5",
"@libp2p/peer-id-factory": "^4.0.5",
"@libp2p/peer-store": "^10.0.8",
"@types/node": "^20.11.6",
"abortable-iterator": "^5.1.0",
Expand Down
27 changes: 15 additions & 12 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { TypedEventEmitter, StrictSign, StrictNoSign, TopicValidatorResult, serviceCapabilities, serviceDependencies } from '@libp2p/interface'
import { peerIdFromBytes, peerIdFromString } from '@libp2p/peer-id'
import { peerIdFromMultihash, peerIdFromString } from '@libp2p/peer-id'

Check failure on line 2 in src/index.ts

View workflow job for this annotation

GitHub Actions / check

Module '"@libp2p/peer-id"' has no exported member 'peerIdFromMultihash'.
import { encode } from 'it-length-prefixed'
import { pipe } from 'it-pipe'
import { pushable } from 'it-pushable'
import * as Digest from 'multiformats/hashes/digest'
import * as constants from './constants.js'
import {
ACCEPT_FROM_WHITELIST_DURATION_MS,
Expand Down Expand Up @@ -73,7 +74,8 @@ import type {
TopicValidatorFn,
Logger,
ComponentLogger,
Topology
Topology,
PrivateKey
} from '@libp2p/interface'
import type { ConnectionManager, IncomingStreamData, Registrar } from '@libp2p/interface-internal'
import type { Multiaddr } from '@multiformats/multiaddr'
Expand Down Expand Up @@ -166,13 +168,13 @@ export interface GossipsubOpts extends GossipsubOptsSpec, PubSubInit {
maxOutboundStreams?: number

/**
* Pass true to run on transient connections - data or time-limited
* Pass true to run on limited connections - data or time-limited
* connections that may be closed at any time such as circuit relay
* connections.
*
* @default false
*/
runOnTransientConnection?: boolean
runOnLimitedConnection?: boolean

/**
* Specify max buffer size in bytes for OutboundStream.
Expand Down Expand Up @@ -259,6 +261,7 @@ interface AcceptFromWhitelistEntry {
}

export interface GossipSubComponents {
privateKey: PrivateKey
peerId: PeerId
peerStore: PeerStore
registrar: Registrar
Expand Down Expand Up @@ -420,7 +423,7 @@ export class GossipSub extends TypedEventEmitter<GossipsubEvents> implements Pub
private status: GossipStatus = { code: GossipStatusCode.stopped }
private readonly maxInboundStreams?: number
private readonly maxOutboundStreams?: number
private readonly runOnTransientConnection?: boolean
private readonly runOnLimitedConnection?: boolean
private readonly allowedTopics: Set<TopicStr> | null

private heartbeatTimer: {
Expand Down Expand Up @@ -554,7 +557,7 @@ export class GossipSub extends TypedEventEmitter<GossipsubEvents> implements Pub

this.maxInboundStreams = options.maxInboundStreams
this.maxOutboundStreams = options.maxOutboundStreams
this.runOnTransientConnection = options.runOnTransientConnection
this.runOnLimitedConnection = options.runOnLimitedConnection

this.allowedTopics = (opts.allowedTopics != null) ? new Set(opts.allowedTopics) : null
}
Expand Down Expand Up @@ -591,7 +594,7 @@ export class GossipSub extends TypedEventEmitter<GossipsubEvents> implements Pub

this.log('starting')

this.publishConfig = await getPublishConfigFromPeerId(this.globalSignaturePolicy, this.components.peerId)
this.publishConfig = getPublishConfigFromPeerId(this.globalSignaturePolicy, this.components.peerId, this.components.privateKey)

// Create the outbound inflight queue
// This ensures that outbound stream creation happens sequentially
Expand Down Expand Up @@ -619,7 +622,7 @@ export class GossipSub extends TypedEventEmitter<GossipsubEvents> implements Pub
registrar.handle(multicodec, this.onIncomingStream.bind(this), {
maxInboundStreams: this.maxInboundStreams,
maxOutboundStreams: this.maxOutboundStreams,
runOnTransientConnection: this.runOnTransientConnection
runOnLimitedConnection: this.runOnLimitedConnection

Check failure on line 625 in src/index.ts

View workflow job for this annotation

GitHub Actions / check

Object literal may only specify known properties, and 'runOnLimitedConnection' does not exist in type 'StreamHandlerOptions'.
})
)
)
Expand All @@ -646,7 +649,7 @@ export class GossipSub extends TypedEventEmitter<GossipsubEvents> implements Pub
const topology: Topology = {
onConnect: this.onPeerConnected.bind(this),
onDisconnect: this.onPeerDisconnected.bind(this),
notifyOnTransient: this.runOnTransientConnection
notifyOnLimitedConnection: this.runOnLimitedConnection

Check failure on line 652 in src/index.ts

View workflow job for this annotation

GitHub Actions / check

Object literal may only specify known properties, and 'notifyOnLimitedConnection' does not exist in type 'Topology'.
}
const registrarTopologyIds = await Promise.all(
this.multicodecs.map(async (multicodec) => registrar.register(multicodec, topology))
Expand Down Expand Up @@ -817,7 +820,7 @@ export class GossipSub extends TypedEventEmitter<GossipsubEvents> implements Pub
try {
const stream = new OutboundStream(
await connection.newStream(this.multicodecs, {
runOnTransientConnection: this.runOnTransientConnection
runOnLimitedConnection: this.runOnLimitedConnection

Check failure on line 823 in src/index.ts

View workflow job for this annotation

GitHub Actions / check

Object literal may only specify known properties, and 'runOnLimitedConnection' does not exist in type 'NewStreamOptions'.
}),
(e) => { this.log.error('outbound pipe error', e) },
{ maxBufferSize: this.opts.maxOutboundBufferSize }
Expand Down Expand Up @@ -1778,7 +1781,7 @@ export class GossipSub extends TypedEventEmitter<GossipsubEvents> implements Pub
return
}

const peer = peerIdFromBytes(pi.peerID)
const peer = peerIdFromMultihash(Digest.decode(pi.peerID))
const p = peer.toString()

if (this.peers.has(p)) {
Expand Down Expand Up @@ -2616,7 +2619,7 @@ export class GossipSub extends TypedEventEmitter<GossipsubEvents> implements Pub
}

return {
peerID: id.toBytes(),
peerID: id.toMultihash().bytes,

Check failure on line 2622 in src/index.ts

View workflow job for this annotation

GitHub Actions / check

Property 'toMultihash' does not exist on type 'Ed25519PeerId | Secp256k1PeerId | RSAPeerId'. Did you mean 'multihash'?
signedPeerRecord: peerInfo?.peerRecordEnvelope
}
})
Expand Down
20 changes: 10 additions & 10 deletions src/utils/buildRawMessage.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { randomBytes } from '@libp2p/crypto'
import { marshalPublicKey, unmarshalPublicKey } from '@libp2p/crypto/keys'
import { publicKeyFromProtobuf } from '@libp2p/crypto/keys'

Check failure on line 2 in src/utils/buildRawMessage.ts

View workflow job for this annotation

GitHub Actions / check

Module '"@libp2p/crypto/keys"' has no exported member 'publicKeyFromProtobuf'.
import { StrictSign, StrictNoSign, type Message, type PublicKey, type PeerId } from '@libp2p/interface'
import { peerIdFromBytes } from '@libp2p/peer-id'
import { peerIdFromMultihash } from '@libp2p/peer-id'

Check failure on line 4 in src/utils/buildRawMessage.ts

View workflow job for this annotation

GitHub Actions / check

Module '"@libp2p/peer-id"' has no exported member 'peerIdFromMultihash'.
import * as Digest from 'multiformats/hashes/digest'
import { concat as uint8ArrayConcat } from 'uint8arrays/concat'
import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
import { RPC } from '../message/rpc.js'
Expand All @@ -25,7 +25,7 @@ export async function buildRawMessage (
switch (publishConfig.type) {
case PublishConfigType.Signing: {
const rpcMsg: RPC.Message = {
from: publishConfig.author.toBytes(),
from: publishConfig.author.toMultihash().bytes,

Check failure on line 28 in src/utils/buildRawMessage.ts

View workflow job for this annotation

GitHub Actions / check

Property 'toMultihash' does not exist on type 'PeerId'. Did you mean 'multihash'?
data: transformedData,
seqno: randomBytes(8),
topic,
Expand All @@ -47,7 +47,7 @@ export async function buildRawMessage (
sequenceNumber: BigInt(`0x${uint8ArrayToString(rpcMsg.seqno as Uint8Array, 'base16')}`),
topic,
signature: rpcMsg.signature,
key: rpcMsg.key
key: publicKeyFromProtobuf(rpcMsg.key)
}
return {
raw: rpcMsg,
Expand Down Expand Up @@ -108,7 +108,7 @@ export async function validateToRawMessage (
let fromPeerId: PeerId
try {
// TODO: Fix PeerId types
fromPeerId = peerIdFromBytes(msg.from)
fromPeerId = peerIdFromMultihash(Digest.decode(msg.from))
} catch (e) {
return { valid: false, error: ValidateError.InvalidPeerId }
}
Expand All @@ -122,16 +122,16 @@ export async function validateToRawMessage (

let publicKey: PublicKey
if (msg.key != null) {
publicKey = unmarshalPublicKey(msg.key)
publicKey = publicKeyFromProtobuf(msg.key)
// TODO: Should `fromPeerId.pubKey` be optional?
if (fromPeerId.publicKey !== undefined && !uint8ArrayEquals(publicKey.bytes, fromPeerId.publicKey)) {
if (fromPeerId.publicKey !== undefined && !publicKey.equals(fromPeerId.publicKey)) {

Check failure on line 127 in src/utils/buildRawMessage.ts

View workflow job for this annotation

GitHub Actions / check

Argument of type 'Uint8Array' is not assignable to parameter of type 'PublicKey<"Ed25519">'.
return { valid: false, error: ValidateError.InvalidPeerId }
}
} else {
if (fromPeerId.publicKey == null) {
return { valid: false, error: ValidateError.InvalidPeerId }
}
publicKey = unmarshalPublicKey(fromPeerId.publicKey)
publicKey = fromPeerId.publicKey

Check failure on line 134 in src/utils/buildRawMessage.ts

View workflow job for this annotation

GitHub Actions / check

Type 'Uint8Array' is not assignable to type 'PublicKey<"Ed25519">'.
}

const rpcMsgPreSign: RPC.Message = {
Expand Down Expand Up @@ -160,7 +160,7 @@ export async function validateToRawMessage (
sequenceNumber: BigInt(`0x${uint8ArrayToString(msg.seqno, 'base16')}`),
topic: msg.topic,
signature: msg.signature,
key: msg.key ?? marshalPublicKey(publicKey)
key: msg.key != null ? publicKeyFromProtobuf(msg.key) : publicKey
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/utils/msgIdFn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function msgIdFnStrictSign (msg: Message): Uint8Array {
if (msg.sequenceNumber == null) throw Error('missing seqno field')

// TODO: Should use .from here or key?
return msgId(msg.from.toBytes(), msg.sequenceNumber)
return msgId(msg.from.publicKey ?? msg.key, msg.sequenceNumber)
}

/**
Expand Down
28 changes: 7 additions & 21 deletions src/utils/publishConfig.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,22 @@
import { unmarshalPrivateKey } from '@libp2p/crypto/keys'
import { publicKeyToProtobuf } from '@libp2p/crypto/keys'
import { StrictSign, StrictNoSign } from '@libp2p/interface'
import { type PublishConfig, PublishConfigType } from '../types.js'
import type { PeerId } from '@libp2p/interface'
import type { PeerId, PrivateKey } from '@libp2p/interface'

/**
* Prepare a PublishConfig object from a PeerId.
*/
export async function getPublishConfigFromPeerId (
export function getPublishConfigFromPeerId (
signaturePolicy: typeof StrictSign | typeof StrictNoSign,
peerId?: PeerId
): Promise<PublishConfig> {
peerId: PeerId,
privateKey: PrivateKey
): PublishConfig {
switch (signaturePolicy) {
case StrictSign: {
if (peerId == null) {
throw Error('Must provide PeerId')
}

if (peerId.privateKey == null) {
throw Error('Cannot sign message, no private key present')
}

if (peerId.publicKey == null) {
throw Error('Cannot sign message, no public key present')
}

// Transform privateKey once at initialization time instead of once per message
const privateKey = await unmarshalPrivateKey(peerId.privateKey)

return {
type: PublishConfigType.Signing,
author: peerId,
key: peerId.publicKey,
key: publicKeyToProtobuf(privateKey.publicKey),
privateKey
}
}
Expand Down
7 changes: 5 additions & 2 deletions test/accept-from.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { generateKeyPair } from '@libp2p/crypto/keys'
import { type PeerStore } from '@libp2p/interface'
import { defaultLogger } from '@libp2p/logger'
import { peerIdFromPrivateKey } from '@libp2p/peer-id'
import { expect } from 'aegir/chai'
import sinon from 'sinon'
import { stubInterface } from 'ts-sinon'
import { GossipSub } from '../src/index.js'
import { createPeerId } from './utils/index.js'
import { fastMsgIdFn } from './utils/msgId.js'
import type { ConnectionManager, Registrar } from '@libp2p/interface-internal'

Expand All @@ -20,9 +21,11 @@ describe('Gossipsub acceptFrom', () => {
// not able to use fake timers or tests in browser are suspended
// sandbox.useFakeTimers(Date.now())

const peerId = await createPeerId()
const privateKey = await generateKeyPair('Ed25519')
const peerId = peerIdFromPrivateKey(privateKey)
gossipsub = new GossipSub(
{
privateKey,
peerId,
registrar: stubInterface<Registrar>(),
peerStore: stubInterface<PeerStore>(),
Expand Down
9 changes: 6 additions & 3 deletions test/gossip.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { generateKeyPair } from '@libp2p/crypto/keys'
import { stop } from '@libp2p/interface'
import { mockNetwork } from '@libp2p/interface-compliance-tests/mocks'
import { defaultLogger } from '@libp2p/logger'
import { createEd25519PeerId } from '@libp2p/peer-id-factory'
import { peerIdFromPrivateKey } from '@libp2p/peer-id'
import { expect } from 'aegir/chai'
import { pEvent } from 'p-event'
import sinon, { type SinonStubbedInstance } from 'sinon'
Expand Down Expand Up @@ -273,10 +274,12 @@ describe('gossip', () => {
const maxOutboundStreams = 5

const registrar = stubInterface<Registrar>()

const privateKey = await generateKeyPair('Ed25519')
const peerId = peerIdFromPrivateKey(privateKey)
const pubsub = new GossipSub(
{
peerId: await createEd25519PeerId(),
privateKey,
peerId,
registrar,
peerStore: stubInterface<PeerStore>(),
connectionManager: stubInterface<ConnectionManager>(),
Expand Down
Loading

0 comments on commit a993667

Please sign in to comment.