github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/core/state/transition_no_verify_sig.go (about)

     1  package state
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"fmt"
     7  
     8  	"github.com/pkg/errors"
     9  	b "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
    10  	"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
    11  	"github.com/prysmaticlabs/prysm/beacon-chain/core/state/interop"
    12  	v "github.com/prysmaticlabs/prysm/beacon-chain/core/validators"
    13  	iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
    14  	"github.com/prysmaticlabs/prysm/proto/interfaces"
    15  	"github.com/prysmaticlabs/prysm/shared/bls"
    16  	"github.com/prysmaticlabs/prysm/shared/featureconfig"
    17  	"github.com/prysmaticlabs/prysm/shared/traceutil"
    18  	"go.opencensus.io/trace"
    19  )
    20  
    21  // ExecuteStateTransitionNoVerifyAnySig defines the procedure for a state transition function.
    22  // This does not validate any BLS signatures of attestations, block proposer signature, randao signature,
    23  // it is used for performing a state transition as quickly as possible. This function also returns a signature
    24  // set of all signatures not verified, so that they can be stored and verified later.
    25  //
    26  // WARNING: This method does not validate any signatures (i.e. calling `state_transition()` with `validate_result=False`).
    27  // This method also modifies the passed in state.
    28  //
    29  // Spec pseudocode definition:
    30  //  def state_transition(state: BeaconState, signed_block: SignedBeaconBlock, validate_result: bool=True) -> None:
    31  //    block = signed_block.message
    32  //    # Process slots (including those with no blocks) since block
    33  //    process_slots(state, block.slot)
    34  //    # Verify signature
    35  //    if validate_result:
    36  //        assert verify_block_signature(state, signed_block)
    37  //    # Process block
    38  //    process_block(state, block)
    39  //    # Verify state root
    40  //    if validate_result:
    41  //        assert block.state_root == hash_tree_root(state)
    42  func ExecuteStateTransitionNoVerifyAnySig(
    43  	ctx context.Context,
    44  	state iface.BeaconState,
    45  	signed interfaces.SignedBeaconBlock,
    46  ) (*bls.SignatureSet, iface.BeaconState, error) {
    47  	if ctx.Err() != nil {
    48  		return nil, nil, ctx.Err()
    49  	}
    50  	if signed == nil || signed.IsNil() || signed.Block().IsNil() {
    51  		return nil, nil, errors.New("nil block")
    52  	}
    53  
    54  	ctx, span := trace.StartSpan(ctx, "core.state.ExecuteStateTransitionNoVerifyAttSigs")
    55  	defer span.End()
    56  	var err error
    57  
    58  	interop.WriteBlockToDisk(signed, false /* Has the block failed */)
    59  	interop.WriteStateToDisk(state)
    60  
    61  	if featureconfig.Get().EnableNextSlotStateCache {
    62  		state, err = ProcessSlotsUsingNextSlotCache(ctx, state, signed.Block().ParentRoot(), signed.Block().Slot())
    63  		if err != nil {
    64  			return nil, nil, errors.Wrap(err, "could not process slots")
    65  		}
    66  	} else {
    67  		state, err = ProcessSlots(ctx, state, signed.Block().Slot())
    68  		if err != nil {
    69  			return nil, nil, errors.Wrap(err, "could not process slot")
    70  		}
    71  	}
    72  
    73  	// Execute per block transition.
    74  	set, state, err := ProcessBlockNoVerifyAnySig(ctx, state, signed)
    75  	if err != nil {
    76  		return nil, nil, errors.Wrap(err, "could not process block")
    77  	}
    78  
    79  	// State root validation.
    80  	postStateRoot, err := state.HashTreeRoot(ctx)
    81  	if err != nil {
    82  		return nil, nil, err
    83  	}
    84  	if !bytes.Equal(postStateRoot[:], signed.Block().StateRoot()) {
    85  		return nil, nil, fmt.Errorf("could not validate state root, wanted: %#x, received: %#x",
    86  			postStateRoot[:], signed.Block().StateRoot())
    87  	}
    88  
    89  	return set, state, nil
    90  }
    91  
    92  // CalculateStateRoot defines the procedure for a state transition function.
    93  // This does not validate any BLS signatures in a block, it is used for calculating the
    94  // state root of the state for the block proposer to use.
    95  // This does not modify state.
    96  //
    97  // WARNING: This method does not validate any BLS signatures (i.e. calling `state_transition()` with `validate_result=False`).
    98  // This is used for proposer to compute state root before proposing a new block, and this does not modify state.
    99  //
   100  // Spec pseudocode definition:
   101  //  def state_transition(state: BeaconState, signed_block: SignedBeaconBlock, validate_result: bool=True) -> None:
   102  //    block = signed_block.message
   103  //    # Process slots (including those with no blocks) since block
   104  //    process_slots(state, block.slot)
   105  //    # Verify signature
   106  //    if validate_result:
   107  //        assert verify_block_signature(state, signed_block)
   108  //    # Process block
   109  //    process_block(state, block)
   110  //    # Verify state root
   111  //    if validate_result:
   112  //        assert block.state_root == hash_tree_root(state)
   113  func CalculateStateRoot(
   114  	ctx context.Context,
   115  	state iface.BeaconState,
   116  	signed interfaces.SignedBeaconBlock,
   117  ) ([32]byte, error) {
   118  	ctx, span := trace.StartSpan(ctx, "core.state.CalculateStateRoot")
   119  	defer span.End()
   120  	if ctx.Err() != nil {
   121  		traceutil.AnnotateError(span, ctx.Err())
   122  		return [32]byte{}, ctx.Err()
   123  	}
   124  	if state == nil || state.IsNil() {
   125  		return [32]byte{}, errors.New("nil state")
   126  	}
   127  	if signed == nil || signed.IsNil() || signed.Block().IsNil() {
   128  		return [32]byte{}, errors.New("nil block")
   129  	}
   130  
   131  	// Copy state to avoid mutating the state reference.
   132  	state = state.Copy()
   133  
   134  	// Execute per slots transition.
   135  	var err error
   136  	if featureconfig.Get().EnableNextSlotStateCache {
   137  		state, err = ProcessSlotsUsingNextSlotCache(ctx, state, signed.Block().ParentRoot(), signed.Block().Slot())
   138  		if err != nil {
   139  			return [32]byte{}, errors.Wrap(err, "could not process slots")
   140  		}
   141  	} else {
   142  		state, err = ProcessSlots(ctx, state, signed.Block().Slot())
   143  		if err != nil {
   144  			return [32]byte{}, errors.Wrap(err, "could not process slot")
   145  		}
   146  	}
   147  
   148  	// Execute per block transition.
   149  	state, err = ProcessBlockForStateRoot(ctx, state, signed)
   150  	if err != nil {
   151  		return [32]byte{}, errors.Wrap(err, "could not process block")
   152  	}
   153  
   154  	return state.HashTreeRoot(ctx)
   155  }
   156  
   157  // ProcessBlockNoVerifyAnySig creates a new, modified beacon state by applying block operation
   158  // transformations as defined in the Ethereum Serenity specification. It does not validate
   159  // any block signature except for deposit and slashing signatures. It also returns the relevant
   160  // signature set from all the respective methods.
   161  //
   162  // Spec pseudocode definition:
   163  //
   164  //  def process_block(state: BeaconState, block: BeaconBlock) -> None:
   165  //    process_block_header(state, block)
   166  //    process_randao(state, block.body)
   167  //    process_eth1_data(state, block.body)
   168  //    process_operations(state, block.body)
   169  func ProcessBlockNoVerifyAnySig(
   170  	ctx context.Context,
   171  	state iface.BeaconState,
   172  	signed interfaces.SignedBeaconBlock,
   173  ) (*bls.SignatureSet, iface.BeaconState, error) {
   174  	ctx, span := trace.StartSpan(ctx, "core.state.ProcessBlockNoVerifyAnySig")
   175  	defer span.End()
   176  	if err := helpers.VerifyNilBeaconBlock(signed); err != nil {
   177  		return nil, nil, err
   178  	}
   179  
   180  	blk := signed.Block()
   181  	state, err := ProcessBlockForStateRoot(ctx, state, signed)
   182  	if err != nil {
   183  		return nil, nil, err
   184  	}
   185  
   186  	bSet, err := b.BlockSignatureSet(state, blk.ProposerIndex(), signed.Signature(), blk.HashTreeRoot)
   187  	if err != nil {
   188  		traceutil.AnnotateError(span, err)
   189  		return nil, nil, errors.Wrap(err, "could not retrieve block signature set")
   190  	}
   191  	rSet, err := b.RandaoSignatureSet(state, signed.Block().Body().RandaoReveal())
   192  	if err != nil {
   193  		traceutil.AnnotateError(span, err)
   194  		return nil, nil, errors.Wrap(err, "could not retrieve randao signature set")
   195  	}
   196  	aSet, err := b.AttestationSignatureSet(ctx, state, signed.Block().Body().Attestations())
   197  	if err != nil {
   198  		return nil, nil, errors.Wrap(err, "could not retrieve attestation signature set")
   199  	}
   200  
   201  	// Merge beacon block, randao and attestations signatures into a set.
   202  	set := bls.NewSet()
   203  	set.Join(bSet).Join(rSet).Join(aSet)
   204  
   205  	return set, state, nil
   206  }
   207  
   208  // ProcessOperationsNoVerifyAttsSigs processes the operations in the beacon block and updates beacon state
   209  // with the operations in block. It does not verify attestation signatures.
   210  //
   211  // WARNING: This method does not verify attestation signatures.
   212  // This is used to perform the block operations as fast as possible.
   213  //
   214  // Spec pseudocode definition:
   215  //
   216  //  def process_operations(state: BeaconState, body: BeaconBlockBody) -> None:
   217  //    # Verify that outstanding deposits are processed up to the maximum number of deposits
   218  //    assert len(body.deposits) == min(MAX_DEPOSITS, state.eth1_data.deposit_count - state.eth1_deposit_index)
   219  //
   220  //    def for_ops(operations: Sequence[Any], fn: Callable[[BeaconState, Any], None]) -> None:
   221  //        for operation in operations:
   222  //            fn(state, operation)
   223  //
   224  //    for_ops(body.proposer_slashings, process_proposer_slashing)
   225  //    for_ops(body.attester_slashings, process_attester_slashing)
   226  //    for_ops(body.attestations, process_attestation)
   227  //    for_ops(body.deposits, process_deposit)
   228  //    for_ops(body.voluntary_exits, process_voluntary_exit)
   229  func ProcessOperationsNoVerifyAttsSigs(
   230  	ctx context.Context,
   231  	state iface.BeaconState,
   232  	signedBeaconBlock interfaces.SignedBeaconBlock) (iface.BeaconState, error) {
   233  	ctx, span := trace.StartSpan(ctx, "core.state.ProcessOperationsNoVerifyAttsSigs")
   234  	defer span.End()
   235  	if err := helpers.VerifyNilBeaconBlock(signedBeaconBlock); err != nil {
   236  		return nil, err
   237  	}
   238  
   239  	if _, err := VerifyOperationLengths(ctx, state, signedBeaconBlock); err != nil {
   240  		return nil, errors.Wrap(err, "could not verify operation lengths")
   241  	}
   242  
   243  	state, err := b.ProcessProposerSlashings(ctx, state, signedBeaconBlock.Block().Body().ProposerSlashings(), v.SlashValidator)
   244  	if err != nil {
   245  		return nil, errors.Wrap(err, "could not process block proposer slashings")
   246  	}
   247  	state, err = b.ProcessAttesterSlashings(ctx, state, signedBeaconBlock.Block().Body().AttesterSlashings(), v.SlashValidator)
   248  	if err != nil {
   249  		return nil, errors.Wrap(err, "could not process block attester slashings")
   250  	}
   251  	state, err = b.ProcessAttestationsNoVerifySignature(ctx, state, signedBeaconBlock)
   252  	if err != nil {
   253  		return nil, errors.Wrap(err, "could not process block attestations")
   254  	}
   255  	state, err = b.ProcessDeposits(ctx, state, signedBeaconBlock.Block().Body().Deposits())
   256  	if err != nil {
   257  		return nil, errors.Wrap(err, "could not process block validator deposits")
   258  	}
   259  	state, err = b.ProcessVoluntaryExits(ctx, state, signedBeaconBlock.Block().Body().VoluntaryExits())
   260  	if err != nil {
   261  		return nil, errors.Wrap(err, "could not process validator exits")
   262  	}
   263  
   264  	return state, nil
   265  }
   266  
   267  // ProcessBlockForStateRoot processes the state for state root computation. It skips proposer signature
   268  // and randao signature verifications.
   269  func ProcessBlockForStateRoot(
   270  	ctx context.Context,
   271  	state iface.BeaconState,
   272  	signed interfaces.SignedBeaconBlock,
   273  ) (iface.BeaconState, error) {
   274  	ctx, span := trace.StartSpan(ctx, "core.state.ProcessBlockForStateRoot")
   275  	defer span.End()
   276  	if err := helpers.VerifyNilBeaconBlock(signed); err != nil {
   277  		return nil, err
   278  	}
   279  
   280  	blk := signed.Block()
   281  	body := blk.Body()
   282  	bodyRoot, err := body.HashTreeRoot()
   283  	if err != nil {
   284  		return nil, err
   285  	}
   286  	state, err = b.ProcessBlockHeaderNoVerify(state, blk.Slot(), blk.ProposerIndex(), blk.ParentRoot(), bodyRoot[:])
   287  	if err != nil {
   288  		traceutil.AnnotateError(span, err)
   289  		return nil, errors.Wrap(err, "could not process block header")
   290  	}
   291  
   292  	state, err = b.ProcessRandaoNoVerify(state, signed.Block().Body().RandaoReveal())
   293  	if err != nil {
   294  		traceutil.AnnotateError(span, err)
   295  		return nil, errors.Wrap(err, "could not verify and process randao")
   296  	}
   297  
   298  	state, err = b.ProcessEth1DataInBlock(ctx, state, signed.Block().Body().Eth1Data())
   299  	if err != nil {
   300  		traceutil.AnnotateError(span, err)
   301  		return nil, errors.Wrap(err, "could not process eth1 data")
   302  	}
   303  
   304  	state, err = ProcessOperationsNoVerifyAttsSigs(ctx, state, signed)
   305  	if err != nil {
   306  		traceutil.AnnotateError(span, err)
   307  		return nil, errors.Wrap(err, "could not process block operation")
   308  	}
   309  
   310  	return state, nil
   311  }