Skip to content

Commit a0dcba7

Browse files
committed
Add Txid struct and its methods with test coverage
1 parent f355838 commit a0dcba7

File tree

4 files changed

+122
-64
lines changed

4 files changed

+122
-64
lines changed

kernel/transaction.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,9 @@ func (t *transactionApi) Bytes() ([]byte, error) {
104104
}
105105
return bytes, nil
106106
}
107+
108+
// GetTxid returns the txid for this transaction.
109+
func (t *transactionApi) GetTxid() *TxidView {
110+
ptr := C.btck_transaction_get_txid(t.ptr)
111+
return newTxidView(check(ptr))
112+
}

kernel/transaction_test.go

Lines changed: 11 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ func TestInvalidTransactionData(t *testing.T) {
1515
}
1616
}
1717

18-
func TestTransactionFromRaw(t *testing.T) {
18+
func TestTransaction(t *testing.T) {
1919
txHex := "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff08044c86041b020602ffffffff0100f2052a010000004341041b0e8c2567c12536aa13357b79a073dc4444acb83c4ec7a0e2f99dd7457516c5817242da796924ca4e99947d087fedf9ce467cb9f7c6287078f801df276fdf84ac00000000"
2020
txBytes, err := hex.DecodeString(txHex)
2121
if err != nil {
@@ -24,7 +24,7 @@ func TestTransactionFromRaw(t *testing.T) {
2424

2525
tx, err := NewTransaction(txBytes)
2626
if err != nil {
27-
t.Fatalf("NewTransactionFromRaw() error = %v", err)
27+
t.Fatalf("NewTransaction() error = %v", err)
2828
}
2929
if tx == nil {
3030
t.Fatal("Transaction is nil")
@@ -34,22 +34,8 @@ func TestTransactionFromRaw(t *testing.T) {
3434
if tx.handle.ptr == nil {
3535
t.Error("Transaction pointer is nil")
3636
}
37-
}
38-
39-
func TestTransactionCopy(t *testing.T) {
40-
txHex := "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff08044c86041b020602ffffffff0100f2052a010000004341041b0e8c2567c12536aa13357b79a073dc4444acb83c4ec7a0e2f99dd7457516c5817242da796924ca4e99947d087fedf9ce467cb9f7c6287078f801df276fdf84ac00000000"
41-
txBytes, err := hex.DecodeString(txHex)
42-
if err != nil {
43-
t.Fatalf("Failed to decode transaction hex: %v", err)
44-
}
45-
46-
tx, err := NewTransaction(txBytes)
47-
if err != nil {
48-
t.Fatalf("NewTransactionFromRaw() error = %v", err)
49-
}
50-
defer tx.Destroy()
5137

52-
// Test copying transaction
38+
// Test Copy()
5339
txCopy := tx.Copy()
5440
if txCopy == nil {
5541
t.Fatal("Copied transaction is nil")
@@ -59,77 +45,38 @@ func TestTransactionCopy(t *testing.T) {
5945
if txCopy.handle.ptr == nil {
6046
t.Error("Copied transaction pointer is nil")
6147
}
62-
}
63-
64-
func TestTransactionCountInputsOutputs(t *testing.T) {
65-
txHex := "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff08044c86041b020602ffffffff0100f2052a010000004341041b0e8c2567c12536aa13357b79a073dc4444acb83c4ec7a0e2f99dd7457516c5817242da796924ca4e99947d087fedf9ce467cb9f7c6287078f801df276fdf84ac00000000"
66-
txBytes, err := hex.DecodeString(txHex)
67-
if err != nil {
68-
t.Fatalf("Failed to decode transaction hex: %v", err)
69-
}
70-
71-
tx, err := NewTransaction(txBytes)
72-
if err != nil {
73-
t.Fatalf("NewTransactionFromRaw() error = %v", err)
74-
}
75-
defer tx.Destroy()
7648

77-
// Test counting inputs (this is a coinbase transaction with 1 input)
49+
// Test CountInputs() (this is a coinbase transaction with 1 input)
7850
inputCount := tx.CountInputs()
7951
if inputCount != 1 {
8052
t.Errorf("Expected 1 input, got %d", inputCount)
8153
}
8254

83-
// Test counting outputs (this transaction has 1 output)
55+
// Test CountOutputs() (this transaction has 1 output)
8456
outputCount := tx.CountOutputs()
8557
if outputCount != 1 {
8658
t.Errorf("Expected 1 output, got %d", outputCount)
8759
}
88-
}
89-
90-
func TestTransactionGetOutputAt(t *testing.T) {
91-
txHex := "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff08044c86041b020602ffffffff0100f2052a010000004341041b0e8c2567c12536aa13357b79a073dc4444acb83c4ec7a0e2f99dd7457516c5817242da796924ca4e99947d087fedf9ce467cb9f7c6287078f801df276fdf84ac00000000"
92-
txBytes, err := hex.DecodeString(txHex)
93-
if err != nil {
94-
t.Fatalf("Failed to decode transaction hex: %v", err)
95-
}
96-
97-
tx, err := NewTransaction(txBytes)
98-
if err != nil {
99-
t.Fatalf("NewTransactionFromRaw() error = %v", err)
100-
}
101-
defer tx.Destroy()
10260

103-
// Test getting output at index 0
61+
// Test GetOutput()
10462
output, err := tx.GetOutput(0)
10563
if err != nil {
106-
t.Fatalf("Transaction.GetOutputAt(0) error = %v", err)
64+
t.Fatalf("GetOutput(0) error = %v", err)
10765
}
10866
if output == nil {
10967
t.Fatal("Output is nil")
11068
}
11169
if output.ptr == nil {
11270
t.Error("Output pointer is nil")
11371
}
114-
}
11572

116-
func TestTransactionToBytes(t *testing.T) {
117-
txHex := "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff08044c86041b020602ffffffff0100f2052a010000004341041b0e8c2567c12536aa13357b79a073dc4444acb83c4ec7a0e2f99dd7457516c5817242da796924ca4e99947d087fedf9ce467cb9f7c6287078f801df276fdf84ac00000000"
118-
txBytes, err := hex.DecodeString(txHex)
119-
if err != nil {
120-
t.Fatalf("Failed to decode transaction hex: %v", err)
121-
}
122-
123-
tx, err := NewTransaction(txBytes)
124-
if err != nil {
125-
t.Fatalf("NewTransactionFromRaw() error = %v", err)
126-
}
127-
defer tx.Destroy()
73+
// Test GetTxid()
74+
_ = tx.GetTxid()
12875

129-
// Test serializing transaction back to bytes
76+
// Test Bytes()
13077
serialized, err := tx.Bytes()
13178
if err != nil {
132-
t.Fatalf("Transaction.ToBytes() error = %v", err)
79+
t.Fatalf("Bytes() error = %v", err)
13380
}
13481

13582
if len(serialized) == 0 {

kernel/txid.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package kernel
2+
3+
/*
4+
#include "kernel/bitcoinkernel.h"
5+
*/
6+
import "C"
7+
import (
8+
"unsafe"
9+
)
10+
11+
type txidCFuncs struct{}
12+
13+
func (txidCFuncs) destroy(ptr unsafe.Pointer) {
14+
C.btck_txid_destroy((*C.btck_Txid)(ptr))
15+
}
16+
17+
func (txidCFuncs) copy(ptr unsafe.Pointer) unsafe.Pointer {
18+
return unsafe.Pointer(C.btck_txid_copy((*C.btck_Txid)(ptr)))
19+
}
20+
21+
type Txid struct {
22+
*handle
23+
txidApi
24+
}
25+
26+
func newTxid(ptr *C.btck_Txid, fromOwned bool) *Txid {
27+
h := newHandle(unsafe.Pointer(ptr), txidCFuncs{}, fromOwned)
28+
return &Txid{handle: h, txidApi: txidApi{(*C.btck_Txid)(h.ptr)}}
29+
}
30+
31+
type TxidView struct {
32+
txidApi
33+
ptr *C.btck_Txid
34+
}
35+
36+
func newTxidView(ptr *C.btck_Txid) *TxidView {
37+
return &TxidView{
38+
txidApi: txidApi{ptr},
39+
ptr: ptr,
40+
}
41+
}
42+
43+
type txidApi struct {
44+
ptr *C.btck_Txid
45+
}
46+
47+
// Copy creates a copy of the txid.
48+
func (t *txidApi) Copy() *Txid {
49+
return newTxid(t.ptr, false)
50+
}
51+
52+
// Equals checks if two txids are equal.
53+
func (t *txidApi) Equals(other *Txid) bool {
54+
return C.btck_txid_equals(t.ptr, other.txidApi.ptr) != 0
55+
}
56+
57+
// Bytes returns the 32-byte representation of the txid.
58+
func (t *txidApi) Bytes() [32]byte {
59+
var output [32]C.uchar
60+
C.btck_txid_to_bytes(t.ptr, &output[0])
61+
return *(*[32]byte)(unsafe.Pointer(&output[0]))
62+
}

kernel/txid_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package kernel
2+
3+
import (
4+
"encoding/hex"
5+
"testing"
6+
)
7+
8+
func TestTxid(t *testing.T) {
9+
txHex := "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff08044c86041b020602ffffffff0100f2052a010000004341041b0e8c2567c12536aa13357b79a073dc4444acb83c4ec7a0e2f99dd7457516c5817242da796924ca4e99947d087fedf9ce467cb9f7c6287078f801df276fdf84ac00000000"
10+
txBytes, err := hex.DecodeString(txHex)
11+
if err != nil {
12+
t.Fatalf("Failed to decode transaction hex: %v", err)
13+
}
14+
15+
tx, err := NewTransaction(txBytes)
16+
if err != nil {
17+
t.Fatalf("NewTransaction() error = %v", err)
18+
}
19+
defer tx.Destroy()
20+
txid := tx.GetTxid()
21+
if txid == nil {
22+
t.Fatal("GetTxid() returned nil")
23+
}
24+
25+
// Test Bytes()
26+
txidBytes := txid.Bytes()
27+
if txidBytes == [32]byte{} {
28+
t.Error("Txid.Bytes() returned empty bytes")
29+
}
30+
31+
// Test Copy()
32+
copiedTxid := txid.Copy()
33+
defer copiedTxid.Destroy()
34+
35+
if txid.Bytes() != copiedTxid.Bytes() {
36+
t.Errorf("Copied txid bytes differ: %x != %x", txid.Bytes(), copiedTxid.Bytes())
37+
}
38+
39+
// Test Equals()
40+
if !txid.Equals(copiedTxid) {
41+
t.Error("txid.Equals(copiedTxid) = false, want true")
42+
}
43+
}

0 commit comments

Comments
 (0)