-
Notifications
You must be signed in to change notification settings - Fork 133
multi: hook up burn and mint events to the supply commit state machine #1675
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
base: main
Are you sure you want to change the base?
Conversation
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.
Took a quick look, didn't go through every commit.
address/book_test.go
Outdated
// Set up mocks | ||
tt.setupMocks(mockStorage) | ||
|
||
// Call the method | ||
hasDelegation, err := book.HasDelegationKey(ctx, tt.assetID) | ||
|
||
// Check results | ||
if tt.expectedError != "" { | ||
require.Error(t, err) | ||
require.Contains(t, err.Error(), tt.expectedError) | ||
} else { | ||
require.NoError(t, err) | ||
} | ||
|
||
require.Equal(t, tt.expectedHas, hasDelegation) | ||
|
||
// Verify expectations |
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.
comments can be removed here
58d8271
to
b1b0ad7
Compare
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.
Very nice! LGTM pending CI fixes.
Pull Request Test Coverage Report for Build 17111730179Details
💛 - Coveralls |
236e50f
to
81c687c
Compare
Pushed a series of commits fixing some bugs:
After all those were fixed, the itest added passes. We mint an asset, then another one in a group, then burn an asset. Along the way we check that all the commitment information has been updated along the way. |
81c687c
to
a1e821b
Compare
Pushed up a commit to fix a rebase issue in the unit tests. |
a1e821b
to
0207a85
Compare
I cleaned up after the AI to fix the linter issues and added release notes to get the CI green. |
0207a85
to
5cb6e07
Compare
I think you forgot to pull my linter fixes... |
5cb6e07
to
eccebe8
Compare
Forgot to pull down those prior chagnes before applying a fixup commit. Should be good now... |
…n control This commit introduces a new DelegationKeyChecker interface that allows verification of whether we control the delegation key for a given asset. The interface is implemented by the address.Book, which checks if the local key ring contains the private key corresponding to an asset's delegation public key. The implementation queries the asset group and metadata to extract the delegation key, then attempts to locate the corresponding private key in the local keystore. This verification is essential for ensuring only authorized parties can create supply commitment proofs for assets with delegation keys.
This commit extends the MultiStateMachineManager to implement the MintCommitter and BurnSupplyCommitter interfaces. These new methods provide a type-safe way to send mint and burn events to the supply commitment state machines. The SendMintEvent method accepts universe-specific types for minting operations, while SendBurnEvent handles burn leaf submissions. Both methods internally construct the appropriate event types and delegate to the existing SendEvent infrastructure, maintaining consistency with the state machine architecture.
This commit enhances the GardenKit configuration by adding two new optional dependencies: DelegationKeyChecker and MintCommitter. These additions enable the garden subsystem to verify delegation key ownership and submit mint events to the supply commitment state machine. The GardenKit struct serves as the central configuration hub for the tapgarden package, and these new fields allow components like the BatchCaretaker to conditionally enable supply commitment functionality when the required dependencies are available.
This commit extends the ChainPorterConfig with DelegationKeyChecker and BurnSupplyCommitter dependencies to enable supply commitment tracking for asset burns. When processing burn events, the chain porter now filters assets to only submit supply commitment events for those where we control the delegation key. The sendBurnSupplyCommitEvents method uses functional filtering to pre-process the burn list, ensuring we only attempt to create supply commitments for assets we're authorized to manage. This prevents unnecessary processing and potential errors for assets where we lack delegation authority.
This commit enhances the BatchCaretaker to filter mint events based on delegation key ownership. The sendSupplyCommitEvents method now uses functional filtering to ensure supply commitment events are only sent for assets where we control the delegation key. Similar to the burn event filtering in tapfreighter, this change ensures the caretaker respects delegation authority when creating supply proofs for newly minted assets. The filtering happens early in the process to avoid unnecessary proof construction and event submission for assets we're not authorized to manage.
This commit completes the integration by wiring the address book's DelegationKeyChecker implementation to both the GardenKit and ChainPorterConfig. With this configuration, both minting and burning operations now properly verify delegation key ownership before submitting supply commitment events. The address book serves as the central authority for key ownership verification, leveraging its existing access to the key ring and asset metadata storage. This ensures consistent delegation checking across all supply commitment operations.
This commit introduces comprehensive test coverage for the delegation key filtering functionality in the BatchCaretaker. The tests verify that mint supply commitment events are only sent for assets where we control the delegation key. The test suite covers three key scenarios: all assets having delegation keys, partial delegation key ownership, and no delegation keys. Mock implementations of the MintCommitter and DelegationKeyChecker interfaces enable isolated testing of the filtering logic without requiring actual key management infrastructure.
This commit adds a unified test suite for burn supply commitment event processing in the ChainPorter. The tests verify delegation key filtering, error handling, and various burn scenarios through a table-driven approach with a helper function for cleaner test setup. The test coverage includes successful burn processing with mixed group keys, delegation key filtering scenarios, error handling for both the delegation checker and burn committer, handling of missing dependencies, and validation of invalid group key bytes. The setupChainPorterTest helper function eliminates repetitive mock configuration, making the tests more maintainable and focused on the scenarios being tested.
This'll be useful to fix a bug in the next commit, where we weren't actually able to effectivley look up which pre commitment was being spent by a new supply commit.
The call is idempotent so not explcitily a bug, but we have two calls to the function here. Likely was a rebase issue.
In this commit, we fix a bug where we wouldn't actually mark pre commitmetns as spent. We'll do so now, which makes sure that when we fetch the pre commits for a later batch, we aren't trying to include one that might be double spent.
This fixes a bug that would cause a spend of a supply commitment output to fail. We weren't storing the full key desc, so lnd wasn't able to sign the PSBT, as the bip32 information didn't match up (derived wrong key).
If this isn't set, then we can't do a spend, as lnd can't figure out how to sign for the PSBT input.
eccebe8
to
2d410bf
Compare
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've gone over these changes in detail and think they look solid. LGTM. 👍
I'd recommend adding a brief description of the changes in the OP, for posterity. I also noted a few utterly-trivial typo-related nits I just happened to pick up on while going through the code, but they don't actually need to be fixed.
|
||
assetGroup, err := b.cfg.Store.QueryAssetGroupByID(ctx, assetID) | ||
if err != nil { | ||
return false, fmt.Errorf("fail to find asset group given "+ |
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.
nit: s/fail/failed
} | ||
|
||
// Now that we have the delegation key, we'll see if we know of the | ||
// internal key loactor. If we do, then this means that we were the ones |
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.
nit: s/loactor/locator
@@ -265,6 +266,30 @@ func (m *MultiStateMachineManager) SendEventSync(ctx context.Context, | |||
return event.WaitForDone(ctx) | |||
} | |||
|
|||
// SendMintEvent sends a mint event to the supply commitment state machine. |
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.
nit: I've observed that some interface implementations specify the interface they're implementing with a NOTE in the leading comment. Not sure if this is intended to be universal practice, but this (for example) is missing it.
@@ -49,6 +50,15 @@ type ProofImporter interface { | |||
replace bool, proofs ...*proof.AnnotatedProof) error | |||
} | |||
|
|||
// BurnSupplyCommitter is used by the chain porter to update the on-chain supply | |||
// commitment when burns new 1st party burns are confirmed. |
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.
nit: s/burns/
Worth noting that this will also resolve #1648. |
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 we need to include setting the block height in both burn and mint events in this PR.
Here’s an example of the change needed for burn:
Subject: [PATCH] tapfreighter: set block header and height in burn proofs for commitments
---
Index: tapfreighter/chain_porter.go
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/tapfreighter/chain_porter.go b/tapfreighter/chain_porter.go
--- a/tapfreighter/chain_porter.go (revision ca914afd712ea0b6be7ae155803dce527a16084c)
+++ b/tapfreighter/chain_porter.go (revision 6db075b18a823e12290aa6e09ca35e018ac9d14a)
@@ -815,7 +815,15 @@
)
}
+ anchorTxBlockHeight := int32(pkg.TransferTxConfEvent.BlockHeight)
+ anchorTxBlockHeader := pkg.TransferTxConfEvent.Block.Header
+
// Now we scan through the VPacket for any burns.
+ //
+ // Once the anchor transaction is confirmed, we must populate the block
+ // header and block height in the proof suffixes of all outputs. Without
+ // the block height, burn events cannot be considered valid for
+ // inclusion in supply commitments.
var burns []*AssetBurn
for _, v := range pkg.VirtualPackets {
@@ -841,6 +849,10 @@
OutPoint: op,
}
+ // Set the block height and header in the burn proof.
+ b.Proof.BlockHeight = uint32(anchorTxBlockHeight)
+ b.Proof.BlockHeader = anchorTxBlockHeader
+
if o.Asset.GroupKey != nil {
groupKey := o.Asset.GroupKey.GroupPubKey
b.GroupKey = groupKey.SerializeCompressed()
@@ -862,7 +874,6 @@
// At this point we have the confirmation signal, so we can mark the
// parcel delivery as completed in the database.
anchorTXID := pkg.OutboundPkg.AnchorTx.TxHash()
- anchorTxBlockHeight := int32(pkg.TransferTxConfEvent.BlockHeight)
err = p.cfg.ExportLog.LogAnchorTxConfirm(ctx, &AssetConfirmEvent{
AnchorTXID: anchorTXID,
BlockHash: *pkg.TransferTxConfEvent.BlockHash,
And here's the sort of thing I think we need for mint:
Subject: [PATCH] tapgarden+supplycommit: set mint block height in NewMintEvent
---
Index: tapgarden/caretaker.go
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/tapgarden/caretaker.go b/tapgarden/caretaker.go
--- a/tapgarden/caretaker.go (revision 6db075b18a823e12290aa6e09ca35e018ac9d14a)
+++ b/tapgarden/caretaker.go (revision a5e97c86a59571d10d525ea7fd516be271259258)
@@ -1550,6 +1550,7 @@
// Finally we send all of the above to the supply commiter.
err = b.cfg.MintSupplyCommitter.SendMintEvent(
ctx, assetSpec, uniqueLeafKey, universeLeaf,
+ leafProof.BlockHeight,
)
if err != nil {
return fmt.Errorf("unable to send mint event for "+
Index: tapgarden/planter.go
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/tapgarden/planter.go b/tapgarden/planter.go
--- a/tapgarden/planter.go (revision 6db075b18a823e12290aa6e09ca35e018ac9d14a)
+++ b/tapgarden/planter.go (revision a5e97c86a59571d10d525ea7fd516be271259258)
@@ -37,8 +37,8 @@
// SendMintEvent sends a mint event to the supply commitment state
// machine.
SendMintEvent(ctx context.Context, assetSpec asset.Specifier,
- leafKey universe.UniqueLeafKey,
- issuanceProof universe.Leaf) error
+ leafKey universe.UniqueLeafKey, issuanceProof universe.Leaf,
+ mintBlockHeight uint32) error
}
// GardenKit holds the set of shared fundamental interfaces all sub-systems of
Index: tapgarden/supply_commit_test.go
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/tapgarden/supply_commit_test.go b/tapgarden/supply_commit_test.go
--- a/tapgarden/supply_commit_test.go (revision 6db075b18a823e12290aa6e09ca35e018ac9d14a)
+++ b/tapgarden/supply_commit_test.go (revision a5e97c86a59571d10d525ea7fd516be271259258)
@@ -44,9 +44,11 @@
// SendMintEvent implements the SupplyCommitManager interface.
func (m *MockSupplyCommitManager) SendMintEvent(ctx context.Context,
assetSpec asset.Specifier, leafKey universe.UniqueLeafKey,
- issuanceProof universe.Leaf) error {
+ issuanceProof universe.Leaf, mintBlockHeight uint32) error {
- args := m.Called(ctx, assetSpec, leafKey, issuanceProof)
+ args := m.Called(
+ ctx, assetSpec, leafKey, issuanceProof, mintBlockHeight,
+ )
return args.Error(0)
}
@@ -132,7 +134,8 @@
mock.AnythingOfType(
"universe.AssetLeafKey",
),
- mock.AnythingOfType("universe.Leaf")).
+ mock.AnythingOfType("universe.Leaf"),
+ mock.AnythingOfType("uint32")).
Return(nil).
Times(tc.expectedCallCount)
}
Index: universe/supplycommit/manager.go
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/universe/supplycommit/manager.go b/universe/supplycommit/manager.go
--- a/universe/supplycommit/manager.go (revision 6db075b18a823e12290aa6e09ca35e018ac9d14a)
+++ b/universe/supplycommit/manager.go (revision a5e97c86a59571d10d525ea7fd516be271259258)
@@ -266,11 +266,13 @@
// SendMintEvent sends a mint event to the supply commitment state machine.
func (m *Manager) SendMintEvent(ctx context.Context, assetSpec asset.Specifier,
- leafKey universe.UniqueLeafKey, issuanceProof universe.Leaf) error {
+ leafKey universe.UniqueLeafKey, issuanceProof universe.Leaf,
+ mintBlockHeight uint32) error {
mintEvent := &NewMintEvent{
LeafKey: leafKey,
IssuanceProof: issuanceProof,
+ MintHeight: mintBlockHeight,
}
return m.SendEventSync(ctx, assetSpec, mintEvent)
// With the proof extracted, we can now create the universe | ||
// key and leaf. | ||
universeKey := universe.BaseLeafKey{ | ||
OutPoint: mintedAsset.Genesis.FirstPrevOut, |
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 this should be leafProof.OutPoint()
.
No description provided.