Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Geth Bindings From Prysm #11586

Merged
merged 13 commits into from
Nov 17, 2022
1 change: 0 additions & 1 deletion beacon-chain/execution/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ go_test(
"@com_github_ethereum_go_ethereum//core/beacon:go_default_library",
"@com_github_ethereum_go_ethereum//core/types:go_default_library",
"@com_github_ethereum_go_ethereum//rpc:go_default_library",
"@com_github_ethereum_go_ethereum//trie:go_default_library",
"@com_github_holiman_uint256//:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prometheus_client_golang//prometheus:go_default_library",
Expand Down
4 changes: 2 additions & 2 deletions beacon-chain/execution/block_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import (
"sync"

"github.com/ethereum/go-ethereum/common"
gethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/execution/types"
"github.com/prysmaticlabs/prysm/v3/config/params"
pb "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
"k8s.io/client-go/tools/cache"
)

Expand Down Expand Up @@ -133,7 +133,7 @@ func (c *headerCache) HeaderInfoByHeight(height *big.Int) (bool, *types.HeaderIn
// size limit. This method should be called in sequential header number order if
// the desired behavior is that the blocks with the highest header number should
// be present in the cache.
func (c *headerCache) AddHeader(hdr *gethTypes.Header) error {
func (c *headerCache) AddHeader(hdr *pb.ExecutionBlock) error {
c.lock.Lock()
defer c.lock.Unlock()

Expand Down
35 changes: 21 additions & 14 deletions beacon-chain/execution/block_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"github.com/ethereum/go-ethereum/common"
gethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/prysmaticlabs/prysm/v3/beacon-chain/execution/types"
"github.com/prysmaticlabs/prysm/v3/encoding/bytesutil"
pb "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
"github.com/prysmaticlabs/prysm/v3/testing/assert"
"github.com/prysmaticlabs/prysm/v3/testing/require"
)
Expand Down Expand Up @@ -44,33 +46,35 @@ func TestHeightKeyFn_InvalidObj(t *testing.T) {
func TestBlockCache_byHash(t *testing.T) {
cache := newHeaderCache()

header := &gethTypes.Header{
ParentHash: common.HexToHash("0x12345"),
Number: big.NewInt(55),
header := &pb.ExecutionBlock{
Header: gethTypes.Header{
ParentHash: common.HexToHash("0x12345"),
Number: big.NewInt(55),
},
}

exists, _, err := cache.HeaderInfoByHash(header.Hash())
exists, _, err := cache.HeaderInfoByHash(header.Hash)
require.NoError(t, err)
assert.Equal(t, false, exists, "Expected block info not to exist in empty cache")

err = cache.AddHeader(header)
require.NoError(t, err)

exists, fetchedInfo, err := cache.HeaderInfoByHash(header.Hash())
exists, fetchedInfo, err := cache.HeaderInfoByHash(header.Hash)
require.NoError(t, err)
assert.Equal(t, true, exists, "Expected headerInfo to exist")
assert.Equal(t, 0, fetchedInfo.Number.Cmp(header.Number), "Expected fetched info number to be equal")
assert.Equal(t, header.Hash(), fetchedInfo.Hash, "Expected hash to be equal")
assert.Equal(t, header.Hash, fetchedInfo.Hash, "Expected hash to be equal")

}

func TestBlockCache_byHeight(t *testing.T) {
cache := newHeaderCache()

header := &gethTypes.Header{
ParentHash: common.HexToHash("0x12345"),
Number: big.NewInt(55),
}
header := &pb.ExecutionBlock{
Header: gethTypes.Header{
ParentHash: common.HexToHash("0x12345"),
Number: big.NewInt(55),
}}

exists, _, err := cache.HeaderInfoByHeight(header.Number)
require.NoError(t, err)
Expand All @@ -84,16 +88,19 @@ func TestBlockCache_byHeight(t *testing.T) {
assert.Equal(t, true, exists, "Expected headerInfo to exist")

assert.Equal(t, 0, fetchedInfo.Number.Cmp(header.Number), "Expected fetched info number to be equal")
assert.Equal(t, header.Hash(), fetchedInfo.Hash, "Expected hash to be equal")
assert.Equal(t, header.Hash, fetchedInfo.Hash, "Expected hash to be equal")

}

func TestBlockCache_maxSize(t *testing.T) {
cache := newHeaderCache()

for i := int64(0); i < int64(maxCacheSize+10); i++ {
header := &gethTypes.Header{
Number: big.NewInt(i),
header := &pb.ExecutionBlock{
Header: gethTypes.Header{
Number: big.NewInt(i),
},
Hash: common.Hash(bytesutil.ToBytes32(bytesutil.Bytes32(uint64(i)))),
}
err := cache.AddHeader(header)
require.NoError(t, err)
Expand Down
18 changes: 9 additions & 9 deletions beacon-chain/execution/block_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func (s *Service) BlockExists(ctx context.Context, hash common.Hash) (bool, *big
return true, hdrInfo.Number, nil
}
span.AddAttributes(trace.BoolAttribute("blockCacheHit", false))
header, err := s.eth1DataFetcher.HeaderByHash(ctx, hash)
header, err := s.HeaderByHash(ctx, hash)
if err != nil {
return false, big.NewInt(0), errors.Wrap(err, "could not query block with given hash")
}
Expand All @@ -61,33 +61,33 @@ func (s *Service) BlockHashByHeight(ctx context.Context, height *big.Int) (commo
}
span.AddAttributes(trace.BoolAttribute("headerCacheHit", false))

if s.eth1DataFetcher == nil {
err := errors.New("nil eth1DataFetcher")
if s.rpcClient == nil {
err := errors.New("nil rpc client")
tracing.AnnotateError(span, err)
return [32]byte{}, err
}

header, err := s.eth1DataFetcher.HeaderByNumber(ctx, height)
header, err := s.HeaderByNumber(ctx, height)
if err != nil {
return [32]byte{}, errors.Wrap(err, fmt.Sprintf("could not query header with height %d", height.Uint64()))
}
if err := s.headerCache.AddHeader(header); err != nil {
return [32]byte{}, err
}
return header.Hash(), nil
return header.Hash, nil
}

// BlockTimeByHeight fetches an eth1 block timestamp by its height.
func (s *Service) BlockTimeByHeight(ctx context.Context, height *big.Int) (uint64, error) {
ctx, span := trace.StartSpan(ctx, "powchain.BlockTimeByHeight")
defer span.End()
if s.eth1DataFetcher == nil {
err := errors.New("nil eth1DataFetcher")
if s.rpcClient == nil {
err := errors.New("nil rpc client")
tracing.AnnotateError(span, err)
return 0, err
}

header, err := s.eth1DataFetcher.HeaderByNumber(ctx, height)
header, err := s.HeaderByNumber(ctx, height)
if err != nil {
return 0, errors.Wrap(err, fmt.Sprintf("could not query block with height %d", height.Uint64()))
}
Expand Down Expand Up @@ -207,7 +207,7 @@ func (s *Service) retrieveHeaderInfo(ctx context.Context, bNum uint64) (*types.H
return nil, err
}
if !exists {
blk, err := s.eth1DataFetcher.HeaderByNumber(ctx, bn)
blk, err := s.HeaderByNumber(ctx, bn)
if err != nil {
return nil, err
}
Expand Down
49 changes: 22 additions & 27 deletions beacon-chain/execution/block_reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,16 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
gethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/trie"
dbutil "github.com/prysmaticlabs/prysm/v3/beacon-chain/db/testing"
mockExecution "github.com/prysmaticlabs/prysm/v3/beacon-chain/execution/testing"
contracts "github.com/prysmaticlabs/prysm/v3/contracts/deposit"
"github.com/prysmaticlabs/prysm/v3/contracts/deposit/mock"
pb "github.com/prysmaticlabs/prysm/v3/proto/engine/v1"
"github.com/prysmaticlabs/prysm/v3/testing/assert"
"github.com/prysmaticlabs/prysm/v3/testing/require"
)

func setDefaultMocks(service *Service) *Service {
service.eth1DataFetcher = &goodFetcher{}
service.httpLogger = &goodLogger{}
service.cfg.stateNotifier = &goodNotifier{}
return service
Expand All @@ -44,7 +43,6 @@ func TestLatestMainchainInfo_OK(t *testing.T) {

web3Service = setDefaultMocks(web3Service)
web3Service.rpcClient = &mockExecution.RPCClient{Backend: testAcc.Backend}
web3Service.eth1DataFetcher = &goodFetcher{backend: testAcc.Backend}

web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend)
require.NoError(t, err)
Expand All @@ -57,7 +55,7 @@ func TestLatestMainchainInfo_OK(t *testing.T) {
<-exitRoutine
}()

header, err := web3Service.eth1DataFetcher.HeaderByNumber(web3Service.ctx, nil)
header, err := web3Service.HeaderByNumber(web3Service.ctx, nil)
require.NoError(t, err)

tickerChan := make(chan time.Time)
Expand All @@ -67,7 +65,7 @@ func TestLatestMainchainInfo_OK(t *testing.T) {
exitRoutine <- true

assert.Equal(t, web3Service.latestEth1Data.BlockHeight, header.Number.Uint64())
assert.Equal(t, hexutil.Encode(web3Service.latestEth1Data.BlockHash), header.Hash().Hex())
assert.Equal(t, hexutil.Encode(web3Service.latestEth1Data.BlockHash), header.Hash.Hex())
assert.Equal(t, web3Service.latestEth1Data.BlockTime, header.Time)
}

Expand All @@ -85,6 +83,7 @@ func TestBlockHashByHeight_ReturnsHash(t *testing.T) {
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")

web3Service = setDefaultMocks(web3Service)
web3Service.rpcClient = &mockExecution.RPCClient{}
ctx := context.Background()

header := &gethTypes.Header{
Expand Down Expand Up @@ -117,15 +116,17 @@ func TestBlockHashByHeight_ReturnsError_WhenNoEth1Client(t *testing.T) {
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")

web3Service = setDefaultMocks(web3Service)
web3Service.eth1DataFetcher = nil
web3Service.rpcClient = nil
ctx := context.Background()

_, err = web3Service.BlockHashByHeight(ctx, big.NewInt(0))
require.ErrorContains(t, "nil eth1DataFetcher", err)
require.ErrorContains(t, "nil rpc client", err)
}

func TestBlockExists_ValidHash(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
testAcc, err := mock.Setup()
require.NoError(t, err, "Unable to set up simulated backend")
server, endpoint, err := mockExecution.SetupRPCServer()
require.NoError(t, err)
t.Cleanup(func() {
Expand All @@ -138,16 +139,10 @@ func TestBlockExists_ValidHash(t *testing.T) {
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")

web3Service = setDefaultMocks(web3Service)

block := gethTypes.NewBlock(
&gethTypes.Header{
Number: big.NewInt(0),
},
[]*gethTypes.Transaction{},
[]*gethTypes.Header{},
[]*gethTypes.Receipt{},
new(trie.Trie),
)
web3Service.rpcClient = &mockExecution.RPCClient{Backend: testAcc.Backend}
testAcc.Backend.Commit()
block, err := testAcc.Backend.BlockByNumber(context.Background(), big.NewInt(0))
assert.NoError(t, err)

exists, height, err := web3Service.BlockExists(context.Background(), block.Hash())
require.NoError(t, err, "Could not get block hash with given height")
Expand Down Expand Up @@ -191,17 +186,17 @@ func TestBlockExists_UsesCachedBlockInfo(t *testing.T) {
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
// nil eth1DataFetcher would panic if cached value not used
web3Service.eth1DataFetcher = nil

header := &gethTypes.Header{
Number: big.NewInt(0),
header := &pb.ExecutionBlock{
Header: gethTypes.Header{
Number: big.NewInt(0),
},
}

err = web3Service.headerCache.AddHeader(header)
require.NoError(t, err)

exists, height, err := web3Service.BlockExists(context.Background(), header.Hash())
exists, height, err := web3Service.BlockExists(context.Background(), header.Hash)
require.NoError(t, err, "Could not get block hash with given height")
require.Equal(t, true, exists)
require.Equal(t, 0, height.Cmp(header.Number))
Expand All @@ -222,7 +217,7 @@ func TestService_BlockNumberByTimestamp(t *testing.T) {
)
require.NoError(t, err)
web3Service = setDefaultMocks(web3Service)
web3Service.eth1DataFetcher = &goodFetcher{backend: testAcc.Backend}
web3Service.rpcClient = &mockExecution.RPCClient{Backend: testAcc.Backend}

for i := 0; i < 200; i++ {
testAcc.Backend.Commit()
Expand Down Expand Up @@ -254,7 +249,7 @@ func TestService_BlockNumberByTimestampLessTargetTime(t *testing.T) {
)
require.NoError(t, err)
web3Service = setDefaultMocks(web3Service)
web3Service.eth1DataFetcher = &goodFetcher{backend: testAcc.Backend}
web3Service.rpcClient = &mockExecution.RPCClient{Backend: testAcc.Backend}

for i := 0; i < 200; i++ {
testAcc.Backend.Commit()
Expand Down Expand Up @@ -292,7 +287,7 @@ func TestService_BlockNumberByTimestampMoreTargetTime(t *testing.T) {
)
require.NoError(t, err)
web3Service = setDefaultMocks(web3Service)
web3Service.eth1DataFetcher = &goodFetcher{backend: testAcc.Backend}
web3Service.rpcClient = &mockExecution.RPCClient{Backend: testAcc.Backend}

for i := 0; i < 200; i++ {
testAcc.Backend.Commit()
Expand Down Expand Up @@ -329,9 +324,9 @@ func TestService_BlockTimeByHeight_ReturnsError_WhenNoEth1Client(t *testing.T) {
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")

web3Service = setDefaultMocks(web3Service)
web3Service.eth1DataFetcher = nil
web3Service.rpcClient = nil
ctx := context.Background()

_, err = web3Service.BlockTimeByHeight(ctx, big.NewInt(0))
require.ErrorContains(t, "nil eth1DataFetcher", err)
require.ErrorContains(t, "nil rpc client", err)
}
38 changes: 38 additions & 0 deletions beacon-chain/execution/engine_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strings"
"time"

"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
gethRPC "github.com/ethereum/go-ethereum/rpc"
Expand Down Expand Up @@ -354,6 +355,24 @@ func (s *Service) ExecutionBlocksByHashes(ctx context.Context, hashes []common.H
return execBlks, nil
}

func (s *Service) HeaderByHash(ctx context.Context, hash common.Hash) (*pb.ExecutionBlock, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing doc

var blk *pb.ExecutionBlock
err := s.rpcClient.CallContext(ctx, &blk, "eth_getBlockByHash", hash, false /* no transactions */)
if err == nil && blk == nil {
err = ethereum.NotFound
}
return blk, err
}

func (s *Service) HeaderByNumber(ctx context.Context, number *big.Int) (*pb.ExecutionBlock, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing doc

var blk *pb.ExecutionBlock
err := s.rpcClient.CallContext(ctx, &blk, "eth_getBlockByNumber", toBlockNumArg(number), false /* no transactions */)
if err == nil && blk == nil {
err = ethereum.NotFound
}
return blk, err
}

// ReconstructFullBellatrixBlock takes in a blinded beacon block and reconstructs
// a beacon block with a full execution payload via the engine API.
func (s *Service) ReconstructFullBellatrixBlock(
Expand Down Expand Up @@ -610,3 +629,22 @@ func buildEmptyExecutionPayload() *pb.ExecutionPayload {
ExtraData: make([]byte, 0),
}
}

func toBlockNumArg(number *big.Int) string {
if number == nil {
return "latest"
}
pending := big.NewInt(-1)
if number.Cmp(pending) == 0 {
return "pending"
}
finalized := big.NewInt(int64(gethRPC.FinalizedBlockNumber))
if number.Cmp(finalized) == 0 {
return "finalized"
}
safe := big.NewInt(int64(gethRPC.SafeBlockNumber))
if number.Cmp(safe) == 0 {
return "safe"
}
return hexutil.EncodeBig(number)
}
Loading