Skip to content

Commit a7c7ade

Browse files
committed
Add Transaction
1 parent c7399fe commit a7c7ade

File tree

4 files changed

+87
-8
lines changed

4 files changed

+87
-8
lines changed

TODO.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ This document lists the remaining C API functions and data structures from `bitc
1919
## Missing Data Structures
2020

2121
### Core Transaction Types
22-
- **`kernel_Transaction`** - Transaction handling
2322
- **`kernel_ScriptPubkey`** - Script public key operations
2423
- **`kernel_TransactionOutput`** - Transaction output operations
2524
- **`kernel_BlockPointer`** - Non-owned block pointers (from callbacks)
@@ -28,10 +27,6 @@ This document lists the remaining C API functions and data structures from `bitc
2827

2928
## Missing Functions by Category
3029

31-
### Transaction Operations
32-
- [ ] `kernel_transaction_create()` - Create transaction from serialized data
33-
- [ ] `kernel_transaction_destroy()` - Cleanup transaction
34-
3530
### Script Operations
3631
- [ ] `kernel_script_pubkey_create()` - Create script pubkey
3732
- [ ] `kernel_script_pubkey_destroy()` - Cleanup script pubkey
@@ -56,9 +51,6 @@ This document lists the remaining C API functions and data structures from `bitc
5651
- [ ] `kernel_get_undo_output_by_index()` - Get specific undo output
5752
- [ ] `kernel_block_undo_destroy()` - Cleanup undo data
5853

59-
### Utility Operations
60-
- [ ] `kernel_byte_array_destroy()` - Cleanup byte arrays
61-
6254
### Callback Support
6355
- [ ] **Notification callbacks** - Full integration of kernel notification system
6456
- [ ] **Validation interface callbacks** - Block validation event handling

kernel/errors.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,6 @@ var (
1919
ErrBlockRead = errors.New("failed to read block from disk")
2020
ErrInvalidCallback = errors.New("invalid callback function")
2121
ErrLoggingConnectionCreation = errors.New("failed to create logging connection")
22+
ErrTransactionCreation = errors.New("failed to create transaction from raw data")
23+
ErrInvalidTransactionData = errors.New("invalid transaction data")
2224
)

kernel/transaction.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package kernel
2+
3+
/*
4+
#include "kernel/bitcoinkernel.h"
5+
*/
6+
import "C"
7+
import (
8+
"runtime"
9+
"unsafe"
10+
)
11+
12+
// Transaction wraps the C kernel_Transaction
13+
type Transaction struct {
14+
ptr *C.kernel_Transaction
15+
}
16+
17+
// NewTransactionFromRaw creates a new transaction from raw serialized data
18+
func NewTransactionFromRaw(rawTransaction []byte) (*Transaction, error) {
19+
if len(rawTransaction) == 0 {
20+
return nil, ErrInvalidTransactionData
21+
}
22+
23+
ptr := C.kernel_transaction_create((*C.uchar)(unsafe.Pointer(&rawTransaction[0])), C.size_t(len(rawTransaction)))
24+
if ptr == nil {
25+
return nil, ErrTransactionCreation
26+
}
27+
28+
transaction := &Transaction{ptr: ptr}
29+
runtime.SetFinalizer(transaction, (*Transaction).destroy)
30+
return transaction, nil
31+
}
32+
33+
func (t *Transaction) destroy() {
34+
if t.ptr != nil {
35+
C.kernel_transaction_destroy(t.ptr)
36+
t.ptr = nil
37+
}
38+
}
39+
40+
func (t *Transaction) Destroy() {
41+
runtime.SetFinalizer(t, nil)
42+
t.destroy()
43+
}

kernel/transaction_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package kernel
2+
3+
import (
4+
"encoding/hex"
5+
"errors"
6+
"testing"
7+
)
8+
9+
func TestInvalidTransactionData(t *testing.T) {
10+
// Test with empty data
11+
_, err := NewTransactionFromRaw([]byte{})
12+
if !errors.Is(err, ErrInvalidTransactionData) {
13+
t.Errorf("Expected ErrInvalidTransactionData, got %v", err)
14+
}
15+
16+
// Test with invalid data
17+
_, err = NewTransactionFromRaw([]byte{0x00, 0x01, 0x02})
18+
if !errors.Is(err, ErrTransactionCreation) {
19+
t.Errorf("Expected ErrTransactionCreation, got %v", err)
20+
}
21+
}
22+
23+
func TestTransactionFromRaw(t *testing.T) {
24+
txHex := "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff08044c86041b020602ffffffff0100f2052a010000004341041b0e8c2567c12536aa13357b79a073dc4444acb83c4ec7a0e2f99dd7457516c5817242da796924ca4e99947d087fedf9ce467cb9f7c6287078f801df276fdf84ac00000000"
25+
txBytes, err := hex.DecodeString(txHex)
26+
if err != nil {
27+
t.Fatalf("Failed to decode transaction hex: %v", err)
28+
}
29+
30+
tx, err := NewTransactionFromRaw(txBytes)
31+
if err != nil {
32+
t.Fatalf("NewTransactionFromRaw() error = %v", err)
33+
}
34+
if tx == nil {
35+
t.Fatal("Transaction is nil")
36+
}
37+
defer tx.Destroy()
38+
39+
if tx.ptr == nil {
40+
t.Error("Transaction pointer is nil")
41+
}
42+
}

0 commit comments

Comments
 (0)