public ConsensusStats(CoinViewStack stack, CoinView coinView, ConsensusLoop consensusLoop, ChainBehavior.ChainState chainState, ConcurrentChain chain, IConnectionManager connectionManager)
        {
            stack        = new CoinViewStack(coinView);
            this.cache   = stack.Find <CachedCoinView>();
            this.dbreeze = stack.Find <DBreezeCoinView>();
            this.bottom  = stack.Bottom;

            this.consensusLoop   = consensusLoop;
            this.lookaheadPuller = this.consensusLoop.Puller as LookaheadBlockPuller;

            this.lastSnapshot      = consensusLoop.Validator.PerformanceCounter.Snapshot();
            this.lastSnapshot2     = this.dbreeze?.PerformanceCounter.Snapshot();
            this.lastSnapshot3     = this.cache?.PerformanceCounter.Snapshot();
            this.chainState        = chainState;
            this.chain             = chain;
            this.connectionManager = connectionManager;
        }
Esempio n. 2
0
        // ppcoin: total coin age spent in transaction, in the unit of coin-days.
        // Only those coins meeting minimum age requirement counts. As those
        // transactions not in main chain are not currently indexed so we
        // might not find out about their coin age. Older transactions are
        // guaranteed to be in main chain by sync-checkpoint. This rule is
        // introduced to help nodes establish a consistent view of the coin
        // age (trust score) of competing branches.
        public bool GetCoinAge(ConcurrentChain chain, CachedCoinView cachedCoinView,
                               Transaction trx, ChainedBlock pindexPrev, out ulong nCoinAge)
        {
            BigInteger bnCentSecond = BigInteger.Zero;              // coin age in the unit of cent-seconds

            nCoinAge = 0;

            if (trx.IsCoinBase)
            {
                return(true);
            }

            foreach (var txin in trx.Inputs)
            {
                var coins = cachedCoinView.FetchCoinsAsync(new[] { txin.PrevOut.Hash }).GetAwaiter().GetResult();
                if (coins == null || coins.UnspentOutputs.Length != 1)
                {
                    continue;
                }

                var prevBlock = chain.GetBlock(coins.BlockHash);
                var prevUtxo  = coins.UnspentOutputs[0];

                // First try finding the previous transaction in database
                //Transaction txPrev = trasnactionStore.Get(txin.PrevOut.Hash);
                //if (txPrev == null)
                //	continue;  // previous transaction not in main chain
                if (trx.Time < prevUtxo.Time)
                {
                    return(false);                     // Transaction timestamp violation
                }
                if (IsProtocolV3((int)trx.Time))
                {
                    if (IsConfirmedInNPrevBlocks(prevUtxo, pindexPrev, this.consensusOptions.StakeMinConfirmations - 1))
                    {
                        //LogPrint("coinage", "coin age skip nSpendDepth=%d\n", nSpendDepth + 1);
                        continue;                         // only count coins meeting min confirmations requirement
                    }
                }
                else
                {
                    // Read block header
                    //var block = blockStore.GetBlock(txPrev.GetHash());
                    //if (block == null)
                    //	return false; // unable to read block of previous transaction
                    if (prevBlock.Header.Time + this.consensusOptions.StakeMinAge > trx.Time)
                    {
                        continue;                         // only count coins meeting min age requirement
                    }
                }

                long nValueIn   = prevUtxo._Outputs[txin.PrevOut.N].Value;
                var  multiplier = BigInteger.ValueOf((trx.Time - prevUtxo.Time) / Money.CENT);
                bnCentSecond = bnCentSecond.Add(BigInteger.ValueOf(nValueIn).Multiply(multiplier));
                //bnCentSecond += new BigInteger(nValueIn) * (trx.Time - txPrev.Time) / CENT;


                //LogPrint("coinage", "coin age nValueIn=%d nTimeDiff=%d bnCentSecond=%s\n", nValueIn, nTime - txPrev.nTime, bnCentSecond.ToString());
            }

            BigInteger bnCoinDay = bnCentSecond.Multiply(BigInteger.ValueOf(Money.CENT / Money.COIN / (24 * 60 * 60)));

            //BigInteger bnCoinDay = bnCentSecond * CENT / COIN / (24 * 60 * 60);

            //LogPrint("coinage", "coin age bnCoinDay=%s\n", bnCoinDay.ToString());
            nCoinAge = new Target(bnCoinDay).ToCompact();

            return(true);
        }