Esempio n. 1
0
        public Slot ComputeSlotsSinceEpochStart(Slot slot)
        {
            Epoch epoch     = _beaconChainUtility.ComputeEpochAtSlot(slot);
            Slot  startSlot = _beaconChainUtility.ComputeStartSlotOfEpoch(epoch);

            return(slot - startSlot);
        }
Esempio n. 2
0
        public static SignedBeaconBlock SignBlock(IServiceProvider testServiceProvider, BeaconState state, BeaconBlock block, ValidatorIndex?optionalProposerIndex)
        {
            TimeParameters   timeParameters   = testServiceProvider.GetService <IOptions <TimeParameters> >().Value;
            SignatureDomains signatureDomains = testServiceProvider.GetService <IOptions <SignatureDomains> >().Value;

            ICryptographyService  cryptographyService   = testServiceProvider.GetService <ICryptographyService>();
            IBeaconChainUtility   beaconChainUtility    = testServiceProvider.GetService <IBeaconChainUtility>();
            BeaconStateAccessor   beaconStateAccessor   = testServiceProvider.GetService <BeaconStateAccessor>();
            BeaconStateTransition beaconStateTransition = testServiceProvider.GetService <BeaconStateTransition>();

            if (state.Slot > block.Slot)
            {
                throw new ArgumentOutOfRangeException("block.Slot", block.Slot, $"Slot of block must be equal or less that state slot {state.Slot}");
            }

            Epoch          blockEpoch = beaconChainUtility.ComputeEpochAtSlot(block.Slot);
            ValidatorIndex proposerIndex;

            if (optionalProposerIndex.HasValue)
            {
                proposerIndex = optionalProposerIndex.Value;
            }
            else
            {
                if (block.Slot == state.Slot)
                {
                    proposerIndex = beaconStateAccessor.GetBeaconProposerIndex(state);
                }
                else
                {
                    Epoch stateEpoch = beaconChainUtility.ComputeEpochAtSlot(state.Slot);
                    if (stateEpoch + 1 > blockEpoch)
                    {
                        Console.WriteLine("WARNING: Block slot far away, and no proposer index manually given."
                                          + " Signing block is slow due to transition for proposer index calculation.");
                    }
                    // use stub state to get proposer index of future slot
                    BeaconState stubState = BeaconState.Clone(state);
                    beaconStateTransition.ProcessSlots(stubState, block.Slot);
                    proposerIndex = beaconStateAccessor.GetBeaconProposerIndex(stubState);
                }
            }

            byte[][] privateKeys = TestKeys.PrivateKeys(timeParameters).ToArray();
            byte[]   privateKey  = privateKeys[(int)(ulong)proposerIndex];

            Root         blockHashTreeRoot = cryptographyService.HashTreeRoot(block);
            Domain       proposerDomain    = beaconStateAccessor.GetDomain(state, signatureDomains.BeaconProposer, blockEpoch);
            Root         signingRoot       = beaconChainUtility.ComputeSigningRoot(blockHashTreeRoot, proposerDomain);
            BlsSignature signature         = TestSecurity.BlsSign(signingRoot, privateKey);

            return(new SignedBeaconBlock(block, signature));
        }
        /// <summary>
        /// Return the beacon committee at ``slot`` for ``index``.
        /// </summary>
        public IReadOnlyList <ValidatorIndex> GetBeaconCommittee(BeaconState state, Slot slot, CommitteeIndex index)
        {
            Epoch epoch             = _beaconChainUtility.ComputeEpochAtSlot(slot);
            ulong committeesPerSlot = GetCommitteeCountAtSlot(state, slot);

            IList <ValidatorIndex> indices = GetActiveValidatorIndices(state, epoch);
            Bytes32 seed           = GetSeed(state, epoch, _signatureDomainOptions.CurrentValue.BeaconAttester);
            ulong   committeeIndex = (slot % _timeParameterOptions.CurrentValue.SlotsPerEpoch) * committeesPerSlot + (ulong)index;
            ulong   committeeCount = committeesPerSlot * _timeParameterOptions.CurrentValue.SlotsPerEpoch;

            IReadOnlyList <ValidatorIndex> committee = _beaconChainUtility.ComputeCommittee(indices, seed, committeeIndex, committeeCount);

            return(committee);
        }
        public void GenesisEpochFullAttestationsNoRewards()
        {
            // Arrange
            IServiceProvider testServiceProvider = TestSystem.BuildTestServiceProvider();
            BeaconState      state = TestState.PrepareTestState(testServiceProvider);

            ChainConstants chainConstants = testServiceProvider.GetService <ChainConstants>();
            TimeParameters timeParameters = testServiceProvider.GetService <IOptions <TimeParameters> >().Value;

            IBeaconChainUtility beaconChainUtility = testServiceProvider.GetService <IBeaconChainUtility>();

            var attestations = new List <Attestation>();

            for (Slot slot = Slot.Zero; slot < timeParameters.SlotsPerEpoch - new Slot(1); slot += new Slot(1))
            {
                // create an attestation for each slot
                if (slot < timeParameters.SlotsPerEpoch)
                {
                    Attestation attestation = TestAttestation.GetValidAttestation(testServiceProvider, state, slot, CommitteeIndex.None, signed: true);
                    attestations.Add(attestation);
                }

                // fill each created slot in state after inclusion delay
                if (slot >= timeParameters.MinimumAttestationInclusionDelay)
                {
                    Slot        index = slot - timeParameters.MinimumAttestationInclusionDelay;
                    Attestation includeAttestation = attestations[(int)(ulong)index];
                    TestAttestation.AddAttestationsToState(testServiceProvider, state, new[] { includeAttestation }, state.Slot);
                }

                TestState.NextSlot(testServiceProvider, state);
            }

            // ensure has not cross the epoch boundary
            Epoch stateEpoch = beaconChainUtility.ComputeEpochAtSlot(state.Slot);

            stateEpoch.ShouldBe(chainConstants.GenesisEpoch);

            BeaconState preState = BeaconState.Clone(state);

            // Act
            RunProcessRewardsAndPenalties(testServiceProvider, state);

            // Assert
            for (int index = 0; index < preState.Validators.Count; index++)
            {
                state.Balances[index].ShouldBe(preState.Balances[index], $"Balance {index}");
            }
        }
        private static IList <Attestation> PrepareStateWithFullAttestations(IServiceProvider testServiceProvider, BeaconState state)
        {
            ChainConstants chainConstants = testServiceProvider.GetService <ChainConstants>();
            TimeParameters timeParameters = testServiceProvider.GetService <IOptions <TimeParameters> >().Value;

            IBeaconChainUtility beaconChainUtility = testServiceProvider.GetService <IBeaconChainUtility>();

            var   attestations = new List <Attestation>();
            ulong maxSlot      = timeParameters.SlotsPerEpoch + timeParameters.MinimumAttestationInclusionDelay;

            for (Slot slot = Slot.Zero; slot < maxSlot; slot += new Slot(1))
            {
                // create an attestation for each slot in epoch
                if (slot < timeParameters.SlotsPerEpoch)
                {
                    Attestation attestation = TestAttestation.GetValidAttestation(testServiceProvider, state, Slot.None, CommitteeIndex.None, signed: true);
                    attestations.Add(attestation);
                }

                // fill each created slot in state after inclusion delay
                if (slot >= timeParameters.MinimumAttestationInclusionDelay)
                {
                    Slot        index = slot - timeParameters.MinimumAttestationInclusionDelay;
                    Attestation includeAttestation = attestations[(int)(ulong)index];
                    TestAttestation.AddAttestationsToState(testServiceProvider, state, new[] { includeAttestation }, state.Slot);
                }

                TestState.NextSlot(testServiceProvider, state);
            }

            Epoch stateEpoch = beaconChainUtility.ComputeEpochAtSlot(state.Slot);

            stateEpoch.ShouldBe(chainConstants.GenesisEpoch + Epoch.One);

            state.PreviousEpochAttestations.Count.ShouldBe((int)timeParameters.SlotsPerEpoch);

            return(attestations);
        }
Esempio n. 6
0
        public async Task OnAttestationPastEpoch()
        {
            // Arrange
            IServiceProvider testServiceProvider = TestSystem.BuildTestServiceProvider(useStore: true);
            BeaconState      state = TestState.PrepareTestState(testServiceProvider);

            ChainConstants chainConstants = testServiceProvider.GetService <ChainConstants>();
            InitialValues  initialValues  = testServiceProvider.GetService <IOptions <InitialValues> >().Value;
            TimeParameters timeParameters = testServiceProvider.GetService <IOptions <TimeParameters> >().Value;
            IForkChoice    forkChoice     = testServiceProvider.GetService <IForkChoice>();

            // Initialization
            IStore store = testServiceProvider.GetService <IStore>();
            await forkChoice.InitializeForkChoiceStoreAsync(store, state);

            // move time forward 2 epochs
            ulong time = store.Time + 2 * timeParameters.SecondsPerSlot * (ulong)timeParameters.SlotsPerEpoch;
            await forkChoice.OnTickAsync(store, time);

            // create and store block from 3 epochs ago
            BeaconBlock       block       = TestBlock.BuildEmptyBlockForNextSlot(testServiceProvider, state, BlsSignature.Zero);
            SignedBeaconBlock signedBlock = TestState.StateTransitionAndSignBlock(testServiceProvider, state, block);
            await forkChoice.OnBlockAsync(store, signedBlock);

            // create attestation for past block
            Attestation attestation = TestAttestation.GetValidAttestation(testServiceProvider, state, state.Slot, CommitteeIndex.None, signed: true);

            attestation.Data.Target.Epoch.ShouldBe(chainConstants.GenesisEpoch);

            IBeaconChainUtility beaconChainUtility = testServiceProvider.GetService <IBeaconChainUtility>();
            Slot  currentSlot  = ((ForkChoice)forkChoice).GetCurrentSlot(store);
            Epoch currentEpoch = beaconChainUtility.ComputeEpochAtSlot(currentSlot);

            currentEpoch.ShouldBe((Epoch)(chainConstants.GenesisEpoch + 2UL));

            await RunOnAttestation(testServiceProvider, state, store, attestation, expectValid : false);
        }
        public void GenesisEpochNoAttestationsNoPenalties()
        {
            // Arrange
            IServiceProvider testServiceProvider = TestSystem.BuildTestServiceProvider();
            BeaconState      state = TestState.PrepareTestState(testServiceProvider);

            ChainConstants      chainConstants     = testServiceProvider.GetService <ChainConstants>();
            IBeaconChainUtility beaconChainUtility = testServiceProvider.GetService <IBeaconChainUtility>();

            BeaconState preState = BeaconState.Clone(state);

            Epoch stateEpoch = beaconChainUtility.ComputeEpochAtSlot(state.Slot);

            stateEpoch.ShouldBe(chainConstants.GenesisEpoch);

            // Act
            RunProcessRewardsAndPenalties(testServiceProvider, state);

            // Assert
            for (int index = 0; index < preState.Validators.Count; index++)
            {
                state.Balances[index].ShouldBe(preState.Balances[index], $"Balance {index}");
            }
        }
Esempio n. 8
0
        private BlsSignature GetEpochSignature(IServiceProvider testServiceProvider, byte[] privateKey, ForkVersion forkVersion, Slot slot)
        {
            SignatureDomains    signatureDomains   = testServiceProvider.GetService <IOptions <SignatureDomains> >().Value;
            IBeaconChainUtility beaconChainUtility = testServiceProvider.GetService <IBeaconChainUtility>();
            var domain = beaconChainUtility.ComputeDomain(signatureDomains.Randao, forkVersion);

            var epoch = beaconChainUtility.ComputeEpochAtSlot(slot);

            var epochRoot        = epoch.HashTreeRoot();
            var epochSigningRoot = beaconChainUtility.ComputeSigningRoot(epochRoot, domain);

            BLSParameters parameters = new BLSParameters()
            {
                PrivateKey = privateKey
            };
            BLS bls         = BLS.Create(parameters);
            var destination = new Span <byte>(new byte[96]);

            bls.TrySignData(epochSigningRoot.AsSpan(), destination, out var bytesWritten);

            var signature = new BlsSignature(destination.ToArray());

            return(signature);
        }
Esempio n. 9
0
        public static BeaconBlock BuildEmptyBlock(IServiceProvider testServiceProvider, BeaconState state, Slot slot, BlsSignature randaoReveal)
        {
            //if (slot) is none

            TimeParameters   timeParameters   = testServiceProvider.GetService <IOptions <TimeParameters> >().Value;
            SignatureDomains signatureDomains = testServiceProvider.GetService <IOptions <SignatureDomains> >().Value;

            ICryptographyService  cryptographyService   = testServiceProvider.GetService <ICryptographyService>();
            IBeaconChainUtility   beaconChainUtility    = testServiceProvider.GetService <IBeaconChainUtility>();
            BeaconStateAccessor   beaconStateAccessor   = testServiceProvider.GetService <BeaconStateAccessor>();
            BeaconStateTransition beaconStateTransition = testServiceProvider.GetService <BeaconStateTransition>();

            Eth1Data eth1Data = new Eth1Data(Root.Zero, state.Eth1DepositIndex, Bytes32.Zero);

            Root stateRoot = !state.LatestBlockHeader.StateRoot.Equals(Root.Zero)
                ? state.LatestBlockHeader.StateRoot
                : cryptographyService.HashTreeRoot(state);
            BeaconBlockHeader previousBlockHeader = new BeaconBlockHeader(state.LatestBlockHeader.Slot,
                                                                          state.LatestBlockHeader.ParentRoot, stateRoot, state.LatestBlockHeader.BodyRoot);
            Root previousBlockHashTreeRoot = cryptographyService.HashTreeRoot(previousBlockHeader);

            if (randaoReveal.Equals(BlsSignature.Zero))
            {
                Epoch          blockEpoch = beaconChainUtility.ComputeEpochAtSlot(slot);
                ValidatorIndex proposerIndex;
                if (slot == state.Slot)
                {
                    proposerIndex = beaconStateAccessor.GetBeaconProposerIndex(state);
                }
                else
                {
                    Epoch stateEpoch = beaconChainUtility.ComputeEpochAtSlot(state.Slot);
                    if (blockEpoch > stateEpoch + 1)
                    {
                        Console.WriteLine("WARNING: Block slot (epoch {0}) far away from state (epoch {1}), and no proposer index manually given."
                                          + " Signing block is slow due to transition for proposer index calculation.", blockEpoch, stateEpoch);
                    }

                    // use stub state to get proposer index of future slot
                    BeaconState stubState = BeaconState.Clone(state);
                    beaconStateTransition.ProcessSlots(stubState, slot);
                    proposerIndex = beaconStateAccessor.GetBeaconProposerIndex(stubState);
                }

                byte[][] privateKeys = TestKeys.PrivateKeys(timeParameters).ToArray();
                byte[]   privateKey  = privateKeys[(int)(ulong)proposerIndex];

                Domain randaoDomain      = beaconStateAccessor.GetDomain(state, signatureDomains.Randao, blockEpoch);
                Root   epochHashTreeRoot = cryptographyService.HashTreeRoot(blockEpoch);
                Root   randaoSigningRoot = beaconChainUtility.ComputeSigningRoot(epochHashTreeRoot, randaoDomain);
                randaoReveal = TestSecurity.BlsSign(randaoSigningRoot, privateKey);
            }

            BeaconBlock emptyBlock = new BeaconBlock(slot,
                                                     previousBlockHashTreeRoot,
                                                     Root.Zero,
                                                     new BeaconBlockBody(
                                                         randaoReveal,
                                                         eth1Data,
                                                         new Bytes32(),
                                                         Array.Empty <ProposerSlashing>(),
                                                         Array.Empty <AttesterSlashing>(),
                                                         Array.Empty <Attestation>(),
                                                         Array.Empty <Deposit>(),
                                                         Array.Empty <SignedVoluntaryExit>()
                                                         ));

            return(emptyBlock);
        }
        private async Task <bool> IsValidPeerStatus(string peerId, PeeringStatus peerPeeringStatus, Root headRoot,
                                                    BeaconState beaconState)
        {
            // Check head epoch expected fork version
            Epoch       peerEpoch = _beaconChainUtility.ComputeEpochAtSlot(peerPeeringStatus.HeadSlot);
            ForkVersion expectedForkVersionAtPeerEpoch;

            if (peerEpoch < beaconState.Fork.Epoch)
            {
                expectedForkVersionAtPeerEpoch = beaconState.Fork.PreviousVersion;
            }
            else
            {
                expectedForkVersionAtPeerEpoch = beaconState.Fork.CurrentVersion;
            }

            if (!peerPeeringStatus.HeadForkVersion.Equals(expectedForkVersionAtPeerEpoch))
            {
                if (_logger.IsWarn())
                {
                    Log.PeerStatusInvalidForkVersion(_logger, peerId, peerPeeringStatus.HeadForkVersion,
                                                     peerPeeringStatus.HeadSlot,
                                                     peerEpoch, expectedForkVersionAtPeerEpoch, null);
                }
                return(false);
            }

            // Check finalized checkpoint in chain at expected epoch; only if finalized checkpoint is shared (i.e. also finalized for us)
            if (peerPeeringStatus.FinalizedEpoch <= beaconState.FinalizedCheckpoint.Epoch)
            {
                // If the (finalized_root, finalized_epoch) shared by the peer is not in the client's chain at the expected epoch.
                // For example, if Peer 1 sends (root, epoch) of (A, 5) and Peer 2 sends (B, 3) but Peer 1 has root C at epoch 3,
                // then Peer 1 would disconnect because it knows that their chains are irreparably disjoint.

                Root expectedFinalizedRoot;
                if (peerPeeringStatus.FinalizedEpoch == Epoch.Zero)
                {
                    // The genesis checkpoint (epoch 0) has root zero.
                    expectedFinalizedRoot = Root.Zero;
                }
                else
                {
                    // Otherwise get the ancestor at the start slot of the peer's finalized epoch
                    Slot peerFinalizedSlot =
                        _beaconChainUtility.ComputeStartSlotOfEpoch(peerPeeringStatus.FinalizedEpoch);
                    expectedFinalizedRoot = await _forkChoice
                                            .GetAncestorAsync(_store, headRoot, peerFinalizedSlot)
                                            .ConfigureAwait(false);
                }

                if (!peerPeeringStatus.FinalizedRoot.Equals(expectedFinalizedRoot))
                {
                    if (_logger.IsWarn())
                    {
                        Log.PeerStatusInvalidFinalizedCheckpoint(_logger, peerId, peerPeeringStatus.FinalizedRoot,
                                                                 peerPeeringStatus.FinalizedEpoch, expectedFinalizedRoot, null);
                    }
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 11
0
        private static AttestationData BuildAttestationData(IServiceProvider testServiceProvider, BeaconState state, Slot slot, CommitteeIndex index)
        {
            IBeaconChainUtility beaconChainUtility  = testServiceProvider.GetService <IBeaconChainUtility>();
            BeaconStateAccessor beaconStateAccessor = testServiceProvider.GetService <BeaconStateAccessor>();

            if (state.Slot > slot)
            {
                throw new ArgumentOutOfRangeException(nameof(slot), slot, $"Slot cannot be greater than state slot {state.Slot}.");
            }

            Root blockRoot;

            if (slot == state.Slot)
            {
                BeaconBlock nextBlock = TestBlock.BuildEmptyBlockForNextSlot(testServiceProvider, state, BlsSignature.Zero);
                blockRoot = nextBlock.ParentRoot;
            }
            else
            {
                blockRoot = beaconStateAccessor.GetBlockRootAtSlot(state, slot);
            }

            Root  epochBoundaryRoot;
            Epoch currentEpoch          = beaconStateAccessor.GetCurrentEpoch(state);
            Slot  currentEpochStartSlot = beaconChainUtility.ComputeStartSlotOfEpoch(currentEpoch);

            if (slot < currentEpochStartSlot)
            {
                Epoch previousEpoch = beaconStateAccessor.GetPreviousEpoch(state);
                epochBoundaryRoot = beaconStateAccessor.GetBlockRoot(state, previousEpoch);
            }
            else if (slot == currentEpochStartSlot)
            {
                epochBoundaryRoot = blockRoot;
            }
            else
            {
                epochBoundaryRoot = beaconStateAccessor.GetBlockRoot(state, currentEpoch);
            }

            Epoch sourceEpoch;
            Root  sourceRoot;

            if (slot < currentEpochStartSlot)
            {
                sourceEpoch = state.PreviousJustifiedCheckpoint.Epoch;
                sourceRoot  = state.PreviousJustifiedCheckpoint.Root;
            }
            else
            {
                sourceEpoch = state.CurrentJustifiedCheckpoint.Epoch;
                sourceRoot  = state.CurrentJustifiedCheckpoint.Root;
            }

            //Crosslink parentCrosslink;
            //if (epochOfSlot == currentEpoch)
            //{
            //    parentCrosslink = state.CurrentCrosslinks[(int)(ulong)shard];
            //}
            //else
            //{
            //    throw new NotImplementedException();
            //}

            Epoch           slotEpoch       = beaconChainUtility.ComputeEpochAtSlot(slot);
            AttestationData attestationData = new AttestationData(
                slot,
                index,
                blockRoot,
                new Checkpoint(sourceEpoch, sourceRoot),
                new Checkpoint(slotEpoch, epochBoundaryRoot));

            return(attestationData);
        }