public void QuickStartGenesis() { var quickStartParameters = _quickStartParameterOptions.CurrentValue; _logger.LogWarning(0, "Mocked quick start with genesis time {GenesisTime} and {ValidatorCount} validators.", quickStartParameters.GenesisTime, quickStartParameters.ValidatorCount); var miscellaneousParameters = _miscellaneousParameterOptions.CurrentValue; var gweiValues = _gweiValueOptions.CurrentValue; var initialValues = _initialValueOptions.CurrentValue; var timeParameters = _timeParameterOptions.CurrentValue; var stateListLengths = _stateListLengthOptions.CurrentValue; var maxOperationsPerBlock = _maxOperationsPerBlockOptions.CurrentValue; var signatureDomains = _signatureDomainOptions.CurrentValue; // Fixed amount var amount = gweiValues.MaximumEffectiveBalance; // Build deposits var depositDataList = new List <DepositData>(); var deposits = new List <Deposit>(); for (var validatorIndex = 0uL; validatorIndex < quickStartParameters.ValidatorCount; validatorIndex++) { var privateKey = GeneratePrivateKey(validatorIndex); // Public Key var blsParameters = new BLSParameters() { PrivateKey = privateKey }; using var bls = BLS.Create(blsParameters); var publicKeyBytes = new Span <byte>(new byte[BlsPublicKey.Length]); bls.TryExportBLSPublicKey(publicKeyBytes, out var publicKeybytesWritten); var publicKey = new BlsPublicKey(publicKeyBytes); // Withdrawal Credentials var withdrawalCredentialBytes = _cryptographyService.Hash(publicKey.AsSpan()).AsSpan().ToArray(); withdrawalCredentialBytes[0] = initialValues.BlsWithdrawalPrefix; var withdrawalCredentials = new Hash32(withdrawalCredentialBytes); // Build deposit data var depositData = new DepositData(publicKey, withdrawalCredentials, amount); // Sign deposit data var depositDataSigningRoot = depositData.SigningRoot(); var domain = _beaconChainUtility.ComputeDomain(signatureDomains.Deposit); var destination = new Span <byte>(new byte[96]); bls.TrySignHash(depositDataSigningRoot.AsSpan(), destination, out var bytesWritten, domain.AsSpan()); var 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 var index = depositDataList.Count; depositDataList.Add(depositData); var 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(); } var indexHash = new Hash32(indexBytes); proof.Add(indexHash); var leaf = depositData.HashTreeRoot(); _beaconChainUtility.IsValidMerkleBranch(leaf, proof, _chainConstants.DepositContractTreeDepth + 1, (ulong)index, root); var deposit = new Deposit(proof, depositData); _logger.LogDebug("Quick start adding deposit for mocked validator {ValidatorIndex} with public key {PublicKey}.", validatorIndex, publicKey); deposits.Add(deposit); } var genesisState = _beaconChain.InitializeBeaconStateFromEth1(quickStartParameters.Eth1BlockHash, quickStartParameters.Eth1Timestamp, deposits); // We use the state directly, and don't test IsValid genesisState.SetGenesisTime(quickStartParameters.GenesisTime); var store = _forkChoice.GetGenesisStore(genesisState); _logger.LogDebug("Quick start genesis store created with genesis time {GenesisTime}.", store.GenesisTime); }
public Root HashTreeRoot(DepositData depositData) { return(depositData.HashTreeRoot()); }