Compare commits

...

2 Commits

Author SHA1 Message Date
Kasey Kirkham
f7cf17149f add missing bazel build file 2023-12-01 09:49:52 -06:00
Kasey Kirkham
1c3df826f4 lock wrapper for safer forkchoice sharing 2023-11-22 14:49:23 -06:00
3 changed files with 80 additions and 0 deletions

View File

@@ -0,0 +1,19 @@
load("@prysm//tools/go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = ["borrower.go"],
importpath = "github.com/prysmaticlabs/prysm/v4/beacon-chain/forkchoice/borrower",
visibility = ["//visibility:public"],
deps = ["//beacon-chain/forkchoice:go_default_library"],
)
go_test(
name = "go_default_test",
srcs = ["borrower_test.go"],
deps = [
":go_default_library",
"//beacon-chain/forkchoice/doubly-linked-tree:go_default_library",
"//testing/require:go_default_library",
],
)

View File

@@ -0,0 +1,42 @@
package borrower
import "github.com/prysmaticlabs/prysm/v4/beacon-chain/forkchoice"
func NewForkchoiceBorrower(fc forkchoice.ForkChoicer) *ForkchoiceBorrower {
return &ForkchoiceBorrower{fc: fc}
}
type ForkchoiceBorrower struct {
fc forkchoice.ForkChoicer
}
type BorrowedForkChoicer struct {
forkchoice.ForkChoicer
unlock func()
}
// Return ends the borrow lifecycle, calling the (Unlock/RUlock) method and nilling the
// pointer to the underlying forkchoice object so that it can no longer be used by the caller.
func (b *BorrowedForkChoicer) Return() {
if b.unlock != nil {
b.unlock()
}
b.ForkChoicer = nil
}
// Borrow is used to borrow the Forkchoicer. When the borrower is done with it, they must
// call the function, passing in the returned Forkchoicer, to invalidate the pointer.
func (fb *ForkchoiceBorrower) Borrow() (*BorrowedForkChoicer, func()) {
fb.fc.Lock()
b := &BorrowedForkChoicer{ForkChoicer: fb.fc, unlock: fb.fc.Unlock}
return b, b.Return
}
// BorrowRO is an implementation of Borrow that uses read locks rather than write locks.
// Borrow is used to borrow the Forkchoicer. When the borrower is done with it, they must
// call the function, passing in the returned Forkchoicer, to invalidate the pointer.
func (fb *ForkchoiceBorrower) BorrowRO() (*BorrowedForkChoicer, func()) {
fb.fc.RLock()
b := &BorrowedForkChoicer{ForkChoicer: fb.fc, unlock: fb.fc.RUnlock}
return b, b.Return
}

View File

@@ -0,0 +1,19 @@
package borrower_test
import (
"testing"
"github.com/prysmaticlabs/prysm/v4/beacon-chain/forkchoice/borrower"
doublylinkedtree "github.com/prysmaticlabs/prysm/v4/beacon-chain/forkchoice/doubly-linked-tree"
"github.com/prysmaticlabs/prysm/v4/testing/require"
)
func TestBorrowNilness(t *testing.T) {
realFC := doublylinkedtree.New()
fb := borrower.NewForkchoiceBorrower(realFC)
fc, r := fb.Borrow()
// just calling a method to make sure this doesn't panic
require.Equal(t, 0, fc.NodeCount())
r()
require.Equal(t, nil, fc.ForkChoicer)
}