refactor(types): centralise transparent spend-key lookup
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 22:00:07 +00:00
parent 51d5ce9f14
commit 0512861330
5 changed files with 38 additions and 6 deletions

View file

@ -56,8 +56,8 @@ func (c *Chain) GetRingOutputs(height, amount uint64, offsets []uint64) ([]types
// before or after the contract expiration. The refund path only opens after // before or after the contract expiration. The refund path only opens after
// the expiration height has passed. // the expiration height has passed.
func ringOutputSpendKey(height uint64, target types.TxOutTarget) (types.PublicKey, error) { func ringOutputSpendKey(height uint64, target types.TxOutTarget) (types.PublicKey, error) {
if t, ok := types.AsTxOutToKey(target); ok { if key, ok := (types.TxOutputBare{Target: target}).SpendKey(); ok {
return t.Key, nil return key, nil
} }
switch t := target.(type) { switch t := target.(type) {

View file

@ -325,8 +325,8 @@ func (m *ExplorerModel) viewTxDetail() string {
for i, output := range tx.Vout { for i, output := range tx.Vout {
switch v := output.(type) { switch v := output.(type) {
case types.TxOutputBare: case types.TxOutputBare:
if targetKey, ok := types.AsTxOutToKey(v.Target); ok { if targetKey, ok := v.SpendKey(); ok {
b.WriteString(fmt.Sprintf(" [%d] bare amount=%d key=%x\n", i, v.Amount, targetKey.Key[:4])) b.WriteString(fmt.Sprintf(" [%d] bare amount=%d key=%x\n", i, v.Amount, targetKey[:4]))
} else { } else {
b.WriteString(fmt.Sprintf(" [%d] bare amount=%d target=%T\n", i, v.Amount, v.Target)) b.WriteString(fmt.Sprintf(" [%d] bare amount=%d target=%T\n", i, v.Amount, v.Target))
} }

View file

@ -244,6 +244,17 @@ type TxOutputBare struct {
Target TxOutTarget Target TxOutTarget
} }
// SpendKey returns the standard transparent spend key when the target is
// TxOutToKey. Callers that only care about transparent key outputs can use
// this instead of repeating a type assertion.
func (t TxOutputBare) SpendKey() (PublicKey, bool) {
target, ok := AsTxOutToKey(t.Target)
if !ok {
return PublicKey{}, false
}
return target.Key, true
}
// OutputType returns the wire variant tag for bare outputs. // OutputType returns the wire variant tag for bare outputs.
func (t TxOutputBare) OutputType() uint8 { return OutputTypeBare } func (t TxOutputBare) OutputType() uint8 { return OutputTypeBare }

View file

@ -33,6 +33,27 @@ func TestAsTxOutToKey_Bad(t *testing.T) {
} }
} }
func TestTxOutputBare_SpendKey_Good(t *testing.T) {
out := TxOutputBare{
Amount: 10,
Target: TxOutToKey{Key: PublicKey{0xAA, 0xBB}, MixAttr: 3},
}
key, ok := out.SpendKey()
if !ok {
t.Fatal("SpendKey: expected true for TxOutToKey target")
}
if key != (PublicKey{0xAA, 0xBB}) {
t.Errorf("SpendKey: got %x, want %x", key, PublicKey{0xAA, 0xBB})
}
}
func TestTxOutputBare_SpendKey_Bad(t *testing.T) {
out := TxOutputBare{Target: TxOutHTLC{Expiration: 100}}
if key, ok := out.SpendKey(); ok || key != (PublicKey{}) {
t.Fatalf("SpendKey: got (%x, %v), want zero key and false", key, ok)
}
}
func TestTxOutMultisig_TargetType_Good(t *testing.T) { func TestTxOutMultisig_TargetType_Good(t *testing.T) {
var target TxOutTarget = TxOutMultisig{MinimumSigs: 2, Keys: []PublicKey{{1}, {2}}} var target TxOutTarget = TxOutMultisig{MinimumSigs: 2, Keys: []PublicKey{{1}, {2}}}
if target.TargetType() != TargetTypeMultisig { if target.TargetType() != TargetTypeMultisig {

View file

@ -64,11 +64,11 @@ func (s *V1Scanner) ScanTransaction(tx *types.Transaction, txHash types.Hash,
continue continue
} }
targetKey, ok := types.AsTxOutToKey(bare.Target) targetKey, ok := bare.SpendKey()
if !ok { if !ok {
continue continue
} }
if types.PublicKey(expectedPublicKey) != targetKey.Key { if types.PublicKey(expectedPublicKey) != targetKey {
continue continue
} }