func (s *State) ProcessBlock(block *Block, con *config.Config, view BlockView, verifySignature bool) error {
	proposerIndex, err := s.GetBeaconProposerIndex(block.BlockHeader.SlotNumber-1, con)
	if err != nil {
		return err
	}

	if block.BlockHeader.SlotNumber != s.Slot {
		return fmt.Errorf("block has incorrect slot number (expecting: %d, got: %d)", s.Slot, block.BlockHeader.SlotNumber)
	}

	if block.BlockHeader.ValidatorIndex != proposerIndex {
		return fmt.Errorf("proposer index doesn't match (expected: %d, got %d)", proposerIndex, block.BlockHeader.ValidatorIndex)
	}

	blockWithoutSignature := block.Copy()
	blockWithoutSignature.BlockHeader.Signature = bls.EmptySignature.Serialize()
	blockWithoutSignatureRoot, err := ssz.HashTreeRoot(blockWithoutSignature)
	if err != nil {
		return err
	}

	proposal := ProposalSignedData{
		Slot:      s.Slot,
		Shard:     con.BeaconShardNumber,
		BlockHash: blockWithoutSignatureRoot,
	}

	proposalRoot, err := ssz.HashTreeRoot(proposal)
	if err != nil {
		return err
	}

	proposerPub, err := s.ValidatorRegistry[proposerIndex].GetPublicKey()
	if err != nil {
		return err
	}

	proposerSig, err := bls.DeserializeSignature(block.BlockHeader.Signature)
	if err != nil {
		return err
	}

	// process block and randao verifications concurrently

	if verifySignature {
		verificationResult := make(chan error)

		go func() {
			valid, err := bls.VerifySig(proposerPub, proposalRoot[:], proposerSig, bls.DomainProposal)
			if err != nil {
				verificationResult <- err
			}

			if !valid {
				verificationResult <- fmt.Errorf("block had invalid signature (expected signature from validator %d)", proposerIndex)
			}

			verificationResult <- nil
		}()

		var slotBytes [8]byte
		binary.BigEndian.PutUint64(slotBytes[:], block.BlockHeader.SlotNumber)
		slotBytesHash := chainhash.HashH(slotBytes[:])

		randaoSig, err := bls.DeserializeSignature(block.BlockHeader.RandaoReveal)
		if err != nil {
			return err
		}

		go func() {
			valid, err := bls.VerifySig(proposerPub, slotBytesHash[:], randaoSig, bls.DomainRandao)
			if err != nil {
				verificationResult <- err
			}
			if !valid {
				verificationResult <- errors.New("block has invalid randao signature")
			}

			verificationResult <- nil
		}()

		result1 := <-verificationResult
		result2 := <-verificationResult

		if result1 != nil {
			return result1
		}

		if result2 != nil {
			return result2
		}
	}

	randaoRevealSerialized, err := ssz.HashTreeRoot(block.BlockHeader.RandaoReveal)
	if err != nil {
		return err
	}

	for i := range s.NextRandaoMix {
		s.NextRandaoMix[i] ^= randaoRevealSerialized[i]
	}

	if len(block.BlockBody.ProposerSlashings) > con.MaxProposerSlashings {
		return errors.New("more than maximum proposer slashings")
	}

	if len(block.BlockBody.CasperSlashings) > con.MaxCasperSlashings {
		return errors.New("more than maximum casper slashings")
	}

	if len(block.BlockBody.Attestations) > con.MaxAttestations {
		return errors.New("more than maximum attestations")
	}

	if len(block.BlockBody.Exits) > con.MaxExits {
		return errors.New("more than maximum exits")
	}

	if len(block.BlockBody.Deposits) > con.MaxDeposits {
		return errors.New("more than maximum deposits")
	}

	if len(block.BlockBody.Votes) > con.MaxVotes {
		return errors.New("more than maximum votes")
	}

	for _, slashing := range block.BlockBody.ProposerSlashings {
		err := s.applyProposerSlashing(slashing, con)
		if err != nil {
			return err
		}
	}

	for _, c := range block.BlockBody.CasperSlashings {
		err := s.applyCasperSlashing(c, con)
		if err != nil {
			return err
		}
	}

	for _, a := range block.BlockBody.Attestations {
		err := s.applyAttestation(a, con, verifySignature, proposerIndex)
		if err != nil {
			return err
		}
	}

	// process deposits here

	for _, e := range block.BlockBody.Exits {
		err := s.ApplyExit(e, con)
		if err != nil {
			return err
		}
	}

	for _, v := range block.BlockBody.Votes {
		err := s.applyVote(v, con)
		if err != nil {
			return err
		}
	}

	// Check state root.
	expectedStateRoot, err := view.GetLastStateRoot()
	if err != nil {
		return err
	}
	if !block.BlockHeader.StateRoot.IsEqual(&expectedStateRoot) {
		return fmt.Errorf("state root doesn't match (expected: %s, got: %s)", expectedStateRoot, block.BlockHeader.StateRoot)
	}

	return nil
}
// ProcessBlock tries to apply a block to the state.
ProcessBlock tries to apply a block to the state.
// ProcessBlock tries to apply a block to the state .
func (s *State) ProcessBlock(block *Block, con *config.Config, view BlockView, verifySignature bool) error {
	proposerIndex, err := s.GetBeaconProposerIndex(block.BlockHeader.SlotNumber-1, con)
	if err != nil {
		return err
	}
	if block.BlockHeader.SlotNumber != s.Slot {
		return fmt.Errorf("block has incorrect slot number (expecting: %d, got: %d)", s.Slot, block.BlockHeader.SlotNumber)
	}
	if block.BlockHeader.ValidatorIndex != proposerIndex {
		return fmt.Errorf("proposer index doesn't match (expected: %d, got %d)", proposerIndex, block.BlockHeader.ValidatorIndex)
	}
	blockWithoutSignature := block.Copy()
	blockWithoutSignature.BlockHeader.Signature = bls.EmptySignature.Serialize()
	blockWithoutSignatureRoot, err := ssz.HashTreeRoot(blockWithoutSignature)
	if err != nil {
		return err
	}
	proposal := ProposalSignedData{
		Slot:      s.Slot,
		Shard:     con.BeaconShardNumber,
		BlockHash: blockWithoutSignatureRoot,
	}
	proposalRoot, err := ssz.HashTreeRoot(proposal)
	if err != nil {
		return err
	}
	proposerPub, err := s.ValidatorRegistry[proposerIndex].GetPublicKey()
	if err != nil {
		return err
	}
	proposerSig, err := bls.DeserializeSignature(block.BlockHeader.Signature)
	if err != nil {
		return err
	}
	if verifySignature {
		verificationResult := make(chan error)
		go func() {
			valid, err := bls.VerifySig(proposerPub, proposalRoot[:], proposerSig, bls.DomainProposal)
			if err != nil {
				verificationResult <- err
			}
			if !valid {
				verificationResult <- fmt.Errorf("block had invalid signature (expected signature from validator %d)", proposerIndex)
			}
			verificationResult <- nil
		}()
		var slotBytes [8]byte
		binary.BigEndian.PutUint64(slotBytes[:], block.BlockHeader.SlotNumber)
		slotBytesHash := chainhash.HashH(slotBytes[:])
		randaoSig, err := bls.DeserializeSignature(block.BlockHeader.RandaoReveal)
		if err != nil {
			return err
		}
		go func() {
			valid, err := bls.VerifySig(proposerPub, slotBytesHash[:], randaoSig, bls.DomainRandao)
			if err != nil {
				verificationResult <- err
			}
			if !valid {
				verificationResult <- errors.New("block has invalid randao signature")
			}
			verificationResult <- nil
		}()
		result1 := <-verificationResult
		result2 := <-verificationResult
		if result1 != nil {
			return result1
		}
		if result2 != nil {
			return result2
		}
	}
	randaoRevealSerialized, err := ssz.HashTreeRoot(block.BlockHeader.RandaoReveal)
	if err != nil {
		return err
	}
	for i := range s.NextRandaoMix {
		s.NextRandaoMix[i] ^= randaoRevealSerialized[i]
	}
	if len(block.BlockBody.ProposerSlashings) > con.MaxProposerSlashings {
		return errors.New("more than maximum proposer slashings")
	}
	if len(block.BlockBody.CasperSlashings) > con.MaxCasperSlashings {
		return errors.New("more than maximum casper slashings")
	}
	if len(block.BlockBody.Attestations) > con.MaxAttestations {
		return errors.New("more than maximum attestations")
	}
	if len(block.BlockBody.Exits) > con.MaxExits {
		return errors.New("more than maximum exits")
	}
	if len(block.BlockBody.Deposits) > con.MaxDeposits {
		return errors.New("more than maximum deposits")
	}
	if len(block.BlockBody.Votes) > con.MaxVotes {
		return errors.New("more than maximum votes")
	}
	for _, slashing := range block.BlockBody.ProposerSlashings {
		err := s.applyProposerSlashing(slashing, con)
		if err != nil {
			return err
		}
	}
	for _, c := range block.BlockBody.CasperSlashings {
		err := s.applyCasperSlashing(c, con)
		if err != nil {
			return err
		}
	}
	for _, a := range block.BlockBody.Attestations {
		err := s.applyAttestation(a, con, verifySignature, proposerIndex)
		if err != nil {
			return err
		}
	}
	for _, e := range block.BlockBody.Exits {
		err := s.ApplyExit(e, con)
		if err != nil {
			return err
		}
	}
	for _, v := range block.BlockBody.Votes {
		err := s.applyVote(v, con)
		if err != nil {
			return err
		}
	}
	expectedStateRoot, err := view.GetLastStateRoot()
	if err != nil {
		return err
	}
	if !block.BlockHeader.StateRoot.IsEqual(&expectedStateRoot) {
		return fmt.Errorf("state root doesn't match (expected: %s, got: %s)", expectedStateRoot, block.BlockHeader.StateRoot)
	}
	return nil
}
func ( s * State ) ProcessBlock ( block * Block , con * config . Config , view BlockView , verifySignature bool ) error { proposerIndex , err := s . GetBeaconProposerIndex ( block . BlockHeader . SlotNumber - 1 , con ) if err != nil { return err } if block . BlockHeader . SlotNumber != s . Slot { return fmt . Errorf ( " " , s . Slot , block . BlockHeader . SlotNumber ) } if block . BlockHeader . ValidatorIndex != proposerIndex { return fmt . Errorf ( " " , proposerIndex , block . BlockHeader . ValidatorIndex ) } blockWithoutSignature := block . Copy ( ) blockWithoutSignature . BlockHeader . Signature = bls . EmptySignature . Serialize ( ) blockWithoutSignatureRoot , err := ssz . HashTreeRoot ( blockWithoutSignature ) if err != nil { return err } proposal := ProposalSignedData { Slot : s . Slot , Shard : con . BeaconShardNumber , BlockHash : blockWithoutSignatureRoot , } proposalRoot , err := ssz . HashTreeRoot ( proposal ) if err != nil { return err } proposerPub , err := s . ValidatorRegistry [ proposerIndex ] . GetPublicKey ( ) if err != nil { return err } proposerSig , err := bls . DeserializeSignature ( block . BlockHeader . Signature ) if err != nil { return err } if verifySignature { verificationResult := make ( chan error ) go func ( ) { valid , err := bls . VerifySig ( proposerPub , proposalRoot [ : ] , proposerSig , bls . DomainProposal ) if err != nil { verificationResult <- err } if ! valid { verificationResult <- fmt . Errorf ( " " , proposerIndex ) } verificationResult <- nil } ( ) var slotBytes [ 8 ] byte binary . BigEndian . PutUint64 ( slotBytes [ : ] , block . BlockHeader . SlotNumber ) slotBytesHash := chainhash . HashH ( slotBytes [ : ] ) randaoSig , err := bls . DeserializeSignature ( block . BlockHeader . RandaoReveal ) if err != nil { return err } go func ( ) { valid , err := bls . VerifySig ( proposerPub , slotBytesHash [ : ] , randaoSig , bls . DomainRandao ) if err != nil { verificationResult <- err } if ! valid { verificationResult <- errors . New ( " " ) } verificationResult <- nil } ( ) result1 := <- verificationResult result2 := <- verificationResult if result1 != nil { return result1 } if result2 != nil { return result2 } } randaoRevealSerialized , err := ssz . HashTreeRoot ( block . BlockHeader . RandaoReveal ) if err != nil { return err } for i := range s . NextRandaoMix { s . NextRandaoMix [ i ] ^= randaoRevealSerialized [ i ] } if len ( block . BlockBody . ProposerSlashings ) > con . MaxProposerSlashings { return errors . New ( " " ) } if len ( block . BlockBody . CasperSlashings ) > con . MaxCasperSlashings { return errors . New ( " " ) } if len ( block . BlockBody . Attestations ) > con . MaxAttestations { return errors . New ( " " ) } if len ( block . BlockBody . Exits ) > con . MaxExits { return errors . New ( " " ) } if len ( block . BlockBody . Deposits ) > con . MaxDeposits { return errors . New ( " " ) } if len ( block . BlockBody . Votes ) > con . MaxVotes { return errors . New ( " " ) } for _ , slashing := range block . BlockBody . ProposerSlashings { err := s . applyProposerSlashing ( slashing , con ) if err != nil { return err } } for _ , c := range block . BlockBody . CasperSlashings { err := s . applyCasperSlashing ( c , con ) if err != nil { return err } } for _ , a := range block . BlockBody . Attestations { err := s . applyAttestation ( a , con , verifySignature , proposerIndex ) if err != nil { return err } } for _ , e := range block . BlockBody . Exits { err := s . ApplyExit ( e , con ) if err != nil { return err } } for _ , v := range block . BlockBody . Votes { err := s . applyVote ( v , con ) if err != nil { return err } } expectedStateRoot , err := view . GetLastStateRoot ( ) if err != nil { return err } if ! block . BlockHeader . StateRoot . IsEqual ( & expectedStateRoot ) { return fmt . Errorf ( " " , expectedStateRoot , block . BlockHeader . StateRoot ) } return nil }
ProcessBlock tries to apply a block to the state.
ProcessBlock tries to apply a block to the state .
// process block and randao verifications concurrently // process deposits here // Check state root.