protected override void PostChainIdentifyConfigure() { ChainConfig = coin.GetNetwork(network.NetworkType); solver = EquihashSolverFactory.GetSolver(ctx, ChainConfig.Solver); base.PostChainIdentifyConfigure(); }
public virtual void Init(EquihashBlockTemplate blockTemplate, string jobId, PoolConfig poolConfig, ClusterConfig clusterConfig, IMasterClock clock, IDestination poolAddressDestination, Network network, EquihashSolver solver) { Contract.RequiresNonNull(blockTemplate, nameof(blockTemplate)); Contract.RequiresNonNull(poolConfig, nameof(poolConfig)); Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig)); Contract.RequiresNonNull(clock, nameof(clock)); Contract.RequiresNonNull(poolAddressDestination, nameof(poolAddressDestination)); Contract.RequiresNonNull(solver, nameof(solver)); Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(jobId), $"{nameof(jobId)} must not be empty"); this.clock = clock; this.poolAddressDestination = poolAddressDestination; coin = poolConfig.Template.As <EquihashCoinTemplate>(); networkParams = coin.GetNetwork(network.NetworkType); this.network = network; BlockTemplate = blockTemplate; JobId = jobId; Difficulty = (double)new BigRational(networkParams.Diff1BValue, BlockTemplate.Target.HexToReverseByteArray().AsSpan().ToBigInteger()); // ZCash Sapling & Overwinter support isSaplingActive = networkParams.SaplingActivationHeight.HasValue && networkParams.SaplingTxVersion.HasValue && networkParams.SaplingTxVersionGroupId.HasValue && networkParams.SaplingActivationHeight.Value > 0 && blockTemplate.Height >= networkParams.SaplingActivationHeight.Value; isOverwinterActive = isSaplingActive || networkParams.OverwinterTxVersion.HasValue && networkParams.OverwinterTxVersionGroupId.HasValue && networkParams.OverwinterActivationHeight.HasValue && networkParams.OverwinterActivationHeight.Value > 0 && blockTemplate.Height >= networkParams.OverwinterActivationHeight.Value; if (isSaplingActive) { txVersion = networkParams.SaplingTxVersion.Value; txVersionGroupId = networkParams.SaplingTxVersionGroupId.Value; } else if (isOverwinterActive) { txVersion = networkParams.OverwinterTxVersion.Value; txVersionGroupId = networkParams.OverwinterTxVersionGroupId.Value; } // Misc this.solver = solver; if (!string.IsNullOrEmpty(BlockTemplate.Target)) { blockTargetValue = new uint256(BlockTemplate.Target); } else { var tmp = new Target(BlockTemplate.Bits.HexToByteArray()); blockTargetValue = tmp.ToUInt256(); } previousBlockHashReversedHex = BlockTemplate.PreviousBlockhash .HexToByteArray() .ReverseInPlace() .ToHexString(); if (blockTemplate.Subsidy != null) { blockReward = blockTemplate.Subsidy.Miner * BitcoinConstants.SatoshisPerBitcoin; } else { blockReward = BlockTemplate.CoinbaseValue; } if (networkParams?.vFundingStreams == true) { decimal fundingstreamTotal = 0; fundingstreamTotal = blockTemplate.Subsidy.FundingStreams.Sum(x => x.Value); blockReward = (blockTemplate.Subsidy.Miner + fundingstreamTotal) * BitcoinConstants.SatoshisPerBitcoin; } else if (networkParams?.PayFoundersReward == true) { var founders = blockTemplate.Subsidy.Founders ?? blockTemplate.Subsidy.Community; if (!founders.HasValue) { throw new Exception("Error, founders reward missing for block template"); } blockReward = (blockTemplate.Subsidy.Miner + founders.Value) * BitcoinConstants.SatoshisPerBitcoin; } rewardFees = blockTemplate.Transactions.Sum(x => x.Fee); BuildCoinbase(); // build tx hashes var txHashes = new List <uint256> { new uint256(coinbaseInitialHash) }; txHashes.AddRange(BlockTemplate.Transactions.Select(tx => new uint256(tx.Hash.HexToReverseByteArray()))); // build merkle root merkleRoot = MerkleNode.GetRoot(txHashes).Hash.ToBytes().ReverseInPlace(); merkleRootReversed = merkleRoot.ReverseInPlace(); merkleRootReversedHex = merkleRootReversed.ToHexString(); // misc var hashReserved = isSaplingActive && !string.IsNullOrEmpty(blockTemplate.FinalSaplingRootHash) ? blockTemplate.FinalSaplingRootHash.HexToReverseByteArray().ToHexString() : sha256Empty.ToHexString(); var solutionIn = !string.IsNullOrEmpty(blockTemplate.Solution) ? blockTemplate.Solution.HexToByteArray().ToHexString() : null; jobParams = new object[] { JobId, BlockTemplate.Version.ReverseByteOrder().ToStringHex8(), previousBlockHashReversedHex, merkleRootReversedHex, hashReserved, BlockTemplate.CurTime.ReverseByteOrder().ToStringHex8(), BlockTemplate.Bits.HexToReverseByteArray().ToHexString(), false, solutionIn }; }