예제 #1
0
        /// <summary>
        /// Check if ``indexed_attestation`` has valid indices and signature.
        /// </summary>
        public bool IsValidIndexedAttestation(BeaconState state, IndexedAttestation indexedAttestation, Domain domain)
        {
            MiscellaneousParameters miscellaneousParameters = _miscellaneousParameterOptions.CurrentValue;
            IReadOnlyList<ValidatorIndex> attestingIndices = indexedAttestation.AttestingIndices;

            // Verify max number of indices
            if ((ulong) attestingIndices.Count > miscellaneousParameters.MaximumValidatorsPerCommittee)
            {
                if (_logger.IsWarn()) Log.InvalidIndexedAttestationTooMany(_logger, indexedAttestation.Data.Index, indexedAttestation.Data.Slot, attestingIndices.Count, miscellaneousParameters.MaximumValidatorsPerCommittee, null);
                return false;
            }

            // Verify indices are sorted
            if (attestingIndices.Count() > 1)
            {
                for (int index = 0; index < attestingIndices.Count() - 1; index++)
                {
                    if (!(attestingIndices[index] < attestingIndices[index + 1]))
                    {
                        if (_logger.IsWarn()) Log.InvalidIndexedAttestationNotSorted(_logger, indexedAttestation.Data.Index, indexedAttestation.Data.Slot, 0, index, null);
                        return false;
                    }
                }
            }

            // Verify aggregate signature
            IEnumerable<BlsPublicKey> publicKeys = attestingIndices.Select(x => state.Validators[(int) (ulong) x].PublicKey);
            BlsPublicKey aggregatePublicKey = _cryptographyService.BlsAggregatePublicKeys(publicKeys);
            Hash32 messageHash = _cryptographyService.HashTreeRoot(indexedAttestation.Data);
            BlsSignature signature = indexedAttestation.Signature;

            bool isValid = _cryptographyService.BlsVerify(aggregatePublicKey, messageHash, signature, domain);
            if (!isValid)
            {
                if (_logger.IsWarn()) Log.InvalidIndexedAttestationSignature(_logger, indexedAttestation.Data.Index, indexedAttestation.Data.Slot, null);
                return false;
            }

            return true;
        }
예제 #2
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}");
            }
        }