Skip to content

Commit ce60b4e

Browse files
committed
Add new validation interface callbacks
1 parent ffe8337 commit ce60b4e

File tree

3 files changed

+80
-24
lines changed

3 files changed

+80
-24
lines changed

kernel/context_options.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ extern void go_notify_warning_unset_bridge(void* user_data, btck_Warning warning
1515
extern void go_notify_flush_error_bridge(void* user_data, const char* message, size_t message_len);
1616
extern void go_notify_fatal_error_bridge(void* user_data, const char* message, size_t message_len);
1717
extern void go_validation_interface_block_checked_bridge(void* user_data, btck_Block* block, const btck_BlockValidationState* state);
18+
extern void go_validation_interface_pow_valid_block_bridge(void* user_data, const btck_BlockTreeEntry* entry, btck_Block* block);
19+
extern void go_validation_interface_block_connected_bridge(void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry);
20+
extern void go_validation_interface_block_disconnected_bridge(void* user_data, btck_Block* block, const btck_BlockTreeEntry* entry);
1821
1922
extern void go_delete_handle(void* user_data);
2023
*/
@@ -89,9 +92,12 @@ func (opts *ContextOptions) SetNotifications(callbacks *NotificationCallbacks) {
8992
// - callbacks: The callbacks used for passing validation information to the user.
9093
func (opts *ContextOptions) SetValidationInterface(callbacks *ValidationInterfaceCallbacks) {
9194
validationCallbacks := C.btck_ValidationInterfaceCallbacks{
92-
user_data: unsafe.Pointer(cgo.NewHandle(callbacks)),
93-
user_data_destroy: C.btck_DestroyCallback(C.go_delete_handle),
94-
block_checked: C.btck_ValidationInterfaceBlockChecked(C.go_validation_interface_block_checked_bridge),
95+
user_data: unsafe.Pointer(cgo.NewHandle(callbacks)),
96+
user_data_destroy: C.btck_DestroyCallback(C.go_delete_handle),
97+
block_checked: C.btck_ValidationInterfaceBlockChecked(C.go_validation_interface_block_checked_bridge),
98+
pow_valid_block: C.btck_ValidationInterfacePowValidBlock(C.go_validation_interface_pow_valid_block_bridge),
99+
block_connected: C.btck_ValidationInterfaceBlockConnected(C.go_validation_interface_block_connected_bridge),
100+
block_disconnected: C.btck_ValidationInterfaceBlockDisconnected(C.go_validation_interface_block_disconnected_bridge),
95101
}
96102
C.btck_context_options_set_validation_interface((*C.btck_ContextOptions)(opts.ptr), validationCallbacks)
97103
}

kernel/validation_interface_callbacks.go

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,14 @@ import (
99
"unsafe"
1010
)
1111

12-
// ValidationInterfaceCallbacks contains all the Go callback function types for validation interface.
12+
// ValidationInterfaceCallbacks holds the validation interface callbacks.
13+
//
14+
// Note that these callbacks block any further validation execution when they are called.
1315
type ValidationInterfaceCallbacks struct {
14-
OnBlockChecked func(block *Block, state *BlockValidationState)
16+
OnBlockChecked func(block *Block, state *BlockValidationState) // Called when a new block has been fully validated. Contains the result of its validation.
17+
OnPowValidBlock func(entry *BlockTreeEntry, block *Block) // Called when a new block extends the header chain and has a valid transaction and segwit merkle root.
18+
OnBlockConnected func(block *Block, entry *BlockTreeEntry) // Called when a block is valid and has now been connected to the best chain.
19+
OnBlockDisconnected func(block *Block, entry *BlockTreeEntry) // Called during a re-org when a block has been removed from the best chain.
1520
}
1621

1722
//export go_validation_interface_block_checked_bridge
@@ -22,3 +27,30 @@ func go_validation_interface_block_checked_bridge(user_data unsafe.Pointer, bloc
2227
callbacks.OnBlockChecked(newBlock(block, true), &BlockValidationState{ptr: state})
2328
}
2429
}
30+
31+
//export go_validation_interface_pow_valid_block_bridge
32+
func go_validation_interface_pow_valid_block_bridge(user_data unsafe.Pointer, entry *C.btck_BlockTreeEntry, block *C.btck_Block) {
33+
handle := cgo.Handle(user_data)
34+
callbacks := handle.Value().(*ValidationInterfaceCallbacks)
35+
if callbacks.OnPowValidBlock != nil {
36+
callbacks.OnPowValidBlock(&BlockTreeEntry{ptr: entry}, newBlock(block, true))
37+
}
38+
}
39+
40+
//export go_validation_interface_block_connected_bridge
41+
func go_validation_interface_block_connected_bridge(user_data unsafe.Pointer, block *C.btck_Block, entry *C.btck_BlockTreeEntry) {
42+
handle := cgo.Handle(user_data)
43+
callbacks := handle.Value().(*ValidationInterfaceCallbacks)
44+
if callbacks.OnBlockConnected != nil {
45+
callbacks.OnBlockConnected(newBlock(block, true), &BlockTreeEntry{ptr: entry})
46+
}
47+
}
48+
49+
//export go_validation_interface_block_disconnected_bridge
50+
func go_validation_interface_block_disconnected_bridge(user_data unsafe.Pointer, block *C.btck_Block, entry *C.btck_BlockTreeEntry) {
51+
handle := cgo.Handle(user_data)
52+
callbacks := handle.Value().(*ValidationInterfaceCallbacks)
53+
if callbacks.OnBlockDisconnected != nil {
54+
callbacks.OnBlockDisconnected(newBlock(block, true), &BlockTreeEntry{ptr: entry})
55+
}
56+
}

kernel/validation_interface_callbacks_test.go

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,38 +6,56 @@ import (
66
)
77

88
func TestValidationInterfaceCallbacks(t *testing.T) {
9-
var blockCheckedCalled bool
9+
10+
var lastBlockCheckedBlockData []byte
1011
var lastValidationMode ValidationMode
11-
var lastBlockData []byte
1212

13-
callbacks := &ValidationInterfaceCallbacks{
14-
OnBlockChecked: func(block *Block, state *BlockValidationState) {
15-
blockCheckedCalled = true
16-
lastValidationMode = state.ValidationMode()
17-
var err error
18-
lastBlockData, err = block.Bytes()
19-
if err != nil {
20-
t.Fatal(err)
21-
}
22-
},
23-
}
13+
var lastBlockConnectedBlockData []byte
14+
var lastBlockConnectedBlockHeight int32
2415

2516
suite := ChainstateManagerTestSuite{
2617
MaxBlockHeightToImport: 2,
27-
ValidationCallbacks: callbacks,
18+
ValidationCallbacks: &ValidationInterfaceCallbacks{
19+
OnBlockChecked: func(block *Block, state *BlockValidationState) {
20+
lastValidationMode = state.ValidationMode()
21+
var err error
22+
lastBlockCheckedBlockData, err = block.Bytes()
23+
if err != nil {
24+
t.Fatal(err)
25+
}
26+
},
27+
OnBlockConnected: func(block *Block, entry *BlockTreeEntry) {
28+
lastBlockConnectedBlockHeight = entry.Height()
29+
var err error
30+
lastBlockConnectedBlockData, err = block.Bytes()
31+
if err != nil {
32+
t.Fatal(err)
33+
}
34+
},
35+
},
2836
}
2937
suite.Setup(t)
3038

31-
if !blockCheckedCalled {
39+
// OnBlockChecked
40+
if lastBlockCheckedBlockData == nil {
3241
t.Error("OnBlockChecked callback was not called")
3342
}
34-
3543
if lastValidationMode != ValidationStateValid {
3644
t.Errorf("Expected validation mode %d, got %d", ValidationStateValid, lastValidationMode)
3745
}
38-
39-
lastBlockDataHex := hex.EncodeToString(lastBlockData)
40-
if lastBlockDataHex != "00000020a629da61ccd6c9de14dd22d4dcf06ac4b98828801fb58275af1ed2c89e361b79677daedb5fc7781c5907a88133cd461b4865e9a4881fecfb362304ad1806acf3a7242d66ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025200ffffffff0200f2052a010000001600141409745405c4e8310a875bcd602db6b9b3dc0cf90000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000" {
46+
expectedLastBlockDataHex := "00000020a629da61ccd6c9de14dd22d4dcf06ac4b98828801fb58275af1ed2c89e361b79677daedb5fc7781c5907a88133cd461b4865e9a4881fecfb362304ad1806acf3a7242d66ffff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff025200ffffffff0200f2052a010000001600141409745405c4e8310a875bcd602db6b9b3dc0cf90000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000"
47+
if hex.EncodeToString(lastBlockCheckedBlockData) != expectedLastBlockDataHex {
4148
t.Errorf("Unexpected block data for last block")
4249
}
50+
51+
// OnBlockConnected
52+
if lastBlockConnectedBlockData == nil {
53+
t.Error("OnBlockConnected callback was not called")
54+
}
55+
if lastBlockConnectedBlockHeight != 2 {
56+
t.Errorf("Expected connected block height 2, got %d", lastBlockConnectedBlockHeight)
57+
}
58+
if hex.EncodeToString(lastBlockConnectedBlockData) != expectedLastBlockDataHex {
59+
t.Errorf("Unexpected block data for connected block")
60+
}
4361
}

0 commit comments

Comments
 (0)