예제 #1
0
        public void ProcessBlockHeader(BeaconState state, BeaconBlock block)
        {
            _logger.LogInformation(Event.ProcessBlock, "Process block header for block {BeaconBlock}", block);
            // Verify that the slots match
            if (block.Slot != state.Slot)
            {
                throw new ArgumentOutOfRangeException("block.Slot", block.Slot, $"Block slot must match state slot {state.Slot}.");
            }
            // Verify that the parent matches
            var latestBlockSigningRoot = state.LatestBlockHeader.SigningRoot();

            if (block.ParentRoot != latestBlockSigningRoot)
            {
                throw new ArgumentOutOfRangeException("block.ParentRoot", block.ParentRoot, $"Block parent root must match latest block header root {latestBlockSigningRoot}.");
            }

            // Save current block as the new latest block
            var bodyRoot       = block.Body.HashTreeRoot(_miscellaneousParameterOptions.CurrentValue, _maxOperationsPerBlockOptions.CurrentValue);
            var newBlockHeader = new BeaconBlockHeader(block.Slot,
                                                       block.ParentRoot,
                                                       Hash32.Zero,       // `state_root` is zeroed and overwritten in the next `process_slot` call
                                                       bodyRoot,
                                                       new BlsSignature() //`signature` is zeroed
                                                       );

            state.SetLatestBlockHeader(newBlockHeader);

            // Verify proposer is not slashed
            var beaconProposerIndex = _beaconStateAccessor.GetBeaconProposerIndex(state);
            var proposer            = state.Validators[(int)(ulong)beaconProposerIndex];

            if (proposer.IsSlashed)
            {
                throw new Exception("Beacon proposer must not be slashed.");
            }

            // Verify proposer signature
            var signingRoot    = block.SigningRoot(_miscellaneousParameterOptions.CurrentValue, _maxOperationsPerBlockOptions.CurrentValue);
            var domain         = _beaconStateAccessor.GetDomain(state, _signatureDomainOptions.CurrentValue.BeaconProposer, Epoch.None);
            var validSignature = _cryptographyService.BlsVerify(proposer.PublicKey, signingRoot, block.Signature, domain);

            if (!validSignature)
            {
                throw new Exception($"Block signature must match proposer public key {proposer.PublicKey}");
            }
        }