Esempio n. 1
0
        protected virtual Transaction CreateOutputTransaction()
        {
            var blockReward = new Money(BlockTemplate.CoinbaseValue, MoneyUnit.Satoshi);

            rewardToPool = new Money(BlockTemplate.CoinbaseValue, MoneyUnit.Satoshi);

            var tx = new Transaction();

            // Distribute funds to configured reward recipients
            var rewardRecipients = new List <RewardRecipient>(poolConfig.RewardRecipients);

            foreach (var recipient in rewardRecipients.Where(x => x.Type != RewardRecipientType.Dev && x.Percentage > 0))
            {
                var recipientAddress = BitcoinUtils.AddressToScript(recipient.Address);
                var recipientReward  = new Money((long)Math.Floor(recipient.Percentage / 100.0m * blockReward.Satoshi));

                rewardToPool -= recipientReward;

                tx.AddOutput(recipientReward, recipientAddress);
            }

            // Finally distribute remaining funds to pool
            tx.Outputs.Insert(0, new TxOut(rewardToPool, poolAddressDestination)
            {
                Value = rewardToPool
            });

            // validate it
            //var checkResult = tx.Check();
            //Debug.Assert(checkResult == TransactionCheckResult.Success);

            return(tx);
        }
Esempio n. 2
0
        protected virtual Transaction CreateOutputTransaction()
        {
            var blockReward = new Money(BlockTemplate.CoinbaseValue, MoneyUnit.Satoshi);

            rewardToPool = new Money(BlockTemplate.CoinbaseValue, MoneyUnit.Satoshi);

            var tx = new Transaction();

            // Distribute funds to configured reward recipients
            var rewardRecipients = new List <RewardRecipient>(poolConfig.RewardRecipients);

            // Tiny donation to MiningCore developer(s)
            if (!clusterConfig.DisableDevDonation &&
                networkType == BitcoinNetworkType.Main &&
                KnownAddresses.DevFeeAddresses.ContainsKey(poolConfig.Coin.Type))
            {
                rewardRecipients.Add(new RewardRecipient
                {
                    Address    = KnownAddresses.DevFeeAddresses[poolConfig.Coin.Type],
                    Percentage = 0.2m
                });
            }

            foreach (var recipient in rewardRecipients.Where(x => x.Percentage > 0))
            {
                var recipientAddress = BitcoinUtils.AddressToScript(recipient.Address);
                var recipientReward  = new Money((long)Math.Floor(recipient.Percentage / 100.0m * blockReward.Satoshi));

                rewardToPool -= recipientReward;

                tx.AddOutput(recipientReward, recipientAddress);
            }

            // Finally distribute remaining funds to pool
            tx.Outputs.Insert(0, new TxOut(rewardToPool, poolAddressDestination)
            {
                Value = rewardToPool
            });

            // validate it
            //var checkResult = tx.Check();
            //Debug.Assert(checkResult == TransactionCheckResult.Success);

            return(tx);
        }
Esempio n. 3
0
        protected override async Task PostStartInitAsync()
        {
            var commands = new[]
            {
                new DaemonCmd(BitcoinCommands.ValidateAddress, new[] { poolConfig.Address }),
                new DaemonCmd(BitcoinCommands.GetDifficulty),
                new DaemonCmd(BitcoinCommands.SubmitBlock),
                new DaemonCmd(BitcoinCommands.GetBlockchainInfo)
            };

            var results = await daemon.ExecuteBatchAnyAsync(commands);

            if (results.Any(x => x.Error != null))
            {
                var resultList = results.ToList();
                var errors     = results.Where(x => x.Error != null && commands[resultList.IndexOf(x)].Method != BitcoinCommands.SubmitBlock)
                                 .ToArray();

                if (errors.Any())
                {
                    logger.ThrowLogPoolStartupException($"Init RPC failed: {string.Join(", ", errors.Select(y => y.Error.Message))}", LogCat);
                }
            }

            // extract results
            var validateAddressResponse = results[0].Response.ToObject <ValidateAddressResponse>();
            var difficultyResponse      = results[1].Response.ToObject <JToken>();
            var submitBlockResponse     = results[2];
            var blockchainInfoResponse  = results[3].Response.ToObject <BlockchainInfo>();

            // ensure pool owns wallet
            if (!validateAddressResponse.IsValid)
            {
                logger.ThrowLogPoolStartupException($"Daemon reports pool-address '{poolConfig.Address}' as invalid", LogCat);
            }

            if (!validateAddressResponse.IsMine)
            {
                logger.ThrowLogPoolStartupException($"Daemon does not own pool-address '{poolConfig.Address}'", LogCat);
            }

            isPoS = difficultyResponse.Values().Any(x => x.Path == "proof-of-stake");

            // Create pool address script from response
            if (isPoS)
            {
                poolAddressDestination = new PubKey(validateAddressResponse.PubKey);
            }
            else
            {
                poolAddressDestination = BitcoinUtils.AddressToScript(validateAddressResponse.Address);
            }

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

            ConfigureRewards();

            // update stats
            BlockchainStats.NetworkType = networkType.ToString();
            BlockchainStats.RewardType  = isPoS ? "POS" : "POW";

            // block submission RPC method
            if (submitBlockResponse.Error?.Message?.ToLower() == "method not found")
            {
                hasSubmitBlockMethod = false;
            }
            else if (submitBlockResponse.Error?.Code == -1)
            {
                hasSubmitBlockMethod = true;
            }
            else
            {
                logger.ThrowLogPoolStartupException($"Unable detect block submission RPC method", LogCat);
            }

            await UpdateNetworkStatsAsync();

            SetupCrypto();
            SetupJobUpdates();
        }
Esempio n. 4
0
 protected virtual IDestination AddressToDestination(string address)
 {
     return BitcoinUtils.AddressToDestination(address);
 }