-
Notifications
You must be signed in to change notification settings - Fork 46
feat: typedef generation & type checking #261
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Thank you for submitting this PR!
Getting other community members to do a review would be great help too on complex PRs (you can ask in the chats/forums). If you are unsure about something, just leave us a comment.
We currently aim to provide initial feedback/triaging within two business days. Please keep an eye on any labelling actions, as these will indicate priorities and status of your contribution. |
| // If there's nothing in the message, bail out | ||
| if (msg.empty) { | ||
| this._requestQueue.tasksDone(peerId, tasks) | ||
| peerId && this._requestQueue.tasksDone(peerId, tasks) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
peerId is obtained on line 76 via following code:
const { peerId, tasks, pendingSize } = this._requestQueue.popTasks(this._opts.targetMessageSize)However popTasks returns an object without peerId in 2 code paths out of 3. At the same time tasksDone and messageSent below do not expect undefined.
It was not exactly clear what made most sense here, so I just conditioned those calls on peerIds presence, but it would be good to make sure all this makes sense.
| */ | ||
| isIdle () { | ||
| return this._pending.length === 0 && this._active.length === 0 | ||
| return this._pending.length === 0 && this._active.size === 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like there was a bug in the code, because _active is a Set instance which doesn't have length property.
|
|
||
| if (typeof inc !== 'number') { | ||
| throw new Error('invalid increment number:', inc) | ||
| throw new Error(`invalid increment number: ${inc}`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seemed like a bug, so I just inlined incinto error message.
src/types/message/index.js
Outdated
| !isMapEqual(this.blocks, other.blocks) || | ||
| // @TODO - Is this a bug ? `isMapEqual` only compare maps of blocks and | ||
| // wants | ||
| // @ts-ignore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one seems like a bug, but maybe it is not 🙄 So isMapEqual will compare only that keys match and will compare values if they are either Blocks or BitswapMessageEntrys (anything that has equals method on them actually). However blockPresences contain numbers so two would be equal even if the actual values are different, which doesn't seems like intended behavior.
P.S.: TS not happy mostly because it's told to expect maps of blocks or entries and is passed maps of numbers below.
|
|
||
| this._entries = [] | ||
| this._log = logger(selfPeerId, 'msgqueue', otherPeerId.toB58String().slice(0, 8)) | ||
| this._log = logger(selfPeerId, 'msgqueue') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what to do with the last argument here, because logger seems to take just two. I dropped it to retain the current behavior, but maybe concatenating last two would make more sense.
hugomrdias
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we make an issue for the all ts-ignore's ?
|
@hugomrdias I have addressed all of your feedback except:
|
|
Merging master introduced the problem with libp2p typedefs so temporarily this pull depends on libp2p/js-libp2p-interfaces#73 |
|
|
@hugomrdias any idea what is going on here ? For some reason |
|
dunno maybe because some deps arent using aegir ts yet or the eslint config |
package.json
Outdated
| "uuid": "^8.0.0" | ||
| "uuid": "^8.0.0", | ||
| "@types/debug": "^4.1.5", | ||
| "typescript": "^4.0.5" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| "typescript": "^4.0.5" |
package.json
Outdated
| "src" | ||
| ], | ||
| "scripts": { | ||
| "prepare": "aegir build", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need full build here
| "prepare": "aegir build", | |
| "prepare": "aegir ts -p check", |
| return this._libp2p.contentRouting.findProviders( | ||
| cid, | ||
| { | ||
| // TODO: Should this be a timeout options insetad ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vasco-santos do you know if we should be passing timeout instead of maxTimeout
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be timeout - the option is passed through to whatever contenting routing modules are configured - these are either libp2p-delegated-content-routing or libp2p-kad-dht and neither of those support a maxTimeout option, only timeout.
| } | ||
|
|
||
| return this.libp2p.dial(peer, options) | ||
| // TODO: Figure out inconsistency here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vasco-santos could you please help me out understand what is expected here. Passed peer here comes from libp2p.contentRouting.findProviders which contains both peer id and multiaddr, but then libp2p.dial expects either peerId or multiaddr and attempts to turn it back into Provider.
I do not know all the ins and outs here, but clearly something makes wrong assumptions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
libp2p.contentRouting.findProviders should return only PeerIDs.
The idea is that libp2p manages the actual multiaddrs internally and we don't worry about them at this level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Created an issue in libp2p libp2p/js-libp2p#899
| !isMapEqual(this.wantlist, other.wantlist) || | ||
| !isMapEqual(this.blocks, other.blocks) || | ||
| // @TODO - Is this a bug ? | ||
| // @ts-expect-error - isMap equals map values to be objects not numbers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hugomrdias This looks like a bug to me, could you please confirm or tell me if I'm not seeing something ?
| this._log('adding to wl') | ||
| // TODO: Figure out the wantType | ||
| // @ts-expect-error - requires wantType | ||
| this.wantlist.add(e.cid, e.priority) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hugomrdias do you understand why wantType is omitted here ? Following lines make make me believe it should be provided, but I'm not sure what the value should be in this instance
js-ipfs-bitswap/src/types/wantlist/index.js
Lines 28 to 32 in 681b015
| if (entry.wantType === Message.WantType.Have && wantType === Message.WantType.Block) { | |
| entry.wantType = wantType | |
| } | |
| } else { | |
| this.set.set(cidStr, new Entry(cid, priority, wantType)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the WantType ends up defaulting to Block if it's omitted. The Have/Block distinction is a later optimisation, I think maybe it just got missed off here when it was implemented.
|
|
||
| sortedEntries () { | ||
| // TODO: Figure out if this is an actual bug. | ||
| // @ts-expect-error - Property 'key' does not exist on type 'WantListEntry' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@achingbrain do you have an idea what this meant to be, I'm guessing key used to be what cid is today, but I'm not sure. Nor I have a clue how this supposed to be sorted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like a bug. I think this is just supposed to be a list of wantlist entries sorted by string CID, rather than insertion order which would be the default - the .key property access is probably due to misreading the docs on the output of Map.entries()?
I'm not sure what the value of it being sorted is, other than the output being stable - it's probably better as a set TBH.
Something we should create an issue for and maybe address later.
achingbrain
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM - a few bugs and inconsistencies are well pointed out but we should get this in and address those as follow ups.
Just needs the github URLs removing from deps and it's good to go.
| return this._libp2p.contentRouting.findProviders( | ||
| cid, | ||
| { | ||
| // TODO: Should this be a timeout options insetad ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be timeout - the option is passed through to whatever contenting routing modules are configured - these are either libp2p-delegated-content-routing or libp2p-kad-dht and neither of those support a maxTimeout option, only timeout.
| * @param {Object} options | ||
| * @param {AbortSignal} options.abortSignal | ||
| * @returns {void} | ||
| * @param {Object} [options] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small nit and not a blocker but in this PR I see @param {Object} in some places and @param {object} in others.
I know it makes no difference functionally, but we should be consistent (and it should really be enforced by our linting rules). I think we're using @param {object} everywhere else.
| } | ||
|
|
||
| return this.libp2p.dial(peer, options) | ||
| // TODO: Figure out inconsistency here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
libp2p.contentRouting.findProviders should return only PeerIDs.
The idea is that libp2p manages the actual multiaddrs internally and we don't worry about them at this level.
|
|
||
| sortedEntries () { | ||
| // TODO: Figure out if this is an actual bug. | ||
| // @ts-expect-error - Property 'key' does not exist on type 'WantListEntry' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like a bug. I think this is just supposed to be a list of wantlist entries sorted by string CID, rather than insertion order which would be the default - the .key property access is probably due to misreading the docs on the output of Map.entries()?
I'm not sure what the value of it being sorted is, other than the output being stable - it's probably better as a set TBH.
Something we should create an issue for and maybe address later.
| this._log('adding to wl') | ||
| // TODO: Figure out the wantType | ||
| // @ts-expect-error - requires wantType | ||
| this.wantlist.add(e.cid, e.priority) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the WantType ends up defaulting to Block if it's omitted. The Have/Block distinction is a later optimisation, I think maybe it just got missed off here when it was implemented.
Fixes up types so they align here ipfs/js-ipfs-bitswap#261 Co-authored-by: achingbrain <[email protected]>
|
Created an issue for all the discovered inconsistencies #303 |
This pull request makes following changes:
While making these changes I did discover certain things that are either bugs or I am misunderstanding what is going on there. I'll comment inline.
Please not that this change depends on: