protected override void PostChainIdentifyConfigure()
        {
            ChainConfig = coin.GetNetwork(network.NetworkType);
            solver      = EquihashSolverFactory.GetSolver(ctx, ChainConfig.Solver);

            base.PostChainIdentifyConfigure();
        }
Esempio n. 2
0
        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
            };
        }