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 }