Hi, glad you found your way here. I'm Yash, a developer who contributes to open source, mostly p2p networking and AI tooling. Each week I write up what I shipped, what broke, and what fixing it taught me.
GitHub · X · LinkedIn · Portfolio
TL;DR
This week was all about the "plumbing" of the decentralized web. I spent my time jumping between three different implementations of the libp2p protocol—Go, Python, and .NET—focusing on resource management, async lifecycles, and Gossipsub robustness. I opened one significant PR in go-libp2p to fix a connection leak, filed three detailed issues in py-libp2p regarding shutdown hangs and DNS resolution, and provided feedback on three PRs in the dotnet-libp2p ecosystem.
Digging into the Go Upgrader
The highlight of my week was working on go-libp2p. If you’ve ever done low-level networking, you know that the "upgrading" process—where a raw connection becomes a secure, multiplexed libp2p connection—is where the most dangerous race conditions live.
I opened a PR titled fix(upgrader): release scope of conns closed before Accept. This addresses a specific edge case in the resource manager. In libp2p, we use "scopes" to track and limit resource usage (like memory and file descriptors). The bug I found was that if a connection was closed by the remote peer or timed out before the local Accept call finished, the resource scope wasn't always being released properly.
I added 181 lines of code, mostly focused on hardening the state machine in the upgrader to ensure that no matter how a connection dies during the handshake, we aren't leaking resources. It’s one of those fixes that doesn't add a flashy feature but keeps a long-running node from slowly eating all the RAM on a server. It's still open and under review, as these kinds of changes require a lot of eyes to ensure we aren't introducing new deadlocks.
Troubleshooting the Python Lifecycle
While the Go work was about fixing a leak, my time with py-libp2p was about diagnosing why things won't stop. I opened three issues this week that all center around the complexity of asynchronous lifecycles in Python, specifically when using structured concurrency (like Trio's nurseries).
The first issue, echo-demo and other one-shot example clients never exit, is a classic "zombie process" problem. I noticed that our example scripts would finish their work but then just hang indefinitely. After some digging, I realized the main nursery was waiting on a background peerstore cleanup task that never got the signal to shut down. It's a small thing that makes the developer experience feel "broken" for newcomers, so I'm hoping to get a fix in for that soon.
I also filed Leaving host.run() leaves connections and listeners open. This is a more serious architectural issue where the Swarm isn't properly cleaning up its internal state when the host is cancelled. If you're running a dynamic system where you're starting and stopping nodes frequently, this would eventually lead to a "too many open files" error.
Finally, I hit a weird networking edge case and documented it in /dns6/localhost can't be dialed on a host with no global IPv6. Basically, the library was being a bit too aggressive in assuming that any DNS6 address must be a public, dialable address, even when it's just a local loopback on a machine that doesn't have a global IPv6 route. Networking is hard, and local dev environments are often the weirdest places for these bugs to hide.
Reviewing the .NET Stack
I also spent some time in the dotnet-libp2p repository, which is being led by the Nethermind team. They are doing some great work bringing the protocol to the C# ecosystem, and I helped out with three code reviews this week.
Two of the reviews were focused on Gossipsub, which is the heavy-duty pubsub protocol used by blockchains like Ethereum. I commented on Populate Gossipsub IP-colocation scoring input and Randomize Gossipsub mesh fanout and gossip peer selection.
These are critical for security. IP-colocation scoring helps the network identify if a single entity is trying to run hundreds of nodes from the same IP range to try and "eclipse" or manipulate the network. Randomizing peer selection is equally important to ensure the gossip network remains a "small world" graph that is resilient to targeted attacks. It’s great to see the .NET implementation reaching this level of maturity.
I also did a quick sanity check on a repository maintenance PR, Move Libp2p.slnx to the repository root, which is just good housekeeping for anyone working in a .NET environment.
Tech Stack & Vibe
This week was a true polyglot experience. Even though the languages data doesn't show a specific commit weight (since I was mostly focused on issues and reviews outside of the one Go PR), I was effectively working across:
- Go: For the core resource management logic.
- Python: For diagnosing async lifecycle and DNS issues.
- C# (.NET): For reviewing security-sensitive Gossipsub logic.
It’s a "maintenance and mentorship" week. I didn't land dozens of commits, but I spent my time where it arguably matters more: helping other implementations stay secure and fixing the bugs that make tools frustrating to use.
What's Next
Next week, I want to follow up on the go-libp2p PR. Resource manager changes usually involve a bit of back-and-forth with the maintainers to make sure the performance trade-offs are worth it. I also want to see if I can actually submit the PRs for those py-libp2p issues I opened. It's one thing to point out that the nursery is hanging; it's another to actually rearrange the async task tree to fix it.
Onward to more green tests!
Top comments (0)