prysm-pulse/beacon-chain/rpc/eth/helpers/sync.go
Radosław Kapka 578fea73d7
API's IsOptimistic - update header.StateRoot only when block is not missing (#10852)
* bug fix

* tests

* comment

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2022-06-09 19:35:35 +00:00

64 lines
2.2 KiB
Go

package helpers
import (
"bytes"
"context"
"strconv"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/api/grpc"
"github.com/prysmaticlabs/prysm/beacon-chain/blockchain"
"github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/beacon-chain/sync"
"github.com/prysmaticlabs/prysm/config/params"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
// ValidateSync checks whether the node is currently syncing and returns an error if it is.
// It also appends syncing info to gRPC headers.
func ValidateSync(ctx context.Context, syncChecker sync.Checker, headFetcher blockchain.HeadFetcher, timeFetcher blockchain.TimeFetcher) error {
if !syncChecker.Syncing() {
return nil
}
headSlot := headFetcher.HeadSlot()
syncDetailsContainer := &SyncDetailsContainer{
SyncDetails: &SyncDetails{
HeadSlot: strconv.FormatUint(uint64(headSlot), 10),
SyncDistance: strconv.FormatUint(uint64(timeFetcher.CurrentSlot()-headSlot), 10),
IsSyncing: true,
},
}
err := grpc.AppendCustomErrorHeader(ctx, syncDetailsContainer)
if err != nil {
return status.Errorf(
codes.Internal,
"Syncing to latest head, not ready to respond. Could not prepare sync details: %v",
err,
)
}
return status.Error(codes.Unavailable, "Syncing to latest head, not ready to respond")
}
// IsOptimistic checks whether the latest block header of the passed in beacon state is the header of an optimistic block.
func IsOptimistic(ctx context.Context, st state.BeaconState, optimisticSyncFetcher blockchain.OptimisticModeFetcher) (bool, error) {
header := st.LatestBlockHeader()
// This happens when the block at the state's slot is not missing.
if bytes.Equal(header.StateRoot, params.BeaconConfig().ZeroHash[:]) {
root, err := st.HashTreeRoot(ctx)
if err != nil {
return false, errors.Wrap(err, "could not get state root")
}
header.StateRoot = root[:]
}
headRoot, err := header.HashTreeRoot()
if err != nil {
return false, errors.Wrap(err, "could not get header root")
}
isOptimistic, err := optimisticSyncFetcher.IsOptimisticForRoot(ctx, headRoot)
if err != nil {
return false, errors.Wrap(err, "could not check if block is optimistic")
}
return isOptimistic, nil
}