Subscribers to the BlockChecked validation interface event may need access to the block outside of the callback scope. Currently, this is only possible by copying the block, which makes exposing this validation interface event publicly either cumbersome or with significant copy overhead.
By using shared_ptr, we make the shared ownership explicit and allow users to safely use the block outside of the callback scope. By using a const-ref shared_ptr, no atomic reference count cost is incurred if a subscriber does not require block ownership.
For example: in #30595, this would allow us to drop the kernel_BlockPointer
handle entirely, and generalize everything into kernel_Block
. This PoC is implemented in https://github.com/stickies-v/bitcoin/commits/kernel/remove-blockpointer/.
Performance
I have added a benchmark in a separate branch, to ensure this change does not lead to a problematic performance regression. Since most of the overhead comes from the subscribers, I have added scenarios for One
, Two
, and Ten
subscribers. From these results, it appears there is no meaningful performance difference on my machine.
When BlockChecked()
takes a const CBlock&
reference (master):
ns/op | op/s | err% | total | benchmark |
---|---|---|---|---|
170.09 | 5,879,308.26 | 0.3% | 0.01 | BlockCheckedOne |
1,603.95 | 623,460.10 | 0.5% | 0.01 | BlockCheckedTen |
336.00 | 2,976,173.37 | 1.1% | 0.01 | BlockCheckedTwo |
When BlockChecked()
takes a const std::shared_ptr<const CBlock>&
(this PR):
ns/op | op/s | err% | total | benchmark |
---|---|---|---|---|
172.20 | 5,807,155.33 | 0.1% | 0.01 | BlockCheckedOne |
1,596.79 | 626,254.52 | 0.0% | 0.01 | BlockCheckedTen |
333.38 | 2,999,603.17 | 0.3% | 0.01 | BlockCheckedTwo |