[ create a new paste ] login | about

Link: http://codepad.org/VCZUhPe3    [ raw code | fork ]

Plain Text, pasted on Dec 7:
diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp
index 606108a..ab1ae22 100644
--- a/src/rpcblockchain.cpp
+++ b/src/rpcblockchain.cpp
@@ -806,3 +806,168 @@ Value measureblockchain(const Array& params, bool fHelp)
 
     return 0;
 }
+
+#define BPS_SANITY_CHECK
+
+class BlockTxInfo {
+public:
+    unsigned int nIndex;
+    const CTransaction *ptx;
+    bool fMaybeCPFP;
+    bool fMaybeDelayed;
+    size_t nSize;
+    double dPriority;
+    CAmount nTxFee;
+    CFeeRate feerate;
+    size_t nBlockSizePrior;
+
+    BlockTxInfo() : fMaybeCPFP(false), fMaybeDelayed(false), dPriority(0.0), nTxFee(0), feerate() {};
+};
+
+Value bcprioritystats(const Array& params, bool fHelp)
+{
+    if (fHelp || params.size() > 0)
+        throw runtime_error(
+            "bcprioritystats\n"
+        );
+
+    unsigned long nTotalTxs = 0, nTotalTxsPriority = 0;
+    for (int nHeight = 300031; true; ++nHeight)
+    {
+        CBlock block;
+        {
+            LOCK(cs_main);
+            if (nHeight > chainActive.Height())
+                break;
+
+            CBlockIndex* pblockindex = chainActive[nHeight];
+
+            if(!ReadBlockFromDisk(block, pblockindex))
+                throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
+        }
+
+        if (block.vtx.size() <= 1) {
+            continue;
+        }
+
+        // Gather info
+        unsigned int nBlockSizeSoFar = ::GetSerializeSize(block.vtx[0], SER_NETWORK, PROTOCOL_VERSION);
+        BlockTxInfo vbti[block.vtx.size()];
+        std::map<uint256, BlockTxInfo*> mbti;
+        for (unsigned int i = 1; i < block.vtx.size(); ++i) {
+            BlockTxInfo& bti = vbti[i];
+            const CTransaction& tx = block.vtx[i];
+            mbti[tx.GetHash()] = &bti;
+            bti.nIndex = i;
+            bti.ptx = &tx;
+
+            bti.nBlockSizePrior = nBlockSizeSoFar;
+            bti.nSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
+
+            CAmount nValueIn = 0;
+            double& dPriority = bti.dPriority;
+            for (int txin_n = tx.vin.size(); --txin_n >= 0; ) {
+                const CTxIn& txin = tx.vin[txin_n];
+
+                std::map<uint256, BlockTxInfo*>::iterator it = mbti.find(txin.prevout.hash);
+                if (it != mbti.end()) {
+                    nValueIn += it->second->ptx->vout[txin.prevout.n].nValue;
+                    it->second->fMaybeCPFP = true;
+                    if (it->second->nIndex == i - 1) {
+                        bti.fMaybeDelayed = true;
+                    }
+                } else {
+                    CTransaction txInput;
+                    uint256 hashInputBlock = 0;
+                    if (!GetTransaction(txin.prevout.hash, txInput, hashInputBlock, true))
+                        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("No information available about transaction (height=%d; i=%d)", nHeight, i));
+
+                    CBlockIndex* const pblockindexInput = mapBlockIndex[hashInputBlock];
+#ifdef BPS_SANITY_CHECK
+#warning "BPS sanity check enabled"
+                    {
+                        LOCK(cs_main);
+                        if (!chainActive.Contains(pblockindexInput))
+                            throw JSONRPCError(RPC_INTERNAL_ERROR, "Input block is not in current chain");
+                    }
+#endif
+
+                    const CAmount& nThisValueIn = txInput.vout[txin.prevout.n].nValue;
+                    nValueIn += nThisValueIn;
+                    dPriority += (double)nThisValueIn * (nHeight - pblockindexInput->nHeight);
+                }
+            }
+            CAmount& nTxFee = bti.nTxFee;
+            nTxFee = nValueIn;
+            BOOST_FOREACH(const CTxOut& txout, tx.vout) {
+                nTxFee -= txout.nValue;
+            }
+            bti.feerate = CFeeRate(nTxFee, bti.nSize);
+            dPriority /= bti.nSize;
+
+            nBlockSizeSoFar += bti.nSize;
+//             std::cerr << i << ": " << dPriority << "," << bti.feerate.ToString() << "\n";
+        }
+
+        unsigned int nFirstFeerateIncreaseTx = 1;
+        {
+            CFeeRate nLastFeerate = vbti[block.vtx.size() - 1].feerate;
+            for (unsigned int i = block.vtx.size(); --i >= 1; ) {
+                const BlockTxInfo& bti = vbti[i];
+//                 std::cerr << i << " " << bti.ptx->GetHash().ToString() << ": cpfp="<<bti.fMaybeCPFP<<",feerate="<<bti.feerate.ToString()<<"\n";
+                if (!bti.fMaybeCPFP) {
+                    if (bti.feerate < nLastFeerate || bti.feerate == CFeeRate()) {
+                        break;
+                    }
+                }
+                nFirstFeerateIncreaseTx = i;
+                nLastFeerate = bti.feerate;
+            }
+        }
+        unsigned int nLastPriorityIncreaseTx = 1;
+        {
+            double dLastPriority = vbti[1].dPriority;
+            for (unsigned int i = 1; i < block.vtx.size(); ++i) {
+                const BlockTxInfo& bti = vbti[i];
+//                 std::cerr << i << " " << bti.ptx->GetHash().ToString() << ": delayed="<<bti.fMaybeDelayed<<",priority="<<strprintf("%.10f", bti.dPriority)<<"\n";
+                if (!bti.fMaybeDelayed) {
+                    if (bti.dPriority > dLastPriority) {
+                        break;
+                    }
+                }
+                nLastPriorityIncreaseTx = i;
+                dLastPriority = bti.dPriority;
+            }
+        }
+
+        std::cerr << nHeight << "\ttxcount=" << strprintf("%5d", block.vtx.size()) << "\tlastprio=" << strprintf("%5d", nLastPriorityIncreaseTx) << "\tfirstfeerate=" << strprintf("%5d(%5d)", nFirstFeerateIncreaseTx, block.vtx.size() - nFirstFeerateIncreaseTx);
+//         std::cerr << nHeight << ",priosize=";
+//         if (nFirstFeebasedTx >= block.vtx.size() - 1)
+//             std::cerr << "*";
+//         else
+//             std::cerr << nBlockPrioritySize;
+//         std::cerr << ",totaltx=" << nTotalTxs << ",totalpriority=" << nTotalTxsPriority << ",totalprioexceptions=" << nTotalTxsPriorityExceptions;
+        unsigned int n = (nFirstFeerateIncreaseTx ? nFirstFeerateIncreaseTx : block.vtx.size()) - 1;
+        unsigned int delta;
+        if (nLastPriorityIncreaseTx != n) {
+            if (nLastPriorityIncreaseTx > n) {
+                delta = (nLastPriorityIncreaseTx - n);
+                std::cerr << "\tOVERLAP=" << strprintf("%5d", delta);
+                nLastPriorityIncreaseTx -= delta;
+            } else if (nLastPriorityIncreaseTx < n) {
+                delta = (n - nLastPriorityIncreaseTx);
+                std::cerr << "\t  space=" << strprintf("%5d", delta);
+            }
+        } else {
+            delta = 0;
+        }
+        if (delta < 8) {
+            nTotalTxs += block.vtx.size();
+            nTotalTxsPriority += nLastPriorityIncreaseTx;
+            std::cerr << "\ttotaltx=" << strprintf("%9d", nTotalTxs) << "\ttotalpriority=" << strprintf("%9d", nTotalTxsPriority) << "(" << strprintf("%5.2f", nTotalTxsPriority * 100.0 / nTotalTxs) << "%)";
+        }
+        std::cerr << "\n";
+    }
+
+    return 0;
+}
diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp
index c3c5827..235f126 100644
--- a/src/rpcserver.cpp
+++ b/src/rpcserver.cpp
@@ -266,6 +266,7 @@ static const CRPCCommand vRPCCommands[] =
     { "blockchain",         "getblock",               &getblock,               true,      false,      false },
     { "blockchain",         "getblockhash",           &getblockhash,           true,      false,      false },
     { "blockchain",         "measureblockchain",      &measureblockchain,      true,      true,       false },
+    { "blockchain",         "bcprioritystats",        &bcprioritystats,      true,      true,       false },
     { "blockchain",         "getchaintips",           &getchaintips,           true,      false,      false },
     { "blockchain",         "getdifficulty",          &getdifficulty,          true,      false,      false },
     { "blockchain",         "getmempoolinfo",         &getmempoolinfo,         true,      true,       false },
diff --git a/src/rpcserver.h b/src/rpcserver.h
index 8712cf7..af8cec7 100644
--- a/src/rpcserver.h
+++ b/src/rpcserver.h
@@ -220,6 +220,7 @@ extern json_spirit::Value getrawmempool(const json_spirit::Array& params, bool f
 extern json_spirit::Value getblockhash(const json_spirit::Array& params, bool fHelp);
 extern json_spirit::Value getblock(const json_spirit::Array& params, bool fHelp);
 extern json_spirit::Value measureblockchain(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value bcprioritystats(const json_spirit::Array& params, bool fHelp);
 extern json_spirit::Value gettxoutsetinfo(const json_spirit::Array& params, bool fHelp);
 extern json_spirit::Value gettxout(const json_spirit::Array& params, bool fHelp);
 extern json_spirit::Value verifychain(const json_spirit::Array& params, bool fHelp);


Create a new paste based on this one


Comments: