github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/core/blocks/randao.go (about) 1 package blocks 2 3 import ( 4 "context" 5 6 "github.com/pkg/errors" 7 "github.com/prysmaticlabs/prysm/beacon-chain/core/helpers" 8 iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface" 9 "github.com/prysmaticlabs/prysm/proto/interfaces" 10 "github.com/prysmaticlabs/prysm/shared/hashutil" 11 "github.com/prysmaticlabs/prysm/shared/params" 12 ) 13 14 // ProcessRandao checks the block proposer's 15 // randao commitment and generates a new randao mix to update 16 // in the beacon state's latest randao mixes slice. 17 // 18 // Spec pseudocode definition: 19 // def process_randao(state: BeaconState, body: BeaconBlockBody) -> None: 20 // epoch = get_current_epoch(state) 21 // # Verify RANDAO reveal 22 // proposer = state.validators[get_beacon_proposer_index(state)] 23 // signing_root = compute_signing_root(epoch, get_domain(state, DOMAIN_RANDAO)) 24 // assert bls.Verify(proposer.pubkey, signing_root, body.randao_reveal) 25 // # Mix in RANDAO reveal 26 // mix = xor(get_randao_mix(state, epoch), hash(body.randao_reveal)) 27 // state.randao_mixes[epoch % EPOCHS_PER_HISTORICAL_VECTOR] = mix 28 func ProcessRandao( 29 _ context.Context, 30 beaconState iface.BeaconState, 31 b interfaces.SignedBeaconBlock, 32 ) (iface.BeaconState, error) { 33 if err := helpers.VerifyNilBeaconBlock(b); err != nil { 34 return nil, err 35 } 36 body := b.Block().Body() 37 buf, proposerPub, domain, err := randaoSigningData(beaconState) 38 if err != nil { 39 return nil, err 40 } 41 if err := verifySignature(buf, proposerPub, body.RandaoReveal(), domain); err != nil { 42 return nil, errors.Wrap(err, "could not verify block randao") 43 } 44 45 beaconState, err = ProcessRandaoNoVerify(beaconState, body.RandaoReveal()) 46 if err != nil { 47 return nil, errors.Wrap(err, "could not process randao") 48 } 49 return beaconState, nil 50 } 51 52 // ProcessRandaoNoVerify generates a new randao mix to update 53 // in the beacon state's latest randao mixes slice. 54 // 55 // Spec pseudocode definition: 56 // # Mix it in 57 // state.latest_randao_mixes[get_current_epoch(state) % LATEST_RANDAO_MIXES_LENGTH] = ( 58 // xor(get_randao_mix(state, get_current_epoch(state)), 59 // hash(body.randao_reveal)) 60 // ) 61 func ProcessRandaoNoVerify( 62 beaconState iface.BeaconState, 63 randaoReveal []byte, 64 ) (iface.BeaconState, error) { 65 currentEpoch := helpers.SlotToEpoch(beaconState.Slot()) 66 // If block randao passed verification, we XOR the state's latest randao mix with the block's 67 // randao and update the state's corresponding latest randao mix value. 68 latestMixesLength := params.BeaconConfig().EpochsPerHistoricalVector 69 latestMixSlice, err := beaconState.RandaoMixAtIndex(uint64(currentEpoch % latestMixesLength)) 70 if err != nil { 71 return nil, err 72 } 73 blockRandaoReveal := hashutil.Hash(randaoReveal) 74 if len(blockRandaoReveal) != len(latestMixSlice) { 75 return nil, errors.New("blockRandaoReveal length doesnt match latestMixSlice length") 76 } 77 for i, x := range blockRandaoReveal { 78 latestMixSlice[i] ^= x 79 } 80 if err := beaconState.UpdateRandaoMixesAtIndex(uint64(currentEpoch%latestMixesLength), latestMixSlice); err != nil { 81 return nil, err 82 } 83 return beaconState, nil 84 }