コード例 #1
0
        private decimal CheckForLowerThreshold(decimal stakeSplitThreshold)
        {
            Log.Debug("Call of method: decimal ProcessWallet.CheckForLowerThreshold(decimal stakeSplitThreshold).");
            Log.Verbose("Parameter stakeSplitThreshold: {stakeSplitThreshold}.", stakeSplitThreshold);
            //If every staking input is not older than StakePatient/2 days lower the thereshold
            List <ListUnspentResponse> stakeInputs = AccessWallet.ListUnspent(0, int.MaxValue, new List <string> {
                Settings.Stake.DedicatedStakingAddress
            });

            if (stakeInputs.Count <= 0)
            {
                return(stakeSplitThreshold);
            }

            decimal             newStakeSplitThreshold = stakeSplitThreshold;
            ListUnspentResponse oldestInput            = stakeInputs.OrderByDescending(s => s.Confirmations).First();
            double waitDays = Settings.Stake.StakingPatience / 2D;

            DateTime blockdate = TransactionHelper.BaseDate.AddSeconds(AccessWallet.GetTransaction(oldestInput.TxId).BlockTime);

            if (blockdate > DateTime.UtcNow.AddDays(-waitDays))
            {
                newStakeSplitThreshold = oldestInput.Amount >= stakeSplitThreshold?Math.Ceiling(oldestInput.Amount * 0.8M) : Math.Ceiling(oldestInput.Amount);
            }

            decimal ret = Math.Min(stakeSplitThreshold, newStakeSplitThreshold);

            Log.Verbose("Returnvalue of ProcessWallet.CheckForLowerThreshold(decimal stakeSplitThreshold): {ret}.", ret);
            return(ret);
        }
コード例 #2
0
        private decimal CheckForHigherThreshold(decimal stakeSplitThreshold)
        {
            Log.Debug("Call of method: decimal ProcessWallet.CheckForHigherThreshold(decimal stakeSplitThreshold).");
            Log.Verbose("Parameter stakeSplitThreshold: {stakeSplitThreshold}.", stakeSplitThreshold);
            decimal newStakeSplitThreshold = stakeSplitThreshold;

            List <ListUnspentResponse> stakeInputs = AccessWallet.ListUnspent(0, int.MaxValue, new List <string> {
                Settings.Stake.DedicatedStakingAddress
            });

            if (stakeInputs.Count <= 0)
            {
                return(newStakeSplitThreshold);
            }

            List <ListUnspentResponse> oldestInputs = stakeInputs.OrderByDescending(s => s.Confirmations)
                                                      .Where(s => TransactionHelper.BaseDate.AddSeconds(AccessWallet.GetTransaction(s.TxId).BlockTime) <
                                                             DateTime.UtcNow.AddDays(-Settings.Stake.StakingPatience))
                                                      .ToList();

            if (oldestInputs.Count > 0)
            {
                newStakeSplitThreshold = oldestInputs.Max(i => i.Amount);
                newStakeSplitThreshold = Math.Floor(newStakeSplitThreshold);
                if (newStakeSplitThreshold <= stakeSplitThreshold)
                {
                    newStakeSplitThreshold = oldestInputs.Max(i => i.Amount) * 1.2M;
                    newStakeSplitThreshold = Math.Ceiling(newStakeSplitThreshold);
                }
                newStakeSplitThreshold = Math.Max(newStakeSplitThreshold, stakeSplitThreshold);
            }

            Log.Verbose("Returnvalue of ProcessWallet.CheckForHigherThreshold(decimal stakeSplitThreshold): {newStakeSplitThreshold}.", newStakeSplitThreshold);
            return(newStakeSplitThreshold);
        }
コード例 #3
0
        private void CreateNewInputs(decimal stakeSplitThreshold)
        {
            Log.Debug("Call of method: void ProcessWallet.CreateNewInputs(decimal stakeSplitThreshold).");
            Log.Verbose("Parameter stakeSplitThreshold: {stakeSplitThreshold}.", stakeSplitThreshold);
            if (!Settings.Stake.EditStakes)
            {
                Log.Information("Edit stakes deactivated. No new stake input will be created.");
                return;
            }

            ListUnspentResponse addressInput = AccessWallet.ListUnspent(1, int.MaxValue, new List <string> {
                Settings.Stake.DedicatedCollectingAddress
            })
                                               .OrderByDescending(i => i.Amount)
                                               .FirstOrDefault();

            if (!(addressInput?.Amount >= stakeSplitThreshold))
            {
                Log.Information("No need to create a new stake input.");
                return;
            }

            Log.Information("Create a new stake input.");
            var inputs  = new List <CreateRawTransactionInput>();
            var outputs = new Dictionary <string, decimal>();

            inputs.Add(new CreateRawTransactionInput {
                TxId = addressInput.TxId, Vout = addressInput.Vout
            });
            outputs.Add(Settings.Stake.DedicatedStakingAddress, addressInput.Amount);
            Send(inputs, outputs);
        }
コード例 #4
0
        private List <string> ProcessInputs([NotNull] List <string> addresses, int minimunNeededInputs, decimal amountLock = decimal.MaxValue, [CanBeNull] string targetAddress = null)
        {
            Log.Debug("Call of method: List<string> ProcessWallet.ProcessInputs(List<string> addresses, int minimunNeededInputs).");
            Log.Verbose("Parameter addresses: {@addresses}.", addresses);
            Log.Verbose("Parameter minimunNeededInputs: {minimunNeededInputs}.", minimunNeededInputs);
            Log.Verbose("Parameter amount: {amountLock}.", amountLock);
            Log.Verbose("Parameter amount: {targetAddress}.", targetAddress);

            if (string.IsNullOrWhiteSpace(targetAddress))
            {
                targetAddress = Settings.Stake.DedicatedCollectingAddress;
            }

            if (addresses.Count == 0 || string.IsNullOrWhiteSpace(targetAddress))
            {
                var erg = new List <string>();
                Log.Verbose("Returnvalue of ProcessWallet.ProcessInputs(List<string> addresses, int minimunNeededInputs): {@ret}.", erg);
                return(erg);
            }

            var transactionList = new List <string>();
            int maxInputs       = TransactionHelper.GetMaxPossibleInputCountForFreeTransaction(1);

            Log.Verbose("Allowed inputs: {maxInputs}.", maxInputs);

            List <ListUnspentResponse> transactions = AccessWallet.ListUnspent(1, int.MaxValue, addresses);

            Log.Verbose("Transactions: {@transactions}.", transactions);
            transactions = transactions.Where(t => t.Amount > 0M && t.Amount <= amountLock).ToList();

            var tCount  = 0;
            var inputs  = new List <CreateRawTransactionInput>();
            var outputs = new Dictionary <string, decimal>();
            var amount  = 0M;

            if (transactions.Count >= minimunNeededInputs)
            {
                string plural = transactions.Count > 1 ? "s" : string.Empty;
                Log.Information($"Merge {transactions.Count} input{plural} to {targetAddress}.");
                foreach (ListUnspentResponse trans in transactions)
                {
                    Log.Debug($"Include Transaction: {trans.TxId}.");
                    inputs.Add(new CreateRawTransactionInput {
                        TxId = trans.TxId, Vout = trans.Vout
                    });
                    amount += trans.Amount;
                    ++tCount;

                    if (tCount < maxInputs)
                    {
                        continue;
                    }

                    Log.Information($"Move {amount} coins to {targetAddress} without fee.");
                    outputs.Add(targetAddress, amount);
                    transactionList.Add(Send(inputs, outputs));
                    tCount  = 0;
                    inputs  = new List <CreateRawTransactionInput>();
                    outputs = new Dictionary <string, decimal>();
                    amount  = 0M;
                }
            }

            if (tCount > 0)
            {
                Log.Information($"Move {amount} coins to {targetAddress} without fee.");
                outputs.Add(targetAddress, amount);
                transactionList.Add(Send(inputs, outputs));
            }


            List <string> ret = transactionList.Where(t => !string.IsNullOrWhiteSpace(t)).ToList();

            Log.Verbose("Returnvalue of ProcessWallet.ProcessInputs(List<string> addresses, int minimunNeededInputs): {@ret}.", ret);
            return(ret);
        }
コード例 #5
0
        private void ManageLowInputs(decimal stakeSplitThreshold)
        {
            Log.Debug("Call of method: void ProcessWallet.ManageLowInputs(decimal stakeSplitThreshold).");
            Log.Verbose("Parameter stakeSplitThreshold: {stakeSplitThreshold}.", stakeSplitThreshold);
            if (!Settings.Stake.EditStakes)
            {
                Log.Information("Edit stakes deactivated. No stake input will be altered.");
                return;
            }

            var found     = true;
            int maxInputs = TransactionHelper.GetMaxPossibleInputCountForFreeTransaction(2);

            Log.Verbose("Allowed inputs: {maxInputs}.", maxInputs);
            int maxOutputs = TransactionHelper.GetMaxPossibleOutputCountForFreeTransaction(2);

            Log.Verbose("Allowed outputs: {maxInputs}.", maxOutputs);

            if (maxInputs < 2 || maxOutputs < 2)
            {
                Log.Warning("Unable to create a zero fee transaction.");
                //Impossible to make zero fee transaction.
                return;
            }

            while (found)
            {
                found = false;

                ListUnspentResponse addressInput = AccessWallet.ListUnspent(1, int.MaxValue, new List <string> {
                    Settings.Stake.DedicatedCollectingAddress
                })
                                                   .OrderByDescending(i => i.Amount)
                                                   .FirstOrDefault();
                if (!(addressInput?.Amount > 0))
                {
                    continue;
                }

                List <ListUnspentResponse> lowInputs = AccessWallet.ListUnspent(1, int.MaxValue, new List <string> {
                    Settings.Stake.DedicatedStakingAddress
                });
                //Low confirmations first. This will prevent the threshold update logic to be confused and this are the inputs that stake less.
                ListUnspentResponse lowInput = lowInputs.OrderBy(i => i.Confirmations).FirstOrDefault(i => i.Amount < stakeSplitThreshold);
                if (lowInput == null)
                {
                    Log.Information("No need to alter a stake input.");
                    continue;
                }

                Log.Information("Alter a stake input to match stake split threshold.");
                decimal mergedAmount = lowInput.Amount + addressInput.Amount;
                var     inputs       = new List <CreateRawTransactionInput>();
                var     outputs      = new Dictionary <string, decimal>();
                inputs.Add(new CreateRawTransactionInput {
                    TxId = addressInput.TxId, Vout = addressInput.Vout
                });
                inputs.Add(new CreateRawTransactionInput {
                    TxId = lowInput.TxId, Vout = lowInput.Vout
                });
                if (mergedAmount > stakeSplitThreshold)
                {
                    outputs.Add(Settings.Stake.DedicatedStakingAddress, stakeSplitThreshold);
                    outputs.Add(Settings.Stake.DedicatedCollectingAddress, mergedAmount - stakeSplitThreshold);
                }
                else
                {
                    outputs.Add(Settings.Stake.DedicatedStakingAddress, mergedAmount);
                }

                string transaction = Send(inputs, outputs);
                found = true;
                WaitTillAllConfirmed(new List <string> {
                    transaction
                });
            }
        }