public void IsValidGenesisStateFalseNotEnoughValidators() { // Arrange IServiceProvider testServiceProvider = TestSystem.BuildTestServiceProvider(useStore: true); MiscellaneousParameters miscellaneousParameters = testServiceProvider.GetService <IOptions <MiscellaneousParameters> >().Value; GweiValues gweiValues = testServiceProvider.GetService <IOptions <GweiValues> >().Value; BeaconNode.GenesisChainStart beaconChain = testServiceProvider.GetService <BeaconNode.GenesisChainStart>(); int depositCount = miscellaneousParameters.MinimumGenesisActiveValidatorCount - 1; IList <DepositData> deposits = TestDeposit.PrepareGenesisDeposits(testServiceProvider, depositCount, gweiValues.MaximumEffectiveBalance, signed: true); IDepositStore depositStore = testServiceProvider.GetService <IDepositStore>(); foreach (DepositData deposit in deposits) { depositStore.Place(deposit); } Bytes32 eth1BlockHash = new Bytes32(Enumerable.Repeat((byte)0x12, 32).ToArray()); ulong eth1Timestamp = miscellaneousParameters.MinimumGenesisTime; // Act BeaconState state = beaconChain.InitializeBeaconStateFromEth1(eth1BlockHash, eth1Timestamp); // Assert IsValidGenesisState(testServiceProvider, state, false); }
// Run ``process_deposit``, yielding: // - pre-state('pre') // - deposit('deposit') // - post-state('post'). //If ``valid == False``, run expecting ``AssertionError`` private void RunDepositProcessing(IServiceProvider testServiceProvider, BeaconState state, Deposit deposit, ValidatorIndex validatorIndex, bool expectValid, bool effective) { GweiValues gweiValues = testServiceProvider.GetService <IOptions <GweiValues> >().Value; BeaconStateTransition beaconStateTransition = testServiceProvider.GetService <BeaconStateTransition>(); int preValidatorCount = state.Validators.Count; Gwei preBalance = Gwei.Zero; if ((int)(ulong)validatorIndex < preValidatorCount) { preBalance = TestState.GetBalance(state, validatorIndex); } if (!expectValid) { Should.Throw <Exception>(() => { beaconStateTransition.ProcessDeposit(state, deposit); }); return; } beaconStateTransition.ProcessDeposit(state, deposit); if (!effective) { state.Validators.Count.ShouldBe(preValidatorCount); state.Balances.Count.ShouldBe(preValidatorCount); if ((int)(ulong)validatorIndex < preValidatorCount) { Gwei balance = TestState.GetBalance(state, validatorIndex); balance.ShouldBe(preBalance); } } else { if ((int)(ulong)validatorIndex < preValidatorCount) { // top up state.Validators.Count.ShouldBe(preValidatorCount); state.Balances.Count.ShouldBe(preValidatorCount); } else { // new validator state.Validators.Count.ShouldBe(preValidatorCount + 1); state.Balances.Count.ShouldBe(preValidatorCount + 1); } Gwei balance = TestState.GetBalance(state, validatorIndex); Gwei expectedBalance = preBalance + deposit.Data.Item.Amount; balance.ShouldBe(expectedBalance); Gwei expectedEffectiveBalance = Gwei.Min(gweiValues.MaximumEffectiveBalance, expectedBalance); expectedEffectiveBalance -= expectedEffectiveBalance % gweiValues.EffectiveBalanceIncrement; state.Validators[(int)(ulong)validatorIndex].EffectiveBalance.ShouldBe(expectedEffectiveBalance); } state.Eth1DepositIndex.ShouldBe(state.Eth1Data.DepositCount); }
public void TestInitializeBeaconStateFromEth1() { bool useBls = true; // Arrange IServiceProvider testServiceProvider = TestSystem.BuildTestServiceProvider(useBls, useStore: true); ChainConstants chainConstants = testServiceProvider.GetService <ChainConstants>(); TimeParameters timeParameters = testServiceProvider.GetService <IOptions <TimeParameters> >().Value; MiscellaneousParameters miscellaneousParameters = testServiceProvider.GetService <IOptions <MiscellaneousParameters> >().Value; GweiValues gweiValues = testServiceProvider.GetService <IOptions <GweiValues> >().Value; int depositCount = miscellaneousParameters.MinimumGenesisActiveValidatorCount; (IList <Deposit> deposits, Root depositRoot) = TestDeposit.PrepareGenesisDeposits(testServiceProvider, depositCount, gweiValues.MaximumEffectiveBalance, signed: useBls); Bytes32 eth1BlockHash = new Bytes32(Enumerable.Repeat((byte)0x12, 32).ToArray()); ulong eth1Timestamp = miscellaneousParameters.MinimumGenesisTime; BeaconNode.GenesisChainStart beaconChain = testServiceProvider.GetService <BeaconNode.GenesisChainStart>(); // Act //# initialize beacon_state BeaconState state = beaconChain.InitializeBeaconStateFromEth1(eth1BlockHash, eth1Timestamp, deposits); // Assert state.GenesisTime.ShouldBe(eth1Timestamp - eth1Timestamp % timeParameters.MinimumGenesisDelay + 2 * timeParameters.MinimumGenesisDelay); state.Validators.Count.ShouldBe(depositCount); state.Eth1Data.DepositRoot.ShouldBe(depositRoot); state.Eth1Data.DepositCount.ShouldBe((ulong)depositCount); state.Eth1Data.BlockHash.ShouldBe(eth1BlockHash); }
public BeaconState InitializeBeaconStateFromEth1(Bytes32 eth1BlockHash, ulong eth1Timestamp, IList <Deposit> deposits) { if (_logger.IsInfo()) { Log.InitializeBeaconState(_logger, eth1BlockHash, eth1Timestamp, deposits.Count, null); } InitialValues initialValues = _initialValueOptions.CurrentValue; GweiValues gweiValues = _gweiValueOptions.CurrentValue; TimeParameters timeParameters = _timeParameterOptions.CurrentValue; StateListLengths stateListLengths = _stateListLengthOptions.CurrentValue; Fork fork = new Fork(initialValues.GenesisForkVersion, initialValues.GenesisForkVersion, _chainConstants.GenesisEpoch); ulong genesisTime = eth1Timestamp - (eth1Timestamp % timeParameters.MinimumGenesisDelay) + (2 * timeParameters.MinimumGenesisDelay); Eth1Data eth1Data = new Eth1Data(Root.Zero, (ulong)deposits.Count, eth1BlockHash); Root emptyBlockBodyRoot = _cryptographyService.HashTreeRoot(BeaconBlockBody.Zero); BeaconBlockHeader latestBlockHeader = new BeaconBlockHeader(emptyBlockBodyRoot); Bytes32[] randaoMixes = Enumerable.Repeat(eth1BlockHash, (int)stateListLengths.EpochsPerHistoricalVector) .ToArray(); BeaconState state = new BeaconState(genesisTime, fork, eth1Data, latestBlockHeader, randaoMixes, timeParameters.SlotsPerHistoricalRoot, stateListLengths.EpochsPerHistoricalVector, stateListLengths.EpochsPerSlashingsVector, _chainConstants.JustificationBitsLength); // Process deposits List <DepositData> depositDataList = new List <DepositData>(); foreach (Deposit deposit in deposits) { depositDataList.Add(deposit.Data); Root depositRoot = _cryptographyService.HashTreeRoot(depositDataList); state.Eth1Data.SetDepositRoot(depositRoot); _beaconStateTransition.ProcessDeposit(state, deposit); } // Process activations for (int validatorIndex = 0; validatorIndex < state.Validators.Count; validatorIndex++) { Validator validator = state.Validators[validatorIndex]; Gwei balance = state.Balances[validatorIndex]; Gwei effectiveBalance = Gwei.Min(balance - (balance % gweiValues.EffectiveBalanceIncrement), gweiValues.MaximumEffectiveBalance); validator.SetEffectiveBalance(effectiveBalance); if (validator.EffectiveBalance == gweiValues.MaximumEffectiveBalance) { validator.SetEligible(_chainConstants.GenesisEpoch); validator.SetActive(_chainConstants.GenesisEpoch); } } return(state); }
public void IsValidGenesisStateTrueMoreBalance() { // Arrange IServiceProvider testServiceProvider = TestSystem.BuildTestServiceProvider(useStore: true); GweiValues gweiValues = testServiceProvider.GetService <IOptions <GweiValues> >().Value; // Act BeaconState state = CreateValidBeaconState(testServiceProvider); state.Validators[0].SetEffectiveBalance(gweiValues.MaximumEffectiveBalance + Gwei.One); // Assert IsValidGenesisState(testServiceProvider, state, true); }
public static BeaconState CreateValidBeaconState(IServiceProvider testServiceProvider, ulong?eth1TimestampOverride = null) { MiscellaneousParameters miscellaneousParameters = testServiceProvider.GetService <IOptions <MiscellaneousParameters> >().Value; GweiValues gweiValues = testServiceProvider.GetService <IOptions <GweiValues> >().Value; BeaconNode.GenesisChainStart beaconChain = testServiceProvider.GetService <BeaconNode.GenesisChainStart>(); int depositCount = miscellaneousParameters.MinimumGenesisActiveValidatorCount; (IList <Deposit> deposits, _) = TestDeposit.PrepareGenesisDeposits(testServiceProvider, depositCount, gweiValues.MaximumEffectiveBalance, signed: true); Bytes32 eth1BlockHash = new Bytes32(Enumerable.Repeat((byte)0x12, 32).ToArray()); ulong eth1Timestamp = eth1TimestampOverride ?? miscellaneousParameters.MinimumGenesisTime; BeaconState state = beaconChain.InitializeBeaconStateFromEth1(eth1BlockHash, eth1Timestamp, deposits); return(state); }
public void NewDepositUnderMax() { // Arrange IServiceProvider testServiceProvider = TestSystem.BuildTestServiceProvider(); BeaconState state = TestState.PrepareTestState(testServiceProvider); // fresh deposit = next validator index = validator appended to registry ValidatorIndex validatorIndex = new ValidatorIndex((ulong)state.Validators.Count); // effective balance will be 1 EFFECTIVE_BALANCE_INCREMENT smaller because of this small decrement. GweiValues gweiValues = testServiceProvider.GetService <IOptions <GweiValues> >().Value; Gwei amount = gweiValues.MaximumEffectiveBalance - new Gwei(1); Deposit deposit = TestDeposit.PrepareStateAndDeposit(testServiceProvider, state, validatorIndex, amount, Bytes32.Zero, signed: true); RunDepositProcessing(testServiceProvider, state, deposit, validatorIndex, expectValid: true, effective: true); }
public static BeaconState CreateGenesisState(IServiceProvider testServiceProvider, ulong numberOfValidators) { ChainConstants chainConstants = testServiceProvider.GetService <ChainConstants>(); GweiValues gweiValues = testServiceProvider.GetService <IOptions <GweiValues> >().Value; InitialValues initialValues = testServiceProvider.GetService <IOptions <InitialValues> >().Value; TimeParameters timeParameters = testServiceProvider.GetService <IOptions <TimeParameters> >().Value; StateListLengths stateListLengths = testServiceProvider.GetService <IOptions <StateListLengths> >().Value; ICryptographyService cryptographyService = testServiceProvider.GetService <ICryptographyService>(); var eth1BlockHash = new Bytes32(Enumerable.Repeat((byte)0x42, 32).ToArray()); var state = new BeaconState( 0, new Core2.Containers.Fork(new ForkVersion(new byte[ForkVersion.Length]), new ForkVersion(new byte[ForkVersion.Length]), Epoch.Zero), new Eth1Data(Root.Zero, numberOfValidators, eth1BlockHash), //numberOfValidators, new BeaconBlockHeader(cryptographyService.HashTreeRoot(BeaconBlockBody.Zero)), Enumerable.Repeat(eth1BlockHash, (int)stateListLengths.EpochsPerHistoricalVector).ToArray(), timeParameters.SlotsPerHistoricalRoot, stateListLengths.EpochsPerHistoricalVector, stateListLengths.EpochsPerSlashingsVector, chainConstants.JustificationBitsLength ); // We directly insert in the initial validators, // as it is much faster than creating and processing genesis deposits for every single test case. for (var index = (ulong)0; index < numberOfValidators; index++) { var validator = BuildMockValidator(chainConstants, initialValues, gweiValues, timeParameters, index, gweiValues.MaximumEffectiveBalance); state.AddValidatorWithBalance(validator, gweiValues.MaximumEffectiveBalance); state.IncreaseEth1DepositIndex(); } // Process genesis activations foreach (var validator in state.Validators) { if (validator.EffectiveBalance >= gweiValues.MaximumEffectiveBalance) { validator.SetEligible(chainConstants.GenesisEpoch); validator.SetActive(chainConstants.GenesisEpoch); } } return(state); }
public BeaconState InitializeBeaconStateFromEth1(Hash32 eth1BlockHash, ulong eth1Timestamp, IEnumerable <Deposit> deposits) { _logger.LogDebug(Event.InitializeBeaconState, "Initialise beacon state from ETH1 block {Eth1BlockHash}, time {Eth1Timestamp}, with {DepositCount} deposits.", eth1BlockHash, eth1Timestamp, deposits.Count()); GweiValues gweiValues = _gweiValueOptions.CurrentValue; InitialValues initialValues = _initialValueOptions.CurrentValue; TimeParameters timeParameters = _timeParameterOptions.CurrentValue; StateListLengths stateListLengths = _stateListLengthOptions.CurrentValue; ulong genesisTime = eth1Timestamp - (eth1Timestamp % _chainConstants.SecondsPerDay) + (2 * _chainConstants.SecondsPerDay); Eth1Data eth1Data = new Eth1Data((ulong)deposits.Count(), eth1BlockHash); BeaconBlockBody emptyBlockBody = new BeaconBlockBody(); BeaconBlockHeader latestBlockHeader = new BeaconBlockHeader(emptyBlockBody.HashTreeRoot(_miscellaneousParameterOptions.CurrentValue, _maxOperationsPerBlockOptions.CurrentValue)); BeaconState state = new BeaconState(genesisTime, 0, eth1Data, latestBlockHeader, timeParameters.SlotsPerHistoricalRoot, stateListLengths.EpochsPerHistoricalVector, stateListLengths.EpochsPerSlashingsVector, _chainConstants.JustificationBitsLength); // Process deposits var depositDataList = new List <DepositData>(); foreach (Deposit deposit in deposits) { depositDataList.Add(deposit.Data); Hash32 depositRoot = depositDataList.HashTreeRoot(_chainConstants.MaximumDepositContracts); state.Eth1Data.SetDepositRoot(depositRoot); _beaconStateTransition.ProcessDeposit(state, deposit); } // Process activations for (int validatorIndex = 0; validatorIndex < state.Validators.Count; validatorIndex++) { Validator validator = state.Validators[validatorIndex]; Gwei balance = state.Balances[validatorIndex]; Gwei effectiveBalance = Gwei.Min(balance - (balance % gweiValues.EffectiveBalanceIncrement), gweiValues.MaximumEffectiveBalance); validator.SetEffectiveBalance(effectiveBalance); if (validator.EffectiveBalance == gweiValues.MaximumEffectiveBalance) { validator.SetEligible(initialValues.GenesisEpoch); validator.SetActive(initialValues.GenesisEpoch); } } return(state); }
public void Ejection() { // Arrange IServiceProvider testServiceProvider = TestSystem.BuildTestServiceProvider(); BeaconState state = TestState.PrepareTestState(testServiceProvider); ChainConstants chainConstants = testServiceProvider.GetService <ChainConstants>(); GweiValues gweiValues = testServiceProvider.GetService <IOptions <GweiValues> >().Value; TimeParameters timeParameters = testServiceProvider.GetService <IOptions <TimeParameters> >().Value; BeaconChainUtility beaconChainUtility = testServiceProvider.GetService <BeaconChainUtility>(); BeaconStateAccessor beaconStateAccessor = testServiceProvider.GetService <BeaconStateAccessor>(); int index = 0; Epoch currentEpoch = beaconStateAccessor.GetCurrentEpoch(state); Validator validator = state.Validators[index]; bool isActive = beaconChainUtility.IsActiveValidator(validator, currentEpoch); isActive.ShouldBeTrue(); validator.ExitEpoch.ShouldBe(chainConstants.FarFutureEpoch); // Mock an ejection state.Validators[index].SetEffectiveBalance(gweiValues.EjectionBalance); for (ulong count = (ulong)0; count < (ulong)timeParameters.MaximumSeedLookahead + 1; count++) { TestState.NextEpoch(testServiceProvider, state); } // Act RunProcessRegistryUpdates(testServiceProvider, state); // Assert Epoch epochAfter = beaconStateAccessor.GetCurrentEpoch(state); Validator validatorAfter = state.Validators[index]; bool isActiveAfter = beaconChainUtility.IsActiveValidator(validatorAfter, epochAfter); isActiveAfter.ShouldBeFalse(); validatorAfter.ExitEpoch.ShouldNotBe(chainConstants.FarFutureEpoch); }
public void IsValidGenesisStateTrueOneMoreValidator() { // Arrange IServiceProvider testServiceProvider = TestSystem.BuildTestServiceProvider(useStore: true); MiscellaneousParameters miscellaneousParameters = testServiceProvider.GetService <IOptions <MiscellaneousParameters> >().Value; GweiValues gweiValues = testServiceProvider.GetService <IOptions <GweiValues> >().Value; BeaconNode.GenesisChainStart beaconChain = testServiceProvider.GetService <BeaconNode.GenesisChainStart>(); int depositCount = miscellaneousParameters.MinimumGenesisActiveValidatorCount + 1; (IList <Deposit> deposits, _) = TestDeposit.PrepareGenesisDeposits(testServiceProvider, depositCount, gweiValues.MaximumEffectiveBalance, signed: true); Bytes32 eth1BlockHash = new Bytes32(Enumerable.Repeat((byte)0x12, 32).ToArray()); ulong eth1Timestamp = miscellaneousParameters.MinimumGenesisTime; // Act BeaconState state = beaconChain.InitializeBeaconStateFromEth1(eth1BlockHash, eth1Timestamp, deposits); // Assert IsValidGenesisState(testServiceProvider, state, true); }
private void MockDeposit(IServiceProvider testServiceProvider, BeaconState state, int index) { ChainConstants chainConstants = testServiceProvider.GetService <ChainConstants>(); GweiValues gweiValues = testServiceProvider.GetService <IOptions <GweiValues> >().Value; BeaconChainUtility beaconChainUtility = testServiceProvider.GetService <BeaconChainUtility>(); BeaconStateAccessor beaconStateAccessor = testServiceProvider.GetService <BeaconStateAccessor>(); Validator validator = state.Validators[index]; Epoch currentEpoch = beaconStateAccessor.GetCurrentEpoch(state); bool isActive = beaconChainUtility.IsActiveValidator(validator, currentEpoch); isActive.ShouldBeTrue(); validator.SetEligible(chainConstants.FarFutureEpoch); validator.SetActive(chainConstants.FarFutureEpoch); validator.SetEffectiveBalance(gweiValues.MaximumEffectiveBalance); bool isActiveAfter = beaconChainUtility.IsActiveValidator(validator, currentEpoch); isActiveAfter.ShouldBeFalse(); }
public Task <Eth1GenesisData> GetEth1GenesisDataAsync(CancellationToken cancellationToken) { QuickStartParameters quickStartParameters = _quickStartParameterOptions.CurrentValue; if (_logger.IsWarn()) { Log.MockedQuickStart(_logger, quickStartParameters.GenesisTime, quickStartParameters.ValidatorCount, null); } GweiValues gweiValues = _gweiValueOptions.CurrentValue; InitialValues initialValues = _initialValueOptions.CurrentValue; TimeParameters timeParameters = _timeParameterOptions.CurrentValue; SignatureDomains signatureDomains = _signatureDomainOptions.CurrentValue; // Fixed amount Gwei amount = gweiValues.MaximumEffectiveBalance; // Build deposits List <DepositData> depositDataList = new List <DepositData>(); List <Deposit> deposits = new List <Deposit>(); for (ulong validatorIndex = 0uL; validatorIndex < quickStartParameters.ValidatorCount; validatorIndex++) { byte[] privateKey = GeneratePrivateKey(validatorIndex); // Public Key BLSParameters blsParameters = new BLSParameters() { PrivateKey = privateKey }; using BLS bls = BLS.Create(blsParameters); byte[] publicKeyBytes = new byte[BlsPublicKey.Length]; bls.TryExportBlsPublicKey(publicKeyBytes, out int publicKeyBytesWritten); BlsPublicKey publicKey = new BlsPublicKey(publicKeyBytes); // Withdrawal Credentials byte[] withdrawalCredentialBytes = _cryptographyService.Hash(publicKey.AsSpan()).AsSpan().ToArray(); withdrawalCredentialBytes[0] = initialValues.BlsWithdrawalPrefix; Bytes32 withdrawalCredentials = new Bytes32(withdrawalCredentialBytes); // Build deposit data DepositData depositData = new DepositData(publicKey, withdrawalCredentials, amount, BlsSignature.Zero); // Sign deposit data Domain domain = _beaconChainUtility.ComputeDomain(signatureDomains.Deposit); DepositMessage depositMessage = new DepositMessage(depositData.PublicKey, depositData.WithdrawalCredentials, depositData.Amount); Root depositMessageRoot = _cryptographyService.HashTreeRoot(depositMessage); Root depositDataSigningRoot = _beaconChainUtility.ComputeSigningRoot(depositMessageRoot, domain); byte[] destination = new byte[96]; bls.TrySignData(depositDataSigningRoot.AsSpan(), destination, out int bytesWritten); BlsSignature depositDataSignature = new BlsSignature(destination); depositData.SetSignature(depositDataSignature); // Deposit // TODO: This seems a very inefficient way (copied from tests) as it recalculates the merkle tree each time // (you only need to add one node) // TODO: Add some tests around quick start, then improve int index = depositDataList.Count; depositDataList.Add(depositData); //int depositDataLength = (ulong) 1 << _chainConstants.DepositContractTreeDepth; Root root = _cryptographyService.HashTreeRoot(depositDataList); IEnumerable <Bytes32> allLeaves = depositDataList.Select(x => new Bytes32(_cryptographyService.HashTreeRoot((DepositData)x).AsSpan())); IList <IList <Bytes32> > tree = CalculateMerkleTreeFromLeaves(allLeaves); IList <Bytes32> merkleProof = GetMerkleProof(tree, index, 32); List <Bytes32> proof = new List <Bytes32>(merkleProof); byte[] indexBytes = new byte[32]; BinaryPrimitives.WriteInt32LittleEndian(indexBytes, index + 1); Bytes32 indexHash = new Bytes32(indexBytes); proof.Add(indexHash); Bytes32 leaf = new Bytes32(_cryptographyService.HashTreeRoot(depositData).AsSpan()); _beaconChainUtility.IsValidMerkleBranch(leaf, proof, _chainConstants.DepositContractTreeDepth + 1, (ulong)index, root); Deposit deposit = new Deposit(proof, depositData); if (_logger.IsEnabled(LogLevel.Debug)) { LogDebug.QuickStartAddValidator(_logger, validatorIndex, publicKey.ToString().Substring(0, 12), null); } deposits.Add(deposit); } ulong eth1Timestamp = quickStartParameters.Eth1Timestamp; if (eth1Timestamp == 0) { eth1Timestamp = quickStartParameters.GenesisTime - (ulong)(1.5 * timeParameters.MinimumGenesisDelay); } else { ulong minimumEth1TimestampInclusive = quickStartParameters.GenesisTime - 2 * timeParameters.MinimumGenesisDelay; ulong maximumEth1TimestampInclusive = quickStartParameters.GenesisTime - timeParameters.MinimumGenesisDelay - 1; if (eth1Timestamp < minimumEth1TimestampInclusive) { if (_logger.IsEnabled(LogLevel.Warning)) { Log.QuickStartEth1TimestampTooLow(_logger, eth1Timestamp, quickStartParameters.GenesisTime, minimumEth1TimestampInclusive, null); } eth1Timestamp = minimumEth1TimestampInclusive; } else if (eth1Timestamp > maximumEth1TimestampInclusive) { if (_logger.IsEnabled(LogLevel.Warning)) { Log.QuickStartEth1TimestampTooHigh(_logger, eth1Timestamp, quickStartParameters.GenesisTime, maximumEth1TimestampInclusive, null); } eth1Timestamp = maximumEth1TimestampInclusive; } } var eth1GenesisData = new Eth1GenesisData(quickStartParameters.Eth1BlockHash, eth1Timestamp, deposits); if (_logger.IsEnabled(LogLevel.Debug)) { LogDebug.QuickStartGenesisDataCreated(_logger, eth1GenesisData.BlockHash, eth1GenesisData.Timestamp, eth1GenesisData.Deposits.Count, null); } return(Task.FromResult(eth1GenesisData)); }
public Task <Eth1GenesisData> GetEth1GenesisDataAsync(CancellationToken cancellationToken) { QuickStartParameters quickStartParameters = _quickStartParameterOptions.CurrentValue; if (_logger.IsWarn()) { Log.MockedQuickStart(_logger, quickStartParameters.GenesisTime, quickStartParameters.ValidatorCount, null); } GweiValues gweiValues = _gweiValueOptions.CurrentValue; TimeParameters timeParameters = _timeParameterOptions.CurrentValue; SignatureDomains signatureDomains = _signatureDomainOptions.CurrentValue; // Fixed amount Gwei amount = gweiValues.MaximumEffectiveBalance; for (ulong validatorIndex = 0uL; validatorIndex < quickStartParameters.ValidatorCount; validatorIndex++) { DepositData depositData = BuildAndSignDepositData( validatorIndex, amount, signatureDomains); _depositStore.Place(depositData); } ulong eth1Timestamp = quickStartParameters.Eth1Timestamp; if (eth1Timestamp == 0) { eth1Timestamp = quickStartParameters.GenesisTime - (ulong)(1.5 * timeParameters.MinimumGenesisDelay); } else { ulong minimumEth1TimestampInclusive = quickStartParameters.GenesisTime - 2 * timeParameters.MinimumGenesisDelay; ulong maximumEth1TimestampInclusive = quickStartParameters.GenesisTime - timeParameters.MinimumGenesisDelay - 1; if (eth1Timestamp < minimumEth1TimestampInclusive) { if (_logger.IsEnabled(LogLevel.Warning)) { Log.QuickStartEth1TimestampTooLow(_logger, eth1Timestamp, quickStartParameters.GenesisTime, minimumEth1TimestampInclusive, null); } eth1Timestamp = minimumEth1TimestampInclusive; } else if (eth1Timestamp > maximumEth1TimestampInclusive) { if (_logger.IsEnabled(LogLevel.Warning)) { Log.QuickStartEth1TimestampTooHigh(_logger, eth1Timestamp, quickStartParameters.GenesisTime, maximumEth1TimestampInclusive, null); } eth1Timestamp = maximumEth1TimestampInclusive; } } var eth1GenesisData = new Eth1GenesisData(quickStartParameters.Eth1BlockHash, eth1Timestamp); if (_logger.IsEnabled(LogLevel.Debug)) { LogDebug.QuickStartGenesisDataCreated(_logger, eth1GenesisData.BlockHash, eth1GenesisData.Timestamp, (uint)_depositStore.Deposits.Count, null); } return(Task.FromResult(eth1GenesisData)); }
public void QuickStartGenesis() { QuickStartParameters quickStartParameters = _quickStartParameterOptions.CurrentValue; _logger.LogWarning(0, "Mocked quick start with genesis time {GenesisTime:n0} and {ValidatorCount} validators.", quickStartParameters.GenesisTime, quickStartParameters.ValidatorCount); GweiValues gweiValues = _gweiValueOptions.CurrentValue; InitialValues initialValues = _initialValueOptions.CurrentValue; SignatureDomains signatureDomains = _signatureDomainOptions.CurrentValue; // Fixed amount Gwei amount = gweiValues.MaximumEffectiveBalance; // Build deposits var depositDataList = new List <DepositData>(); var deposits = new List <Deposit>(); for (ulong validatorIndex = 0uL; validatorIndex < quickStartParameters.ValidatorCount; validatorIndex++) { var privateKey = GeneratePrivateKey(validatorIndex); // Public Key BLSParameters blsParameters = new BLSParameters() { PrivateKey = privateKey }; using BLS bls = BLS.Create(blsParameters); var publicKeyBytes = new byte[BlsPublicKey.Length]; bls.TryExportBLSPublicKey(publicKeyBytes, out int publicKeyBytesWritten); BlsPublicKey publicKey = new BlsPublicKey(publicKeyBytes); // Withdrawal Credentials var withdrawalCredentialBytes = _cryptographyService.Hash(publicKey.AsSpan()).AsSpan().ToArray(); withdrawalCredentialBytes[0] = initialValues.BlsWithdrawalPrefix; Hash32 withdrawalCredentials = new Hash32(withdrawalCredentialBytes); // Build deposit data DepositData depositData = new DepositData(publicKey, withdrawalCredentials, amount); // Sign deposit data Hash32 depositDataSigningRoot = depositData.SigningRoot(); Domain domain = _beaconChainUtility.ComputeDomain(signatureDomains.Deposit); var destination = new byte[96]; bls.TrySignHash(depositDataSigningRoot.AsSpan(), destination, out int bytesWritten, domain.AsSpan()); BlsSignature depositDataSignature = new BlsSignature(destination); depositData.SetSignature(depositDataSignature); // Deposit // TODO: This seems a very inefficient way (copied from tests) as it recalculates the merkle tree each time // (you only need to add one node) // TODO: Add some tests around quick start, then improve int index = depositDataList.Count; depositDataList.Add(depositData); Hash32 root = depositDataList.HashTreeRoot((ulong)1 << _chainConstants.DepositContractTreeDepth); var allLeaves = depositDataList.Select(x => x.HashTreeRoot()); var tree = CalculateMerkleTreeFromLeaves(allLeaves); var merkleProof = GetMerkleProof(tree, index, 32); var proof = new List <Hash32>(merkleProof); var indexBytes = new Span <byte>(new byte[32]); BitConverter.TryWriteBytes(indexBytes, (ulong)index + 1); if (!BitConverter.IsLittleEndian) { indexBytes.Slice(0, 8).Reverse(); } Hash32 indexHash = new Hash32(indexBytes); proof.Add(indexHash); Hash32 leaf = depositData.HashTreeRoot(); _beaconChainUtility.IsValidMerkleBranch(leaf, proof, _chainConstants.DepositContractTreeDepth + 1, (ulong)index, root); Deposit deposit = new Deposit(proof, depositData); if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug("Quick start adding deposit for mocked validator {ValidatorIndex} with public key {PublicKey}.", validatorIndex, publicKey.ToString().Substring(0, 12)); } deposits.Add(deposit); } BeaconState genesisState = _beaconChain.InitializeBeaconStateFromEth1(quickStartParameters.Eth1BlockHash, quickStartParameters.Eth1Timestamp, deposits); // We use the state directly, and don't test IsValid genesisState.SetGenesisTime(quickStartParameters.GenesisTime); IStore store = _forkChoice.GetGenesisStore(genesisState); _logger.LogDebug("Quick start genesis store created with genesis time {GenesisTime:n0}.", store.GenesisTime); }
public static Validator BuildMockValidator(ChainConstants chainConstants, InitialValues initialValues, GweiValues gweiValues, TimeParameters timeParameters, ulong validatorIndex, Gwei balance) { var publicKeys = TestKeys.PublicKeys(timeParameters).ToArray(); var publicKey = publicKeys[validatorIndex]; // insecurely use pubkey as withdrawal key if no credentials provided var withdrawalCredentialBytes = TestSecurity.Hash(publicKey.AsSpan()); withdrawalCredentialBytes[0] = initialValues.BlsWithdrawalPrefix; var withdrawalCredentials = new Bytes32(withdrawalCredentialBytes); var validator = new Validator( publicKey, withdrawalCredentials, Gwei.Min(balance - balance % gweiValues.EffectiveBalanceIncrement, gweiValues.MaximumEffectiveBalance), false, chainConstants.FarFutureEpoch, chainConstants.FarFutureEpoch, chainConstants.FarFutureEpoch, chainConstants.FarFutureEpoch); return(validator); }
public void EffectiveBalanceHysteresis() { // Arrange IServiceProvider testServiceProvider = TestSystem.BuildTestServiceProvider(); BeaconState state = TestState.PrepareTestState(testServiceProvider); //# Prepare state up to the final-updates. //# Then overwrite the balances, we only want to focus to be on the hysteresis based changes. TestProcessUtility.RunEpochProcessingTo(testServiceProvider, state, TestProcessStep.ProcessFinalUpdates); GweiValues gweiValues = testServiceProvider.GetService <IOptions <GweiValues> >().Value; BeaconChainUtility beaconChainUtility = testServiceProvider.GetService <BeaconChainUtility>(); BeaconStateAccessor beaconStateAccessor = testServiceProvider.GetService <BeaconStateAccessor>(); BeaconStateTransition beaconStateTransition = testServiceProvider.GetService <BeaconStateTransition>(); // Set some edge cases for balances Gwei maximum = gweiValues.MaximumEffectiveBalance; Gwei minimum = gweiValues.EjectionBalance; Gwei increment = gweiValues.EffectiveBalanceIncrement; Gwei halfIncrement = increment / 2; EffectiveBalanceCase[] testCases = new[] { new EffectiveBalanceCase(maximum, maximum, maximum, "as-is"), new EffectiveBalanceCase(maximum, (Gwei)(maximum - 1), maximum - increment, "round down, step lower"), new EffectiveBalanceCase(maximum, (Gwei)(maximum + 1), maximum, "round down"), new EffectiveBalanceCase(maximum, (Gwei)(maximum - increment), maximum - increment, "exactly 1 step lower"), new EffectiveBalanceCase(maximum, (Gwei)(maximum - increment - 1), maximum - (increment * 2), "just 1 over 1 step lower"), new EffectiveBalanceCase(maximum, (Gwei)(maximum - increment + 1), maximum - increment, "close to 1 step lower"), new EffectiveBalanceCase(minimum, (Gwei)(minimum + (halfIncrement * 3)), minimum, "bigger balance, but not high enough"), new EffectiveBalanceCase(minimum, (Gwei)(minimum + (halfIncrement * 3) + 1), minimum + increment, "bigger balance, high enough, but small step"), new EffectiveBalanceCase(minimum, (Gwei)(minimum + (halfIncrement * 4) - 1), minimum + increment, "bigger balance, high enough, close to double step"), new EffectiveBalanceCase(minimum, (Gwei)(minimum + (halfIncrement * 4)), minimum + (increment * 2), "exact two step balance increment"), new EffectiveBalanceCase(minimum, (Gwei)(minimum + (halfIncrement * 4) + 1), minimum + (increment * 2), "over two steps, round down"), }; Epoch currentEpoch = beaconStateAccessor.GetCurrentEpoch(state); for (int index = 0; index < testCases.Length; index++) { Validator validator = state.Validators[index]; bool isActive = beaconChainUtility.IsActiveValidator(validator, currentEpoch); isActive.ShouldBeTrue(); EffectiveBalanceCase testCase = testCases[index]; validator.SetEffectiveBalance(testCase.PreEffective); ValidatorIndex validatorIndex = new ValidatorIndex((ulong)index); state.SetBalance(validatorIndex, testCase.Balance); } // Act beaconStateTransition.ProcessFinalUpdates(state); // Assert for (int index = 0; index < testCases.Length; index++) { EffectiveBalanceCase testCase = testCases[index]; Validator validator = state.Validators[index]; validator.EffectiveBalance.ShouldBe(testCase.PostEffective, testCase.Name); } }
private static void ValidateConfigShouldHaveValues(MiscellaneousParameters miscellaneousParameters, ForkChoiceConfiguration forkChoiceConfiguration, HonestValidatorConstants honestValidatorConstants, GweiValues gweiValues, InitialValues initialValues, TimeParameters timeParameters, StateListLengths stateListLengths, RewardsAndPenalties rewardsAndPenalties, MaxOperationsPerBlock maxOperationsPerBlock, SignatureDomains signatureDomains) { miscellaneousParameters.ChurnLimitQuotient.ShouldNotBe(0uL); miscellaneousParameters.MaximumCommitteesPerSlot.ShouldNotBe(0uL); miscellaneousParameters.MaximumValidatorsPerCommittee.ShouldNotBe(0uL); miscellaneousParameters.MinimumGenesisActiveValidatorCount.ShouldNotBe(0); miscellaneousParameters.MinimumGenesisTime.ShouldNotBe(0uL); miscellaneousParameters.MinimumPerEpochChurnLimit.ShouldNotBe(0uL); miscellaneousParameters.ShuffleRoundCount.ShouldNotBe(0); miscellaneousParameters.TargetCommitteeSize.ShouldNotBe(0uL); forkChoiceConfiguration.SafeSlotsToUpdateJustified.ShouldNotBe(Slot.Zero); honestValidatorConstants.EpochsPerRandomSubnetSubscription.ShouldNotBe(Epoch.Zero); honestValidatorConstants.Eth1FollowDistance.ShouldNotBe(0uL); honestValidatorConstants.RandomSubnetsPerValidator.ShouldNotBe(0uL); honestValidatorConstants.SecondsPerEth1Block.ShouldNotBe(0uL); honestValidatorConstants.TargetAggregatorsPerCommittee.ShouldNotBe(0uL); gweiValues.EffectiveBalanceIncrement.ShouldNotBe(Gwei.Zero); gweiValues.EjectionBalance.ShouldNotBe(Gwei.Zero); gweiValues.MaximumEffectiveBalance.ShouldNotBe(Gwei.Zero); // actually should be zero initialValues.BlsWithdrawalPrefix.ShouldBe((byte)0); initialValues.GenesisForkVersion.ShouldBe(new ForkVersion(new byte[] { 0x00, 0x00, 0x00, 0x01 })); timeParameters.MaximumSeedLookahead.ShouldNotBe(Epoch.Zero); timeParameters.MinimumAttestationInclusionDelay.ShouldNotBe(Slot.Zero); timeParameters.MinimumGenesisDelay.ShouldNotBe(0u); timeParameters.MinimumEpochsToInactivityPenalty.ShouldNotBe(Epoch.Zero); timeParameters.MinimumSeedLookahead.ShouldNotBe(Epoch.Zero); timeParameters.MinimumValidatorWithdrawabilityDelay.ShouldNotBe(Epoch.Zero); timeParameters.PersistentCommitteePeriod.ShouldNotBe(Epoch.Zero); timeParameters.SecondsPerSlot.ShouldNotBe(0U); timeParameters.SlotsPerEpoch.ShouldNotBe(0U); timeParameters.SlotsPerEth1VotingPeriod.ShouldNotBe(0U); timeParameters.SlotsPerHistoricalRoot.ShouldNotBe(0U); stateListLengths.EpochsPerHistoricalVector.ShouldNotBe(0U); stateListLengths.EpochsPerSlashingsVector.ShouldNotBe(0U); stateListLengths.HistoricalRootsLimit.ShouldNotBe(0uL); stateListLengths.ValidatorRegistryLimit.ShouldNotBe(0uL); rewardsAndPenalties.BaseRewardFactor.ShouldNotBe(0uL); rewardsAndPenalties.InactivityPenaltyQuotient.ShouldNotBe(0uL); rewardsAndPenalties.MinimumSlashingPenaltyQuotient.ShouldNotBe(0uL); rewardsAndPenalties.ProposerRewardQuotient.ShouldNotBe(0uL); rewardsAndPenalties.WhistleblowerRewardQuotient.ShouldNotBe(0uL); maxOperationsPerBlock.MaximumAttestations.ShouldNotBe(0uL); maxOperationsPerBlock.MaximumAttesterSlashings.ShouldNotBe(0uL); maxOperationsPerBlock.MaximumDeposits.ShouldNotBe(0uL); maxOperationsPerBlock.MaximumProposerSlashings.ShouldNotBe(0uL); maxOperationsPerBlock.MaximumVoluntaryExits.ShouldNotBe(0uL); // actually should be zero signatureDomains.BeaconProposer.ShouldBe(default);