Example #1
0
        public virtual void Init(ExchangeCoinGetWork work, string jobId,
                                 PoolConfig poolConfig, ClusterConfig clusterConfig, IMasterClock clock,
                                 IDestination poolAddressDestination, BitcoinNetworkType networkType,
                                 double shareMultiplier, decimal blockrewardMultiplier, IHashAlgorithm headerHasher)
        {
            Contract.RequiresNonNull(work, nameof(work));
            Contract.RequiresNonNull(poolConfig, nameof(poolConfig));
            Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig));
            Contract.RequiresNonNull(clock, nameof(clock));
            Contract.RequiresNonNull(poolAddressDestination, nameof(poolAddressDestination));
            Contract.RequiresNonNull(headerHasher, nameof(headerHasher));
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(jobId), $"{nameof(jobId)} must not be empty");

            this.clock = clock;

            if (ExchangeCoinConstants.Chains.TryGetValue(poolConfig.Coin.Type, out var chain))
            {
                chain.TryGetValue(networkType, out chainConfig);
            }

            Work        = work;
            BlockHeader = new ExchangeCoinBlockHeader(work.Data);
            JobId       = jobId;

            this.shareMultiplier = shareMultiplier;
            this.headerHasher    = headerHasher;
            this.equihash        = chainConfig.Solver();

            blockTarget = new Target(BlockHeader.Bits);

            Difficulty = chainConfig.Diff1.Divide(blockTarget.ToBigInteger()).LongValue;

            BuildCoinbase();

            jobParams = new object[]
            {
                JobId,
                BlockHeader.PrevBlock.ToHexString(),
                coinbaseInitialHex,
                coinbaseFinalHex,
                "",
                BlockHeader.Version.ToStringHex8().HexToByteArray().ReverseArray().ToHexString(),
                BlockHeader.Bits.ReverseByteOrder().ToStringHex8(),
                BlockHeader.Timestamp.ReverseByteOrder().ToStringHex8(),
                false
            };
        }
Example #2
0
        public override void Init(ZCashBlockTemplate blockTemplate, string jobId,
                                  PoolConfig poolConfig, ClusterConfig clusterConfig, IMasterClock clock,
                                  IDestination poolAddressDestination, BitcoinNetworkType networkType,
                                  bool isPoS, double shareMultiplier, decimal?blockrewardMultiplier,
                                  IHashAlgorithm coinbaseHasher, IHashAlgorithm headerHasher, IHashAlgorithm blockHasher)
        {
            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(coinbaseHasher, nameof(coinbaseHasher));
            Contract.RequiresNonNull(headerHasher, nameof(headerHasher));
            Contract.RequiresNonNull(blockHasher, nameof(blockHasher));
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(jobId), $"{nameof(jobId)} must not be empty");

            this.poolConfig             = poolConfig;
            this.clusterConfig          = clusterConfig;
            this.clock                  = clock;
            this.poolAddressDestination = poolAddressDestination;
            this.networkType            = networkType;

            if (ZCashConstants.Chains.TryGetValue(poolConfig.Coin.Type, out var chain))
            {
                chain.TryGetValue(networkType, out chainConfig);
            }

            BlockTemplate  = blockTemplate;
            JobId          = jobId;
            Difficulty     = (double)new BigRational(chainConfig.Diff1b, BlockTemplate.Target.HexToByteArray().ReverseArray().AsSpan().ToBigInteger());
            txExpiryHeight = blockTemplate.Height + 100;

            // ZCash Sapling & Overwinter support
            isSaplingActive = chainConfig.SaplingActivationHeight.HasValue &&
                              chainConfig.SaplingTxVersion.HasValue &&
                              chainConfig.SaplingTxVersionGroupId.HasValue &&
                              chainConfig.SaplingActivationHeight.Value > 0 &&
                              blockTemplate.Height >= chainConfig.SaplingActivationHeight.Value;

            isOverwinterActive = isSaplingActive ||
                                 chainConfig.OverwinterTxVersion.HasValue &&
                                 chainConfig.OverwinterTxVersionGroupId.HasValue &&
                                 chainConfig.OverwinterActivationHeight.HasValue &&
                                 chainConfig.OverwinterActivationHeight.Value > 0 &&
                                 blockTemplate.Height >= chainConfig.OverwinterActivationHeight.Value;

            if (isSaplingActive)
            {
                txVersion        = chainConfig.SaplingTxVersion.Value;
                txVersionGroupId = chainConfig.SaplingTxVersionGroupId.Value;
            }

            else if (isOverwinterActive)
            {
                txVersion        = chainConfig.OverwinterTxVersion.Value;
                txVersionGroupId = chainConfig.OverwinterTxVersionGroupId.Value;
            }

            // Misc
            this.isPoS           = isPoS;
            this.shareMultiplier = shareMultiplier;

            this.headerHasher = headerHasher;
            this.blockHasher  = blockHasher;
            this.equihash     = chainConfig.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()
                                           .ReverseArray()
                                           .ToHexString();

            blockReward = blockTemplate.Subsidy.Miner * BitcoinConstants.SatoshisPerBitcoin;

            if (chainConfig?.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.HexToByteArray().ReverseArray())));

            // build merkle root
            merkleRoot            = MerkleNode.GetRoot(txHashes).Hash.ToBytes().ReverseArray();
            merkleRootReversed    = merkleRoot.ReverseArray();
            merkleRootReversedHex = merkleRootReversed.ToHexString();

            // misc
            var hashReserved = isSaplingActive && !string.IsNullOrEmpty(blockTemplate.FinalSaplingRootHash) ? blockTemplate.FinalSaplingRootHash.HexToByteArray().ReverseArray().ToHexString() : sha256Empty.ToHexString();

            jobParams = new object[]
            {
                JobId,
                BlockTemplate.Version.ReverseByteOrder().ToStringHex8(),
                previousBlockHashReversedHex,
                merkleRootReversedHex,
                hashReserved,
                BlockTemplate.CurTime.ReverseByteOrder().ToStringHex8(),
                BlockTemplate.Bits.HexToByteArray().ReverseArray().ToHexString(),
                false
            };
        }