feat(wallet): mark HTLC spends during sync
Some checks are pending
Security Scan / security (push) Waiting to run
Test / Test (push) Waiting to run

Co-Authored-By: Charon <charon@lethean.io>
This commit is contained in:
Virgil 2026-04-04 20:42:56 +00:00
parent e25e3e73e7
commit 92cb5a8fbb
2 changed files with 63 additions and 5 deletions

View file

@ -122,17 +122,23 @@ func (w *Wallet) scanTx(tx *types.Transaction, blockHeight uint64) error {
// Check key images for spend detection. // Check key images for spend detection.
for _, vin := range tx.Vin { for _, vin := range tx.Vin {
toKey, ok := vin.(types.TxInputToKey) var keyImage types.KeyImage
if !ok { switch v := vin.(type) {
case types.TxInputToKey:
keyImage = v.KeyImage
case types.TxInputHTLC:
keyImage = v.KeyImage
default:
continue continue
} }
// Try to mark any matching transfer as spent. // Try to mark any matching transfer as spent.
tr, err := getTransfer(w.store, toKey.KeyImage) tr, err := getTransfer(w.store, keyImage)
if err != nil { if err != nil {
continue // not our transfer continue // not our transfer
} }
if !tr.Spent { if !tr.Spent {
markTransferSpent(w.store, toKey.KeyImage, blockHeight) markTransferSpent(w.store, keyImage, blockHeight)
} }
} }

View file

@ -12,11 +12,11 @@ package wallet
import ( import (
"testing" "testing"
store "dappco.re/go/core/store"
"dappco.re/go/core/blockchain/chain" "dappco.re/go/core/blockchain/chain"
"dappco.re/go/core/blockchain/crypto" "dappco.re/go/core/blockchain/crypto"
"dappco.re/go/core/blockchain/types" "dappco.re/go/core/blockchain/types"
"dappco.re/go/core/blockchain/wire" "dappco.re/go/core/blockchain/wire"
store "dappco.re/go/core/store"
) )
func makeTestBlock(t *testing.T, height uint64, prevHash types.Hash, func makeTestBlock(t *testing.T, height uint64, prevHash types.Hash,
@ -133,3 +133,55 @@ func TestWalletTransfers(t *testing.T) {
t.Fatalf("got %d transfers, want 1", len(transfers)) t.Fatalf("got %d transfers, want 1", len(transfers))
} }
} }
func TestWalletScanTxMarksHTLCSpend(t *testing.T) {
s, err := store.New(":memory:")
if err != nil {
t.Fatal(err)
}
defer s.Close()
acc, err := GenerateAccount()
if err != nil {
t.Fatal(err)
}
ki := types.KeyImage{0x42}
if err := putTransfer(s, &Transfer{
KeyImage: ki,
Amount: 100,
BlockHeight: 1,
}); err != nil {
t.Fatal(err)
}
w := &Wallet{
store: s,
scanner: NewV1Scanner(acc),
}
tx := &types.Transaction{
Version: types.VersionPreHF4,
Vin: []types.TxInput{
types.TxInputHTLC{
Amount: 100,
KeyImage: ki,
},
},
}
if err := w.scanTx(tx, 10); err != nil {
t.Fatal(err)
}
got, err := getTransfer(s, ki)
if err != nil {
t.Fatal(err)
}
if !got.Spent {
t.Fatal("expected HTLC spend to be marked spent")
}
if got.SpentHeight != 10 {
t.Fatalf("spent height = %d, want 10", got.SpentHeight)
}
}