public Slot ComputeSlotsSinceEpochStart(Slot slot) { Epoch epoch = _beaconChainUtility.ComputeEpochAtSlot(slot); Slot startSlot = _beaconChainUtility.ComputeStartSlotOfEpoch(epoch); return(slot - startSlot); }
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); }
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}"); } }
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); }
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); }
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); }