For the past 10 days I have focused on mainly three areas:
- updating my cdk branch
- continuing work on ecash issuance
- applying for grants
Up until now I have been building on a branch of cdk that I have not been maintaining. I added a few functions and trait derivations but I haven't focused on upstreaming those changes or keeping the branch up to date with cdk main. I was focused on gaining forward momentum in hashpool. This was a good tradeoff, but I feel I have achieved some momentum and settled back in to my routine after all the October travel so the time has come to update my dependencies.
I started by opening a PR with some new functions to convert the Id struct to a u64 and back. Turns out this is not a very rusty pattern. I learned that implementing the From trait is the better way to go about this and that cdk already had a From impl to convert Id to a u64. But no function to convert it back? It turns out this was actually implemented to support NUT13 deterministic secrets. And it was kind of buggy. It actually implemented a one way function to create a 'fingerprint' that fits inside a u32 but returned it as a u64.
I opened a PR to cdk to return a u32 fingerprint instead and also implement the From traits to convert Id
to and from a u64. Thesimplekid shot down the u64 From traits in PR review but he did merge my fix for the existing From trait. It feels good to get my PR merged! With the knowledge that cdk won't support these traits I built the solution I needed in hashpool and learned about the newtype pattern in the process. I also applied my newfound knowledge of the From trait to rewrite the Sv2BlindedMessage
conversion functions.
I removed a bunch of #[derive(Debug)]
statements and implemented the debug trait manually on the Downstream
and PoolSv2
structs. This way I can just skip debug logging the cdk components that don't support it. This removed the need for even more of the code changes I had made to cdk.
I created a new branch off the latest main and reapplied the one remaining change I needed, generate_premint_secrets
. This change is necessary and also not ready to open a PR. I would like to wait until I have working code that can construct a proof before proposing this change upstream because I will need another related function and will probably want to make additional changes to generate_premint_secrets
.
But on the new "hashpool" branch of cdk there was a new problem. On my previous branch I had manually added the HASH
currency type. But hard coding currency types was always an unmaintainable solution and cdk had changed since I last branched. I needed to use the new CurrencyType::Custom
enum, but when I did this my mint would immediately panic on startup. It was trying to create derivation paths for deterministic secrets but there were none defined for the Custom
enum. I fixed this issue on my cdk branch and opened a PR to push this fix upstream. Turns out my planned fix would break the spec. In my PR I got some guidance on how to provide the derivation paths in the Mint::new
constructor. I had glossed over those changes in my haste to get the code to compile.
I considered generating deterministic derivation path indexes from the currency string but dismissed it as too complex at the time. This would simplify the requirements to start up a mint so I think it might be worthwhile to build. To my surprise Thesimplekid was receptive to this idea in my PR so I would like to try to implement it. I'd also like to salvage some of the many unit tests I wrote for that PR. But I put that effort on the back burner for now in order to focus on my primary development goal: hashpool. I set the PR to draft, hopefully I can get back to this work soon.
With hashpool pointing to a much cleaner and more recent branch of cdk I could proceed working on ehash issuance. With a few more days of work I had built all the plumbing necessary for the pool to sign the blinded message and return it to the proxy where I attempted to reunite them into a Proof, another term for an ecash token. So close!
Creating the proof is still broken. It turns out I need to store more than just the keyset_id, I need to retrieve the whole keyset when the proxy first connects to the mint. Yesterday I implemented the Sv2KeySet
and Sv2SigningKey
structs to represent this data. I plan to get the keyset working and finish generating proofs. Then I want to push as much of this state as possible into the wallet to handle for me. Once I have this working I will be ready to finalize my generate_premint_secrets
PR. It will include another, to be written, function that encapsulates the second half of the wallet::mint
function after the network call to the mint.
I am quickly gaining momentum and facility with these codebases. It feels good to be closing in on my first milesone: ecash issuance. 🤙
I also applied for Spiral and OpenSats grants. As part of this process I converted my dev logs and project description gist to markup files and cleaned them up to be more readable directly from github. I think it would also be worthwhile to add some diagrams. This could be a stepping stone to a project website down the road. I also heard back from HRF that I had passed the first round of the application process. Noice!