Repository navigation
multi: Add the embedded Taproot Assets backend - #1583
darioAnongba wants to merge 11 commits into
Conversation
581e559 to
2a6fdbe
Compare
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2a6fdbef48
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| case <-registration.Done: | ||
| select { | ||
| case done <- struct{}{}: | ||
| case <-quit: | ||
| } |
There was a problem hiding this comment.
Forward the buffered confirmation before terminating on Done
When the btcwallet backend registers a transaction already beyond its reorg-safety depth, such as when resuming an old transfer after restart, btcwbackend.ChainBackend.RegisterConf can buffer both Confirmed and Done before this goroutine runs. Go's select can choose Done first, and this branch then exits without forwarding the buffered confirmation or its block. The embedded engine consequently cannot reconstruct the transfer's confirmed proofs. Preserve a pending terminal signal until the positive confirmation has been forwarded, as chainsource.ConfActor does with PositiveDoneOrder, and distinguish channel closure from an actual finality event.
Useful? React with 👍 / 👎.
95ea542 to
72b8437
Compare
2a6fdbe to
3e67b69
Compare
72b8437 to
cf3f739
Compare
3e67b69 to
4c4dee2
Compare
|
/gateway review |
|
❌ gateway review failed: code-review skill failed across all auth modes: You've hit your weekly limit · resets Nov 15, 6am (UTC) See workflow logs for details. |
Verifying a Taproot Asset proof means checking that each anchor block is on the best chain at its claimed height. BlockHeaderSource is the optional chain backend interface for that lookup, and the Esplora and neutrino backends implement it.
The embedded asset engine keeps its keys, proof files and transfers in the daemon's database, because a browser offers one exclusive database connection and no files. asset_journal holds the deposit journal for the same reason.
AssetEngineStore implements the store of tap-sdk's embedded engine on the asset engine tables, and keeps the asset deposit journal. Lookups that find nothing return after their transaction, so an unknown key does not log as a failed transaction.
A backend that verifies proofs against its own chain view and trusted groups needs no issuance fallback, so its verifier asks it once and never writes to it.
assets.backend=embedded runs tap-sdk's asset engine inside the daemon, so a daemon on a local wallet verifies asset VTXOs and deposits assets with no tapd or lnd beside it. The engine takes its keys from the wallet seed, chain data from the chain backend and storage from the daemon's database, and the deposit journal moves into the database. The backend requires wallet.type lwwallet or btcwallet, whose seed the daemon holds, and is refused outside regtest.
NewAssetReceiveKeys, ImportAssetProof and ListOwnedAssets let a caller receive a Taproot Asset on chain into the daemon's asset wallet and list what it holds. A daemon without tapd has no other way to take in an asset. NewAssetFundingAddress returns a backing-wallet address for the Bitcoin an asset deposit spends.
The asset RPCs go through tap-sdk, so they serve the tapd backend and the embedded one. ImportAssetProof checks that the proof is of the asset the caller names before it stores anything, which is also how the embedded backend learns to trust a grouped asset. NewAssetFundingAddress returns an address of the wallet that pays for deposits.
Mobile and browser hosts reach the daemon only through the wallet SDK's facade. The assets_backend config key selects the daemon's asset backend, and the asset verbs cover funding, receiving, listing, depositing and boarding assets.
The daemon runs on a light wallet with no tapd or lnd of its own. It receives an asset from a tapd, deposits part of it, keeps the change, restarts, and boards the deposit. The tapd verifies the proof the engine wrote.
4c4dee2 to
85ee434
Compare
assets.backend=embeddedruns Taproot Assets inside waved. The daemon holds, verifies and moves assets on its own seed, chain backend and database, with no tapd or lnd beside it, so the same code serves the desktop daemon, the gomobile bindings and the js/wasm build. The backend is tap-sdk's in-process engine (lightninglabs/tap-sdk#197), and waved's asset code keeps calling the tap-sdk interface it calls on the tapd backend.keychain.SecretKeyRing, its headers and broadcast from the chain backend, and its storage fromdb.AssetEngineStore(migration 31). It follows a transfer's confirmation through the chain source actor, which orders the events of every backend and reports finality, so tracking a transfer ends on the light wallet too. The Esplora and neutrino backends serve block headers by height through the newchainsource.BlockHeaderSource. The wallet can still be locked when the backend starts, so the ports resolve the wallet on each call, and the engine resumes its transfers once the wallet services are up.tapassets.LocalProofChainVerifierchecks a confirmed proof with the engine. A grouped asset verifies only for a trusted group: one listed inassets.groupkeys, the group of the asset a request names, or the group of an asset the wallet holds.NewAssetReceiveKeys,ImportAssetProofandListOwnedAssetsreceive an asset on chain and list the holdings. They go through tap-sdk, so they serve the tapd backend too. The engine is given only a proof file that verifies, while tapd verifies each proof as the import inserts it.NewAssetFundingAddressreturns a backing-wallet address for the Bitcoin a deposit spends, which a wallet SDK host cannot learn otherwise.DepositAssetandBoardAssetDepositrun on the engine through the existing onboarding code. The engine signs its anchor inputs with keys of the daemon's seed, so the tapd version check does not apply to it, and the deposit journal lives in the database, since a browser has no files. Claims stay on the tapd backend:ClaimAssetDepositreturnsFailedPreconditionon the engine.assets_backendandasset_group_keysreach the daemon from the wallet SDK, the mobile facade and the wasm entry point, which also gain the asset verbs. Asset amounts are decimal strings in the JSON of the asset types, since they can exceed what a JavaScript number holds exactly.The backend requires
wallet.typelwwalletorbtcwalletand is refused outside regtest.assets.backendstill defaults tonone.TestEmbeddedAssetDepositcovers the lifecycle on a daemon with a light wallet: fund, receive from a tapd, deposit, change, restart and board, with the tapd verifying the proof the engine wrote. The same lifecycle also ran through the gomobile bindings inside an iOS app in the simulator.