refactor(types): change TxOutputBare.Target to TxOutTarget interface
Prepares for HF1 output target types (TxOutMultisig, TxOutHTLC). All call sites updated to type-assert TxOutToKey where needed. Modified files: - types/transaction.go: TxOutputBare.Target is now TxOutTarget - wire/transaction.go: encode/decode use type switch on target - chain/ring.go: type-assert target to TxOutToKey for key extraction - wallet/scanner.go: type-assert target before key comparison - tui/explorer_model.go: type-assert target for display - wire/transaction_test.go: type-assert in assertions - wallet/builder_test.go: type-assert in assertions Co-Authored-By: Charon <charon@lethean.io>
This commit is contained in:
parent
6eabe2a64d
commit
0408d2f3fa
7 changed files with 55 additions and 20 deletions
|
|
@ -35,7 +35,11 @@ func (c *Chain) GetRingOutputs(amount uint64, offsets []uint64) ([]types.PublicK
|
|||
|
||||
switch out := tx.Vout[outNo].(type) {
|
||||
case types.TxOutputBare:
|
||||
pubs[i] = out.Target.Key
|
||||
toKey, ok := out.Target.(types.TxOutToKey)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("ring output %d: unsupported target type %T", i, out.Target)
|
||||
}
|
||||
pubs[i] = toKey.Key
|
||||
default:
|
||||
return nil, fmt.Errorf("ring output %d: unsupported output type %T", i, out)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -325,7 +325,11 @@ func (m *ExplorerModel) viewTxDetail() string {
|
|||
for i, out := range tx.Vout {
|
||||
switch v := out.(type) {
|
||||
case types.TxOutputBare:
|
||||
b.WriteString(fmt.Sprintf(" [%d] bare amount=%d key=%x\n", i, v.Amount, v.Target.Key[:4]))
|
||||
if toKey, ok := v.Target.(types.TxOutToKey); ok {
|
||||
b.WriteString(fmt.Sprintf(" [%d] bare amount=%d key=%x\n", i, v.Amount, toKey.Key[:4]))
|
||||
} else {
|
||||
b.WriteString(fmt.Sprintf(" [%d] bare amount=%d target=%T\n", i, v.Amount, v.Target))
|
||||
}
|
||||
case types.TxOutputZarcanum:
|
||||
b.WriteString(fmt.Sprintf(" [%d] zarcanum stealth=%x\n", i, v.StealthAddress[:4]))
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -183,8 +183,9 @@ type TxOutputBare struct {
|
|||
// Amount in atomic units.
|
||||
Amount uint64
|
||||
|
||||
// Target is the one-time output destination (key + mix attribute).
|
||||
Target TxOutToKey
|
||||
// Target is the output destination. Before HF1 this is always TxOutToKey;
|
||||
// after HF1 it may also be TxOutMultisig or TxOutHTLC.
|
||||
Target TxOutTarget
|
||||
}
|
||||
|
||||
// OutputType returns the wire variant tag for bare outputs.
|
||||
|
|
|
|||
|
|
@ -126,13 +126,21 @@ func TestV1BuilderBasic(t *testing.T) {
|
|||
}
|
||||
|
||||
// Output keys must be non-zero and unique.
|
||||
if out0.Target.Key == (types.PublicKey{}) {
|
||||
toKey0, ok := out0.Target.(types.TxOutToKey)
|
||||
if !ok {
|
||||
t.Fatalf("output 0 target type: got %T, want TxOutToKey", out0.Target)
|
||||
}
|
||||
toKey1, ok := out1.Target.(types.TxOutToKey)
|
||||
if !ok {
|
||||
t.Fatalf("output 1 target type: got %T, want TxOutToKey", out1.Target)
|
||||
}
|
||||
if toKey0.Key == (types.PublicKey{}) {
|
||||
t.Error("output 0 key is zero")
|
||||
}
|
||||
if out1.Target.Key == (types.PublicKey{}) {
|
||||
if toKey1.Key == (types.PublicKey{}) {
|
||||
t.Error("output 1 key is zero")
|
||||
}
|
||||
if out0.Target.Key == out1.Target.Key {
|
||||
if toKey0.Key == toKey1.Key {
|
||||
t.Error("output keys are identical; derivation broken")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,11 @@ func (s *V1Scanner) ScanTransaction(tx *types.Transaction, txHash types.Hash,
|
|||
continue
|
||||
}
|
||||
|
||||
if types.PublicKey(expectedPub) != bare.Target.Key {
|
||||
toKey, ok := bare.Target.(types.TxOutToKey)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if types.PublicKey(expectedPub) != toKey.Key {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -250,9 +250,12 @@ func encodeOutputsV1(enc *Encoder, vout []types.TxOutput) {
|
|||
case types.TxOutputBare:
|
||||
enc.WriteVarint(v.Amount)
|
||||
// Target is a variant (txout_target_v)
|
||||
enc.WriteVariantTag(types.TargetTypeToKey)
|
||||
enc.WriteBlob32((*[32]byte)(&v.Target.Key))
|
||||
enc.WriteUint8(v.Target.MixAttr)
|
||||
switch tgt := v.Target.(type) {
|
||||
case types.TxOutToKey:
|
||||
enc.WriteVariantTag(types.TargetTypeToKey)
|
||||
enc.WriteBlob32((*[32]byte)(&tgt.Key))
|
||||
enc.WriteUint8(tgt.MixAttr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -272,8 +275,10 @@ func decodeOutputsV1(dec *Decoder) []types.TxOutput {
|
|||
}
|
||||
switch tag {
|
||||
case types.TargetTypeToKey:
|
||||
dec.ReadBlob32((*[32]byte)(&out.Target.Key))
|
||||
out.Target.MixAttr = dec.ReadUint8()
|
||||
var tgt types.TxOutToKey
|
||||
dec.ReadBlob32((*[32]byte)(&tgt.Key))
|
||||
tgt.MixAttr = dec.ReadUint8()
|
||||
out.Target = tgt
|
||||
default:
|
||||
dec.err = fmt.Errorf("wire: unsupported target tag 0x%02x", tag)
|
||||
return vout
|
||||
|
|
@ -291,9 +296,12 @@ func encodeOutputsV2(enc *Encoder, vout []types.TxOutput) {
|
|||
switch v := out.(type) {
|
||||
case types.TxOutputBare:
|
||||
enc.WriteVarint(v.Amount)
|
||||
enc.WriteVariantTag(types.TargetTypeToKey)
|
||||
enc.WriteBlob32((*[32]byte)(&v.Target.Key))
|
||||
enc.WriteUint8(v.Target.MixAttr)
|
||||
switch tgt := v.Target.(type) {
|
||||
case types.TxOutToKey:
|
||||
enc.WriteVariantTag(types.TargetTypeToKey)
|
||||
enc.WriteBlob32((*[32]byte)(&tgt.Key))
|
||||
enc.WriteUint8(tgt.MixAttr)
|
||||
}
|
||||
case types.TxOutputZarcanum:
|
||||
enc.WriteBlob32((*[32]byte)(&v.StealthAddress))
|
||||
enc.WriteBlob32((*[32]byte)(&v.ConcealingPoint))
|
||||
|
|
@ -322,8 +330,10 @@ func decodeOutputsV2(dec *Decoder) []types.TxOutput {
|
|||
out.Amount = dec.ReadVarint()
|
||||
targetTag := dec.ReadVariantTag()
|
||||
if targetTag == types.TargetTypeToKey {
|
||||
dec.ReadBlob32((*[32]byte)(&out.Target.Key))
|
||||
out.Target.MixAttr = dec.ReadUint8()
|
||||
var tgt types.TxOutToKey
|
||||
dec.ReadBlob32((*[32]byte)(&tgt.Key))
|
||||
tgt.MixAttr = dec.ReadUint8()
|
||||
out.Target = tgt
|
||||
} else {
|
||||
dec.err = fmt.Errorf("wire: unsupported target tag 0x%02x", targetTag)
|
||||
return vout
|
||||
|
|
|
|||
|
|
@ -65,8 +65,12 @@ func TestCoinbaseTxEncodeDecode_Good(t *testing.T) {
|
|||
if bare.Amount != 1000000 {
|
||||
t.Errorf("amount: got %d, want 1000000", bare.Amount)
|
||||
}
|
||||
if bare.Target.Key[0] != 0xDE || bare.Target.Key[1] != 0xAD {
|
||||
t.Errorf("target key: got %x, want DE AD...", bare.Target.Key[:2])
|
||||
toKey, ok := bare.Target.(types.TxOutToKey)
|
||||
if !ok {
|
||||
t.Fatalf("target type: got %T, want TxOutToKey", bare.Target)
|
||||
}
|
||||
if toKey.Key[0] != 0xDE || toKey.Key[1] != 0xAD {
|
||||
t.Errorf("target key: got %x, want DE AD...", toKey.Key[:2])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue