Files
prysm/beacon-chain/execution/block_reader_test.go
Preston Van Loon 2fd6bd8150 Add golang.org/x/tools modernize static analyzer and fix violations (#15946)
* Ran gopls modernize to fix everything

go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest -fix -test ./...

* Override rules_go provided dependency for golang.org/x/tools to v0.38.0.

To update this, checked out rules_go, then ran `bazel run //go/tools/releaser -- upgrade-dep -mirror=false org_golang_x_tools` and copied the patches.

* Fix buildtag violations and ignore buildtag violations in external

* Introduce modernize analyzer package.

* Add modernize "any" analyzer.

* Fix violations of any analyzer

* Add modernize "appendclipped" analyzer.

* Fix violations of appendclipped

* Add modernize "bloop" analyzer.

* Add modernize "fmtappendf" analyzer.

* Add modernize "forvar" analyzer.

* Add modernize "mapsloop" analyzer.

* Add modernize "minmax" analyzer.

* Fix violations of minmax analyzer

* Add modernize "omitzero" analyzer.

* Add modernize "rangeint" analyzer.

* Fix violations of rangeint.

* Add modernize "reflecttypefor" analyzer.

* Fix violations of reflecttypefor analyzer.

* Add modernize "slicescontains" analyzer.

* Add modernize "slicessort" analyzer.

* Add modernize "slicesdelete" analyzer. This is disabled by default for now. See https://go.dev/issue/73686.

* Add modernize "stringscutprefix" analyzer.

* Add modernize "stringsbuilder" analyzer.

* Fix violations of stringsbuilder analyzer.

* Add modernize "stringsseq" analyzer.

* Add modernize "testingcontext" analyzer.

* Add modernize "waitgroup" analyzer.

* Changelog fragment

* gofmt

* gazelle

* Add modernize "newexpr" analyzer.

* Disable newexpr until go1.26

* Add more details in WORKSPACE on how to update the override

* @nalepae feedback on min()

* gofmt

* Fix violations of forvar
2025-11-14 01:27:22 +00:00

340 lines
11 KiB
Go

package execution
import (
"context"
"math/big"
"testing"
"time"
dbutil "github.com/OffchainLabs/prysm/v7/beacon-chain/db/testing"
mockExecution "github.com/OffchainLabs/prysm/v7/beacon-chain/execution/testing"
"github.com/OffchainLabs/prysm/v7/beacon-chain/execution/types"
"github.com/OffchainLabs/prysm/v7/config/params"
contracts "github.com/OffchainLabs/prysm/v7/contracts/deposit"
"github.com/OffchainLabs/prysm/v7/contracts/deposit/mock"
"github.com/OffchainLabs/prysm/v7/testing/assert"
"github.com/OffchainLabs/prysm/v7/testing/require"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
gethTypes "github.com/ethereum/go-ethereum/core/types"
)
func setDefaultMocks(service *Service) *Service {
service.httpLogger = &goodLogger{}
service.cfg.stateNotifier = &goodNotifier{}
return service
}
func TestLatestMainchainInfo_OK(t *testing.T) {
testAcc, err := mock.Setup()
require.NoError(t, err, "Unable to set up simulated backend")
beaconDB := dbutil.SetupDB(t)
server, endpoint, err := mockExecution.SetupRPCServer()
require.NoError(t, err)
t.Cleanup(func() {
server.Stop()
})
web3Service, err := NewService(t.Context(),
WithHttpEndpoint(endpoint),
WithDepositContractAddress(testAcc.ContractAddr),
WithDatabase(beaconDB),
)
require.NoError(t, err, "Unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
web3Service.rpcClient = &mockExecution.RPCClient{Backend: testAcc.Backend}
web3Service.depositContractCaller, err = contracts.NewDepositContractCaller(testAcc.ContractAddr, testAcc.Backend.Client())
require.NoError(t, err)
testAcc.Backend.Commit()
tickerChan := make(chan time.Time)
web3Service.eth1HeadTicker = &time.Ticker{C: tickerChan}
exitRoutine := make(chan bool)
go func() {
web3Service.run(web3Service.ctx.Done())
<-exitRoutine
}()
header, err := web3Service.HeaderByNumber(web3Service.ctx, nil)
require.NoError(t, err)
tickerChan <- time.Now()
web3Service.cancel()
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, web3Service.latestEth1Data.BlockTime, header.Time)
}
func TestBlockHashByHeight_ReturnsHash(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
server, endpoint, err := mockExecution.SetupRPCServer()
require.NoError(t, err)
t.Cleanup(func() {
server.Stop()
})
web3Service, err := NewService(t.Context(),
WithHttpEndpoint(endpoint),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
web3Service.rpcClient = &mockExecution.RPCClient{}
ctx := t.Context()
header := &gethTypes.Header{
Number: big.NewInt(15),
Time: 150,
}
wanted := header.Hash()
hash, err := web3Service.BlockHashByHeight(ctx, big.NewInt(0))
require.NoError(t, err, "Could not get block hash with given height")
require.DeepEqual(t, wanted.Bytes(), hash.Bytes(), "Block hash did not equal expected hash")
exists, _, err := web3Service.headerCache.HeaderInfoByHash(wanted)
require.NoError(t, err)
require.Equal(t, true, exists, "Expected block info to be cached")
}
func TestBlockHashByHeight_ReturnsError_WhenNoEth1Client(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
server, endpoint, err := mockExecution.SetupRPCServer()
require.NoError(t, err)
t.Cleanup(func() {
server.Stop()
})
web3Service, err := NewService(t.Context(),
WithHttpEndpoint(endpoint),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
web3Service.rpcClient = nil
ctx := t.Context()
_, err = web3Service.BlockHashByHeight(ctx, big.NewInt(0))
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() {
server.Stop()
})
web3Service, err := NewService(t.Context(),
WithHttpEndpoint(endpoint),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
web3Service.rpcClient = &mockExecution.RPCClient{Backend: testAcc.Backend}
testAcc.Backend.Commit()
block, err := testAcc.Backend.Client().BlockByNumber(t.Context(), big.NewInt(0))
assert.NoError(t, err)
exists, height, err := web3Service.BlockExists(t.Context(), block.Hash())
require.NoError(t, err, "Could not get block hash with given height")
require.Equal(t, true, exists)
require.Equal(t, 0, height.Cmp(block.Number()))
exists, _, err = web3Service.headerCache.HeaderInfoByHeight(height)
require.NoError(t, err)
require.Equal(t, true, exists, "Expected block to be cached")
}
func TestBlockExists_InvalidHash(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
server, endpoint, err := mockExecution.SetupRPCServer()
require.NoError(t, err)
t.Cleanup(func() {
server.Stop()
})
web3Service, err := NewService(t.Context(),
WithHttpEndpoint(endpoint),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
_, _, err = web3Service.BlockExists(t.Context(), common.BytesToHash([]byte{0}))
require.NotNil(t, err, "Expected BlockExists to error with invalid hash")
}
func TestBlockExists_UsesCachedBlockInfo(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
server, endpoint, err := mockExecution.SetupRPCServer()
require.NoError(t, err)
t.Cleanup(func() {
server.Stop()
})
web3Service, err := NewService(t.Context(),
WithHttpEndpoint(endpoint),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
header := &types.HeaderInfo{
Number: big.NewInt(0),
}
err = web3Service.headerCache.AddHeader(header)
require.NoError(t, err)
exists, height, err := web3Service.BlockExists(t.Context(), 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))
}
func TestService_BlockNumberByTimestamp(t *testing.T) {
ctx := t.Context()
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() {
server.Stop()
})
web3Service, err := NewService(t.Context(),
WithHttpEndpoint(endpoint),
WithDatabase(beaconDB),
)
require.NoError(t, err)
web3Service = setDefaultMocks(web3Service)
web3Service.rpcClient = &mockExecution.RPCClient{Backend: testAcc.Backend}
// simulated backend sets eth1 block
params.SetupTestConfigCleanup(t)
conf := params.BeaconConfig().Copy()
conf.SecondsPerETH1Block = 1
params.OverrideBeaconConfig(conf)
initialHead, err := testAcc.Backend.Client().HeaderByNumber(ctx, nil)
require.NoError(t, err)
for range 200 {
testAcc.Backend.Commit()
}
hd, err := testAcc.Backend.Client().HeaderByNumber(ctx, nil)
require.NoError(t, err)
web3Service.latestEth1Data.BlockTime = hd.Time
web3Service.latestEth1Data.BlockHeight = hd.Number.Uint64()
blk, err := web3Service.BlockByTimestamp(ctx, initialHead.Time+100 /* time */)
require.NoError(t, err)
if blk.Number.Cmp(big.NewInt(0)) == 0 {
t.Error("Returned a block with zero number, expected to be non zero")
}
}
func TestService_BlockNumberByTimestampLessTargetTime(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() {
server.Stop()
})
web3Service, err := NewService(t.Context(),
WithHttpEndpoint(endpoint),
WithDatabase(beaconDB),
)
require.NoError(t, err)
web3Service = setDefaultMocks(web3Service)
web3Service.rpcClient = &mockExecution.RPCClient{Backend: testAcc.Backend}
for range 200 {
testAcc.Backend.Commit()
}
ctx := t.Context()
hd, err := testAcc.Backend.Client().HeaderByNumber(ctx, nil)
require.NoError(t, err)
web3Service.latestEth1Data.BlockTime = hd.Time
// Use extremely small deadline to illustrate that context deadlines are respected.
ctx, cancel := context.WithTimeout(ctx, 100*time.Nanosecond)
defer cancel()
// Provide an unattainable target time
_, err = web3Service.findMaxTargetEth1Block(ctx, hd.Number, hd.Time/2)
require.ErrorContains(t, context.DeadlineExceeded.Error(), err)
// Provide an attainable target time
blk, err := web3Service.findMaxTargetEth1Block(t.Context(), hd.Number, hd.Time-5)
require.NoError(t, err)
require.NotEqual(t, hd.Number.Uint64(), blk.Number.Uint64(), "retrieved block is not less than the head")
}
func TestService_BlockNumberByTimestampMoreTargetTime(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() {
server.Stop()
})
web3Service, err := NewService(t.Context(),
WithHttpEndpoint(endpoint),
WithDatabase(beaconDB),
)
require.NoError(t, err)
web3Service = setDefaultMocks(web3Service)
web3Service.rpcClient = &mockExecution.RPCClient{Backend: testAcc.Backend}
for range 200 {
testAcc.Backend.Commit()
}
ctx := t.Context()
hd, err := testAcc.Backend.Client().HeaderByNumber(ctx, nil)
require.NoError(t, err)
web3Service.latestEth1Data.BlockTime = hd.Time
// Use extremely small deadline to illustrate that context deadlines are respected.
ctx, cancel := context.WithTimeout(ctx, 100*time.Nanosecond)
defer cancel()
// Provide an unattainable target time with respect to head
_, err = web3Service.findMinTargetEth1Block(ctx, big.NewInt(0).Div(hd.Number, big.NewInt(2)), hd.Time)
require.ErrorContains(t, context.DeadlineExceeded.Error(), err)
// Provide an attainable target time with respect to head
blk, err := web3Service.findMinTargetEth1Block(t.Context(), big.NewInt(0).Sub(hd.Number, big.NewInt(5)), hd.Time)
require.NoError(t, err)
require.Equal(t, hd.Number.Uint64(), blk.Number.Uint64(), "retrieved block is not equal to the head")
}
func TestService_BlockTimeByHeight_ReturnsError_WhenNoEth1Client(t *testing.T) {
beaconDB := dbutil.SetupDB(t)
server, endpoint, err := mockExecution.SetupRPCServer()
require.NoError(t, err)
t.Cleanup(func() {
server.Stop()
})
web3Service, err := NewService(t.Context(),
WithHttpEndpoint(endpoint),
WithDatabase(beaconDB),
)
require.NoError(t, err, "unable to setup web3 ETH1.0 chain service")
web3Service = setDefaultMocks(web3Service)
web3Service.rpcClient = nil
ctx := t.Context()
_, err = web3Service.BlockTimeByHeight(ctx, big.NewInt(0))
require.ErrorContains(t, "nil rpc client", err)
}