コード例 #1
0
        private int GetBlocksToMaturity(StakeTx stakeTx)
        {
            if (!(stakeTx.UtxoSet.IsCoinbase || stakeTx.UtxoSet.IsCoinstake))
            {
                return(0);
            }

            return(Math.Max(0, (int)this.network.Consensus.Option <PosConsensusOptions>().COINBASE_MATURITY + 1 - this.GetDepthInMainChain(stakeTx)));
        }
コード例 #2
0
        // Return depth of transaction in blockchain:
        // -1  : not in blockchain, and not in memory pool (conflicted transaction)
        //  0  : in memory pool, waiting to be included in a block
        // >=1 : this many blocks deep in the main chain
        private int GetDepthInMainChain(StakeTx stakeTx)
        {
            var chainedBlock = this.chain.GetBlock(stakeTx.HashBlock);

            if (chainedBlock == null)
            {
                return(-1);
            }

            // TODO: check if in memory pool then return 0

            return(this.chain.Tip.Height - chainedBlock.Height + 1);
        }
コード例 #3
0
        private bool SignSignature(StakeTx from, Transaction txTo, params Script[] knownRedeems)
        {
            try
            {
                new TransactionBuilder()
                .AddKeys(from.PrvKey)
                .AddKnownRedeems(knownRedeems)
                .AddCoins(new Coin(from.OutPoint, from.TxOut))
                .SignTransactionInPlace(txTo);
            }
            catch (Exception)
            {
                return(false);
            }

            return(true);
        }
コード例 #4
0
        public void GenerateBlocks(List <TrxStakingInfo> trxPairs)
        {
            this.LastCoinStakeSearchInterval = 0;

            if (this.chain.Tip != this.consensusLoop.Tip)
            {
                return;
            }

            BlockTemplate pblocktemplate = null;
            bool          tryToSync      = true;

            while (true)
            {
                while (!this.connection.ConnectedNodes.Any() || chainState.IsInitialBlockDownload)
                {
                    this.LastCoinStakeSearchInterval = 0;
                    tryToSync = true;
                    this.cancellationProvider.Cancellation.Token.WaitHandle.WaitOne(TimeSpan.FromMilliseconds(this.minerSleep));
                }

                if (tryToSync)
                {
                    tryToSync = false;
                    if (this.connection.ConnectedNodes.Count() < 3 ||
                        this.chain.Tip.Header.Time < dateTimeProvider.GetTime() - 10 * 60)
                    {
                        this.cancellationProvider.Cancellation.Token.WaitHandle.WaitOne(TimeSpan.FromMilliseconds(60000));
                        continue;
                    }
                }

                if (pblocktemplate == null)
                {
                    pblocktemplate = this.blockAssemblerFactory.Create(new AssemblerOptions()
                    {
                        IsProofOfStake = true
                    }).CreateNewBlock(new Script());
                }


                var pblock     = pblocktemplate.Block;
                var pindexPrev = this.chain.Tip;

                var stakeTxes = new List <StakeTx>();

                var coinset =
                    this.coinView.FetchCoinsAsync(trxPairs.Select(s => s.TransactionHash).ToArray()).GetAwaiter().GetResult();
                foreach (var sets in coinset.UnspentOutputs)
                {
                    int index = 0;
                    foreach (var outputx in sets._Outputs)
                    {
                        if (outputx != null && outputx.Value > Money.Zero)
                        {
                            var stakeTx = new StakeTx();

                            stakeTx.TxOut       = outputx;
                            stakeTx.OutPoint    = new OutPoint(sets.TransactionId, index);
                            stakeTx.PrvKey      = trxPairs.First(t => t.TransactionHash == sets.TransactionId).PrvKey;
                            stakeTx.OutputIndex = index;
                            stakeTx.HashBlock   = this.chain.GetBlock((int)sets.Height).HashBlock;
                            stakeTx.UtxoSet     = sets;

                            stakeTxes.Add(stakeTx);
                        }

                        index++;
                    }
                }

                // Trying to sign a block
                if (this.SignBlock(stakeTxes, pblock, pindexPrev, pblocktemplate.TotalFee))
                {
                    var blockResult = new BlockResult {
                        Block = pblock
                    };
                    this.CheckState(new ContextInformation(blockResult, network.Consensus), pindexPrev);

                    trxPairs.Add(new TrxStakingInfo
                    {
                        TransactionHash = pblock.Transactions[1].GetHash(),
                        PrvKey          = trxPairs.First().PrvKey
                    });

                    pblocktemplate = null;
                }
                else
                {
                    this.cancellationProvider.Cancellation.Token.WaitHandle.WaitOne(TimeSpan.FromMilliseconds(this.minerSleep));
                }
            }
        }
コード例 #5
0
        public void GenerateBlocks(WalletSecret walletSecret)
        {
            this.LastCoinStakeSearchInterval = 0;

            BlockTemplate pblocktemplate = null;
            bool          tryToSync      = true;

            while (true)
            {
                if (this.chain.Tip != this.consensusLoop.Tip)
                {
                    return;
                }

                while (!this.connection.ConnectedNodes.Any() || this.chainState.IsInitialBlockDownload)
                {
                    this.LastCoinStakeSearchInterval = 0;
                    tryToSync = true;
                    Task.Delay(TimeSpan.FromMilliseconds(this.minerSleep), this.nodeLifetime.ApplicationStopping).GetAwaiter().GetResult();
                }

                if (tryToSync)
                {
                    tryToSync = false;
                    if (this.connection.ConnectedNodes.Count() < 3 ||
                        this.chain.Tip.Header.Time < this.dateTimeProvider.GetTime() - 10 * 60)
                    {
                        //this.cancellationProvider.Cancellation.Token.WaitHandle.WaitOne(TimeSpan.FromMilliseconds(60000));
                        continue;
                    }
                }

                if (pblocktemplate == null)
                {
                    pblocktemplate = this.blockAssemblerFactory.Create(new AssemblerOptions()
                    {
                        IsProofOfStake = true
                    }).CreateNewBlock(new Script());
                }


                var pblock     = pblocktemplate.Block;
                var pindexPrev = this.consensusLoop.Tip;

                var stakeTxes = new List <StakeTx>();
                var spendable = this.wallet.GetSpendableTransactions(1);

                var coinset = this.coinView.FetchCoinsAsync(spendable.SelectMany(s => s.Transactions.Select(t => t.Id)).ToArray()).GetAwaiter().GetResult();

                foreach (var unspentInfo in spendable)
                {
                    foreach (var infoTransaction in unspentInfo.Transactions)
                    {
                        var set  = coinset.UnspentOutputs.FirstOrDefault(f => f?.TransactionId == infoTransaction.Id);
                        var utxo = set?._Outputs[infoTransaction.Index.Value];

                        if (utxo != null && utxo.Value > Money.Zero)
                        {
                            var stakeTx = new StakeTx();

                            stakeTx.TxOut       = utxo;
                            stakeTx.OutPoint    = new OutPoint(set.TransactionId, infoTransaction.Index.Value);
                            stakeTx.Address     = unspentInfo.Address;
                            stakeTx.OutputIndex = infoTransaction.Index.Value;
                            stakeTx.HashBlock   = this.chain.GetBlock((int)set.Height).HashBlock;
                            stakeTx.UtxoSet     = set;
                            stakeTx.Secret      = walletSecret;                        //temporary
                            stakeTxes.Add(stakeTx);
                        }
                    }
                }

                // Trying to sign a block
                if (this.SignBlock(stakeTxes, pblock, pindexPrev, pblocktemplate.TotalFee))
                {
                    var blockResult = new BlockResult {
                        Block = pblock
                    };
                    this.CheckState(new ContextInformation(blockResult, this.network.Consensus), pindexPrev);

                    pblocktemplate = null;
                }
                else
                {
                    Task.Delay(TimeSpan.FromMilliseconds(this.minerSleep), this.nodeLifetime.ApplicationStopping).GetAwaiter().GetResult();
                }
            }
        }