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

            base.PostChainIdentifyConfigure();
        }
示例#2
0
        public override async Task ConfigureAsync(ClusterConfig clusterConfig, PoolConfig poolConfig)
        {
            await base.ConfigureAsync(clusterConfig, poolConfig);

            poolExtraConfig = poolConfig.Extra.SafeExtensionDataAs <EquihashPoolConfigExtra>();

            // detect network
            var blockchainInfoResponse = await daemon.ExecuteCmdSingleAsync <BlockchainInfo>(logger, BitcoinCommands.GetBlockchainInfo);

            if (blockchainInfoResponse.Response.Chain.ToLower() == "test")
            {
                networkType = BitcoinNetworkType.Test;
            }
            else if (blockchainInfoResponse.Response.Chain.ToLower() == "regtest")
            {
                networkType = BitcoinNetworkType.RegTest;
            }
            else
            {
                networkType = BitcoinNetworkType.Main;
            }

            chainConfig = poolConfig.Template.As <EquihashCoinTemplate>().GetNetwork(networkType);

            // detect z_shieldcoinbase support
            var response = await daemon.ExecuteCmdSingleAsync <JObject>(logger, EquihashCommands.ZShieldCoinbase);

            supportsNativeShielding = response.Error.Code != (int)BitcoinRPCErrorCode.RPC_METHOD_NOT_FOUND;
        }
示例#3
0
        public override async Task ConfigureAsync(ClusterConfig clusterConfig, PoolConfig poolConfig, CancellationToken ct)
        {
            await base.ConfigureAsync(clusterConfig, poolConfig, ct);

            poolExtraConfig = poolConfig.Extra.SafeExtensionDataAs <EquihashPoolConfigExtra>();

            // detect network
            var blockchainInfoResponse = await rpcClient.ExecuteAsync <BlockchainInfo>(logger, BitcoinCommands.GetBlockchainInfo, ct);

            network = Network.GetNetwork(blockchainInfoResponse.Response.Chain.ToLower());

            chainConfig = poolConfig.Template.As <EquihashCoinTemplate>().GetNetwork(network.ChainName);

            // detect z_shieldcoinbase support
            var response = await rpcClient.ExecuteAsync <JObject>(logger, EquihashCommands.ZShieldCoinbase, ct);

            supportsNativeShielding = response.Error.Code != (int)BitcoinRPCErrorCode.RPC_METHOD_NOT_FOUND;
        }
示例#4
0
        public static string EncodeTarget(double difficulty, EquihashCoinTemplate.EquihashNetworkParams chainConfig)
        {
            string      result;
            var         diff     = BigInteger.ValueOf((long)(difficulty * 255d));
            var         quotient = chainConfig.Diff1Value.Divide(diff).Multiply(BigInteger.ValueOf(255));
            var         bytes    = quotient.ToByteArray().AsSpan();
            Span <byte> padded   = stackalloc byte[EquihashConstants.TargetPaddingLength];

            var padLength = EquihashConstants.TargetPaddingLength - bytes.Length;

            if (padLength > 0)
            {
                bytes.CopyTo(padded.Slice(padLength, bytes.Length));
                result = padded.ToHexString(0, EquihashConstants.TargetPaddingLength);
            }

            else
            {
                result = bytes.ToHexString(0, EquihashConstants.TargetPaddingLength);
            }

            return(result);
        }
示例#5
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
            };
        }