lightninglabs / taproot-assets

A layer 1 daemon, for the Taproot Assets Protocol specification, written in Go (golang)
MIT License
457 stars 110 forks source link

[bug]: Planter cannot reply to requests while caretaker is finalizing a batch #705

Open jharveyb opened 9 months ago

jharveyb commented 9 months ago

Discovered while working on #693 .

When we finalize a batch ( assets mint finalize ), the planter starts a caretaker to handle the batch. As part of the finalize call, the planter waits for a response from the new caretaker:

https://github.com/lightninglabs/taproot-assets/blob/5318848252e331d64862f7c9173fdbe7dc5f1e27/tapgarden/planter.go#L621

This means that the finalize call will block on a response from the caretaker (or a quit signal). While the finalize call is blocked, the planter cannot respond to other requests like listing batches or cancelling a batch. In practice, I think this means that a user cannot actually cancel a batch owned by a caretaker right now, they can only cancel batches before finalize is called.

I think we didn't notice this earlier because in the unit tests we use the mock minter interfaces to essentially 'pause' the planter and caretaker at different spots, and we were starting batches directly via the batch ticker and not the finalize call, so this case was not exercised.

I'm not sure exactly what an appropriate change would be - IIUC the planter is set up to operate on one state request at a time vs. havving one request in-flight and another request being received.

One possibility would be moving part of the logic here:

https://github.com/lightninglabs/taproot-assets/blob/5318848252e331d64862f7c9173fdbe7dc5f1e27/tapgarden/planter.go#L593

Into a new & separate long-lived goroutine that accepts *BatchCaretaker and receives messages from a caretaker + resolves the original finalize request.

jharveyb commented 6 months ago

Also relevant for test changes as part of #827. We also can't query of the planter state until the caretaker broadcasts. Even if we moved waiting on a caretaker into another goroutine, we handle requests sequentially, so can't currently serve one pending request + one new request.