[117082] users/anddam

and.damore at macports.org and.damore at macports.org
Sat Feb 15 00:24:58 PST 2014


Revision: 117082
          https://trac.macports.org/changeset/117082
Author:   and.damore at macports.org
Date:     2014-02-15 00:24:58 -0800 (Sat, 15 Feb 2014)
Log Message:
-----------
personal folder: working in progress patch for bitcoin port

Added Paths:
-----------
    users/anddam/bitcoin/
    users/anddam/bitcoin/patch_bitcoin-bitcoin_pull-request_2802.diff
    users/anddam/bitcoin/patch_src_main_cpp.diff
    users/anddam/bitcoin/patch_src_main_h.diff
    users/anddam/bitcoin/patch_src_src_serialize_h.diff

Added: users/anddam/bitcoin/patch_bitcoin-bitcoin_pull-request_2802.diff
===================================================================
--- users/anddam/bitcoin/patch_bitcoin-bitcoin_pull-request_2802.diff	                        (rev 0)
+++ users/anddam/bitcoin/patch_bitcoin-bitcoin_pull-request_2802.diff	2014-02-15 08:24:58 UTC (rev 117082)
@@ -0,0 +1,411 @@
+diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp
+index 11fac42..a542470 100644
+--- src/bitcoinrpc.cpp
++++ src/bitcoinrpc.cpp
+@@ -249,6 +249,7 @@ Value stop(const Array& params, bool fHelp)
+     { "importwallet",           &importwallet,           false,     false },
+     { "listunspent",            &listunspent,            false,     false },
+     { "getrawtransaction",      &getrawtransaction,      false,     false },
++    { "searchrawtransactions",  &searchrawtransactions,  false,     false },
+     { "createrawtransaction",   &createrawtransaction,   false,     false },
+     { "decoderawtransaction",   &decoderawtransaction,   false,     false },
+     { "signrawtransaction",     &signrawtransaction,     false,     false },
+@@ -1189,6 +1190,9 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
+     if (strMethod == "listunspent"            && n > 2) ConvertTo<Array>(params[2]);
+     if (strMethod == "getblock"               && n > 1) ConvertTo<bool>(params[1]);
+     if (strMethod == "getrawtransaction"      && n > 1) ConvertTo<boost::int64_t>(params[1]);
++    if (strMethod == "searchrawtransactions"  && n > 1) ConvertTo<boost::int64_t>(params[1]);
++    if (strMethod == "searchrawtransactions"  && n > 2) ConvertTo<boost::int64_t>(params[2]);
++    if (strMethod == "searchrawtransactions"  && n > 3) ConvertTo<boost::int64_t>(params[3]);
+     if (strMethod == "createrawtransaction"   && n > 0) ConvertTo<Array>(params[0]);
+     if (strMethod == "createrawtransaction"   && n > 1) ConvertTo<Object>(params[1]);
+     if (strMethod == "signrawtransaction"     && n > 1) ConvertTo<Array>(params[1], true);
+diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h
+index 4d5599b..443bf98 100644
+--- src/bitcoinrpc.h
++++ src/bitcoinrpc.h
+@@ -192,6 +192,7 @@ class CRPCTable
+ extern json_spirit::Value getinfo(const json_spirit::Array& params, bool fHelp);
+ 
+ extern json_spirit::Value getrawtransaction(const json_spirit::Array& params, bool fHelp); // in rcprawtransaction.cpp
++extern json_spirit::Value searchrawtransactions(const json_spirit::Array& params, bool fHelp);
+ extern json_spirit::Value listunspent(const json_spirit::Array& params, bool fHelp);
+ extern json_spirit::Value lockunspent(const json_spirit::Array& params, bool fHelp);
+ extern json_spirit::Value listlockunspent(const json_spirit::Array& params, bool fHelp);
+diff --git a/src/init.cpp b/src/init.cpp
+index f6b2c91..a8a2379 100644
+--- src/init.cpp
++++ src/init.cpp
+@@ -710,7 +710,7 @@ bool AppInit2(boost::thread_group& threadGroup)
+     if (nTotalCache < (1 << 22))
+         nTotalCache = (1 << 22); // total cache cannot be less than 4 MiB
+     size_t nBlockTreeDBCache = nTotalCache / 8;
+-    if (nBlockTreeDBCache > (1 << 21) && !GetBoolArg("-txindex", false))
++    if (nBlockTreeDBCache > (1 << 21) && !GetBoolArg("-txindex", false) && !GetBoolArg("-addrindex", false))
+         nBlockTreeDBCache = (1 << 21); // block tree db cache shouldn't be larger than 2 MiB
+     nTotalCache -= nBlockTreeDBCache;
+     size_t nCoinDBCache = nTotalCache / 2; // use half of the remaining cache for coindb cache
+@@ -761,6 +761,12 @@ bool AppInit2(boost::thread_group& threadGroup)
+                     break;
+                 }
+ 
++                // Check for changed -addrindex state
++                if (fAddrIndex != GetBoolArg("-addrindex", false)) {
++                    strLoadError = _("You need to rebuild the database using -reindex to change -addrindex");
++                    break;
++                }
++
+                 uiInterface.InitMessage(_("Verifying blocks..."));
+                 if (!VerifyDB(GetArg("-checklevel", 3),
+                               GetArg( "-checkblocks", 288))) {
+diff --git a/src/leveldb.cpp b/src/leveldb.cpp
+index e66f851..ae8d00d 100644
+--- src/leveldb.cpp
++++ src/leveldb.cpp
+@@ -34,6 +34,13 @@ static leveldb::Options GetOptions(size_t nCacheSize) {
+     return options;
+ }
+ 
++CLevelDBIterator::~CLevelDBIterator() { delete piter; }
++bool CLevelDBIterator::Valid() { return piter->Valid(); }
++void CLevelDBIterator::SeekToFirst() { piter->SeekToFirst(); }
++void CLevelDBIterator::SeekToLast() { piter->SeekToLast(); }
++void CLevelDBIterator::Next() { piter->Next(); }
++void CLevelDBIterator::Prev() { piter->Prev(); }
++
+ CLevelDB::CLevelDB(const boost::filesystem::path &path, size_t nCacheSize, bool fMemory, bool fWipe) {
+     penv = NULL;
+     readoptions.verify_checksums = true;
+diff --git a/src/leveldb.h b/src/leveldb.h
+index 79262ed..3388504 100644
+--- src/leveldb.h
++++ src/leveldb.h
+@@ -52,6 +52,63 @@ class CLevelDBBatch
+     }
+ };
+ 
++class CLevelDBIterator
++{
++private:
++    leveldb::Iterator *piter;
++
++public:
++    CLevelDBIterator(leveldb::Iterator *piterIn) : piter(piterIn) {}
++    ~CLevelDBIterator();
++
++    bool Valid();
++
++    void SeekToFirst();
++    void SeekToLast();
++
++    template<typename K> void Seek(const K& key) {
++        CDataStream ssKey(SER_DISK, CLIENT_VERSION);
++        ssKey.reserve(ssKey.GetSerializeSize(key));
++        ssKey << key;
++        leveldb::Slice slKey(&ssKey[0], ssKey.size());
++        piter->Seek(slKey);
++    }
++
++    void Next();
++    void Prev();
++
++    template<typename K> bool GetKey(K& key) {
++        leveldb::Slice slKey = piter->key();
++        try {
++            CDataStream ssKey(slKey.data(), slKey.data() + slKey.size(), SER_DISK, CLIENT_VERSION);
++            ssKey >> key;
++        } catch(std::exception &e) {
++            return false;
++        }
++        return true;
++    }
++
++    unsigned int GetKeySize() {
++        return piter->key().size();
++    }
++
++    template<typename V> bool GetValue(V& value) {
++        leveldb::Slice slValue = piter->value();
++        try {
++            CDataStream ssValue(slValue.data(), slValue.data() + slValue.size(), SER_DISK, CLIENT_VERSION);
++            ssValue >> value;
++        } catch(std::exception &e) {
++            return false;
++        }
++        return true;
++    }
++
++    unsigned int GetValueSize() {
++        return piter->value().size();
++    }
++
++};
++
+ class CLevelDB
+ {
+ private:
+@@ -144,9 +201,8 @@ class CLevelDB
+         return WriteBatch(batch, true);
+     }
+ 
+-    // not exactly clean encapsulation, but it's easiest for now
+-    leveldb::Iterator *NewIterator() {
+-        return pdb->NewIterator(iteroptions);
++    CLevelDBIterator *NewIterator() {
++        return new CLevelDBIterator(pdb->NewIterator(iteroptions));
+     }
+ };
+ 
+diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp
+index f08688d..f7b88a1 100644
+--- src/rpcrawtransaction.cpp
++++ src/rpcrawtransaction.cpp
+@@ -131,6 +131,66 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry)
+     }
+ }
+ 
++Value searchrawtransactions(const Array &params, bool fHelp)
++{
++    if (fHelp || params.size() < 1 || params.size() > 4)
++        throw runtime_error(
++            "searchrawtransactions <address> [verbose=1] [skip=0] [count=100]\n");
++
++    if (!fAddrIndex)
++        throw JSONRPCError(RPC_MISC_ERROR, "Address index not enabled");
++
++    CBitcoinAddress address(params[0].get_str());
++    if (!address.IsValid())
++        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
++    CTxDestination dest = address.Get();
++
++    std::set<CExtDiskTxPos> setpos;
++    if (!FindTransactionsByDestination(dest, setpos))
++        throw JSONRPCError(RPC_DATABASE_ERROR, "Cannot search for address");
++
++    int nSkip = 0;
++    int nCount = 100;
++    bool fVerbose = true;
++    if (params.size() > 1)
++        fVerbose = (params[1].get_int() != 0);
++    if (params.size() > 2)
++        nSkip = params[2].get_int();
++    if (params.size() > 3)
++        nCount = params[3].get_int();
++
++    if (nSkip < 0)
++        nSkip += setpos.size();
++    if (nSkip < 0)
++        nSkip = 0;
++    if (nCount < 0)
++        nCount = 0;
++
++    std::set<CExtDiskTxPos>::const_iterator it = setpos.begin();
++    while (it != setpos.end() && nSkip--) it++;
++
++    Array result;
++    while (it != setpos.end() && nCount--) {
++        CTransaction tx;
++        uint256 hashBlock;
++        if (!ReadTransaction(tx, *it, hashBlock))
++            throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Cannot read transaction from disk");
++        CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
++        ssTx << tx;
++        string strHex = HexStr(ssTx.begin(), ssTx.end());
++        if (fVerbose) {
++            Object object;
++            TxToJSON(tx, hashBlock, object);
++            object.push_back(Pair("hex", strHex));
++            result.push_back(object);
++        } else {
++            result.push_back(strHex);
++        }
++        it++;
++    }
++    return result;
++}
++
+ Value getrawtransaction(const Array& params, bool fHelp)
+ {
+     if (fHelp || params.size() < 1 || params.size() > 2)
+diff --git a/src/txdb.cpp b/src/txdb.cpp
+index 34836ea..7b8b3a5 100644
+--- src/txdb.cpp
++++ src/txdb.cpp
+@@ -67,6 +67,10 @@ bool CCoinsViewDB::BatchWrite(const std::map<uint256, CCoins> &mapCoins, CBlockI
+ }
+ 
+ CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CLevelDB(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe) {
++    if (!Read('S', salt)) {
++        salt = GetRandHash();
++        Write('S', salt);
++    }
+ }
+ 
+ bool CBlockTreeDB::WriteBlockIndex(const CDiskBlockIndex& blockindex)
+@@ -113,8 +117,8 @@ bool CBlockTreeDB::ReadLastBlockFile(int &nFile) {
+ }
+ 
+ bool CCoinsViewDB::GetStats(CCoinsStats &stats) {
+-    leveldb::Iterator *pcursor = db.NewIterator();
+-    pcursor->SeekToFirst();
++    CLevelDBIterator *pcursor = db.NewIterator();
++    pcursor->Seek('c');
+ 
+     CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
+     stats.hashBlock = GetBestBlock()->GetBlockHash();
+@@ -122,22 +126,10 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) {
+     int64 nTotalAmount = 0;
+     while (pcursor->Valid()) {
+         boost::this_thread::interruption_point();
+-        try {
+-            leveldb::Slice slKey = pcursor->key();
+-            CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION);
+-            char chType;
+-            ssKey >> chType;
+-            if (chType == 'c') {
+-                leveldb::Slice slValue = pcursor->value();
+-                CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION);
+-                CCoins coins;
+-                ssValue >> coins;
+-                uint256 txhash;
+-                ssKey >> txhash;
+-                ss << txhash;
+-                ss << VARINT(coins.nVersion);
+-                ss << (coins.fCoinBase ? 'c' : 'n'); 
+-                ss << VARINT(coins.nHeight);
++        std::pair<char, uint256> key;
++        CCoins coins;
++        if (pcursor->GetKey(key) && key.first == 'c') {
++            if (pcursor->GetValue(coins)) {
+                 stats.nTransactions++;
+                 for (unsigned int i=0; i<coins.vout.size(); i++) {
+                     const CTxOut &out = coins.vout[i];
+@@ -148,13 +140,15 @@ bool CCoinsViewDB::GetStats(CCoinsStats &stats) {
+                         nTotalAmount += out.nValue;
+                     }
+                 }
+-                stats.nSerializedSize += 32 + slValue.size();
++                stats.nSerializedSize += 32 + pcursor->GetKeySize();
+                 ss << VARINT(0);
++            } else {
++                return error("CCoinsViewDB::GetStats() : unable to read value");
+             }
+-            pcursor->Next();
+-        } catch (std::exception &e) {
+-            return error("%s() : deserialize error", __PRETTY_FUNCTION__);
++        } else {
++            break;
+         }
++        pcursor->Next();
+     }
+     delete pcursor;
+     stats.nHeight = GetBestBlock()->nHeight;
+@@ -174,6 +168,40 @@ bool CBlockTreeDB::WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos>
+     return WriteBatch(batch);
+ }
+ 
++bool CBlockTreeDB::ReadAddrIndex(uint160 addrid, std::vector<CExtDiskTxPos> &list) {
++    CLevelDBIterator *iter = NewIterator();
++    uint64 lookupid;
++    {
++        CHashWriter ss(SER_GETHASH, 0);
++        ss << salt;
++        ss << addrid;
++        lookupid = ss.GetHash().Get64(0);
++    }
++    iter->Seek(make_pair('a', lookupid));
++    while (iter->Valid()) {
++        std::pair<std::pair<char, uint64>, CExtDiskTxPos> key;
++        if (iter->GetKey(key) && key.first.first == 'a' && key.first.second == lookupid) {
++            list.push_back(key.second);
++        } else {
++            break;
++        }
++        iter->Next();
++    }
++    return true;
++}
++
++bool CBlockTreeDB::AddAddrIndex(const std::vector<std::pair<uint160, CExtDiskTxPos> > &list) {
++    unsigned char foo[0];
++    CLevelDBBatch batch;
++    for (std::vector<std::pair<uint160, CExtDiskTxPos> >::const_iterator it=list.begin(); it!=list.end(); it++) {
++        CHashWriter ss(SER_GETHASH, 0);
++        ss << salt;
++        ss << it->first;
++        batch.Write(make_pair(make_pair('a', ss.GetHash().Get64(0)), it->second), FLATDATA(foo));
++    }
++    return WriteBatch(batch);
++}
++
+ bool CBlockTreeDB::WriteFlag(const std::string &name, bool fValue) {
+     return Write(std::make_pair('F', name), fValue ? '1' : '0');
+ }
+@@ -188,26 +216,17 @@ bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) {
+ 
+ bool CBlockTreeDB::LoadBlockIndexGuts()
+ {
+-    leveldb::Iterator *pcursor = NewIterator();
++    CLevelDBIterator *pcursor = NewIterator();
+ 
+-    CDataStream ssKeySet(SER_DISK, CLIENT_VERSION);
+-    ssKeySet << make_pair('b', uint256(0));
+-    pcursor->Seek(ssKeySet.str());
++    pcursor->Seek(make_pair('b', uint256(0)));
+ 
+     // Load mapBlockIndex
+     while (pcursor->Valid()) {
+         boost::this_thread::interruption_point();
+-        try {
+-            leveldb::Slice slKey = pcursor->key();
+-            CDataStream ssKey(slKey.data(), slKey.data()+slKey.size(), SER_DISK, CLIENT_VERSION);
+-            char chType;
+-            ssKey >> chType;
+-            if (chType == 'b') {
+-                leveldb::Slice slValue = pcursor->value();
+-                CDataStream ssValue(slValue.data(), slValue.data()+slValue.size(), SER_DISK, CLIENT_VERSION);
+-                CDiskBlockIndex diskindex;
+-                ssValue >> diskindex;
+-
++        std::pair<char, uint256> key;
++        if (pcursor->GetKey(key) && key.first == 'b') {
++            CDiskBlockIndex diskindex;
++            if (pcursor->GetValue(diskindex)) {
+                 // Construct block index object
+                 CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash());
+                 pindexNew->pprev          = InsertBlockIndex(diskindex.hashPrev);
+@@ -232,10 +251,10 @@ bool CBlockTreeDB::LoadBlockIndexGuts()
+ 
+                 pcursor->Next();
+             } else {
+-                break; // if shutdown requested or finished loading block index
++                return error("LoadBlockIndex() : failed to read value");
+             }
+-        } catch (std::exception &e) {
+-            return error("%s() : deserialize error", __PRETTY_FUNCTION__);
++        } else {
++            break;
+         }
+     }
+     delete pcursor;
+diff --git a/src/txdb.h b/src/txdb.h
+index f59fc5d..7f5c171 100644
+--- src/txdb.h
++++ src/txdb.h
+@@ -31,6 +31,7 @@ class CBlockTreeDB : public CLevelDB
+ public:
+     CBlockTreeDB(size_t nCacheSize, bool fMemory = false, bool fWipe = false);
+ private:
++    uint256 salt;
+     CBlockTreeDB(const CBlockTreeDB&);
+     void operator=(const CBlockTreeDB&);
+ public:
+@@ -45,6 +46,8 @@ class CBlockTreeDB : public CLevelDB
+     bool ReadReindexing(bool &fReindex);
+     bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos);
+     bool WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos> > &list);
++    bool ReadAddrIndex(uint160 addrid, std::vector<CExtDiskTxPos> &list);
++    bool AddAddrIndex(const std::vector<std::pair<uint160, CExtDiskTxPos> > &list);
+     bool WriteFlag(const std::string &name, bool fValue);
+     bool ReadFlag(const std::string &name, bool &fValue);
+     bool LoadBlockIndexGuts();

Added: users/anddam/bitcoin/patch_src_main_cpp.diff
===================================================================
--- users/anddam/bitcoin/patch_src_main_cpp.diff	                        (rev 0)
+++ users/anddam/bitcoin/patch_src_main_cpp.diff	2014-02-15 08:24:58 UTC (rev 117082)
@@ -0,0 +1,180 @@
+--- src/main.cpp.original	2014-02-14 22:20:23.000000000 +0100
++++ src/main.cpp	2014-02-14 22:46:32.000000000 +0100
+@@ -46,6 +46,7 @@
+ bool fReindex = false;
+ bool fBenchmark = false;
+ bool fTxIndex = false;
++bool fAddrIndex = false;
+ unsigned int nCoinCacheSize = 5000;
+ 
+ /** Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) */
+@@ -962,6 +963,42 @@
+     return false;
+ }
+ 
++bool ReadTransaction(CTransaction& tx, const CDiskTxPos &pos, uint256 &hashBlock) {
++    CAutoFile file(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
++    CBlockHeader header;
++    try {
++        file >> header;
++        fseek(file, pos.nTxOffset, SEEK_CUR);
++        file >> tx;
++    } catch (std::exception &e) {
++        return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__);
++    }
++    hashBlock = header.GetHash();
++    return true;
++}
++
++bool FindTransactionsByDestination(const CTxDestination &dest, std::set<CExtDiskTxPos> &setpos) {
++    uint160 addrid = 0;
++    const CKeyID *pkeyid = boost::get<CKeyID>(&dest);
++    if (pkeyid)
++        addrid = static_cast<uint160>(*pkeyid);
++    if (!addrid) {
++        const CScriptID *pscriptid = boost::get<CScriptID>(&dest);
++        if (pscriptid)
++            addrid = static_cast<uint160>(*pscriptid);
++    }
++    if (!addrid)
++        return false;
++
++    LOCK(cs_main);
++    if (!fAddrIndex)
++        return false;
++    std::vector<CExtDiskTxPos> vPos;
++    if (!pblocktree->ReadAddrIndex(addrid, vPos))
++        return false;
++    setpos.insert(vPos.begin(), vPos.end());
++    return true;
++}
+ 
+ // Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock
+ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
+@@ -981,16 +1018,8 @@
+         if (fTxIndex) {
+             CDiskTxPos postx;
+             if (pblocktree->ReadTxIndex(hash, postx)) {
+-                CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
+-                CBlockHeader header;
+-                try {
+-                    file >> header;
+-                    fseek(file, postx.nTxOffset, SEEK_CUR);
+-                    file >> txOut;
+-                } catch (std::exception &e) {
+-                    return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__);
+-                }
+-                hashBlock = header.GetHash();
++                if (!ReadTransaction(txOut, postx, hashBlock))
++                    return false;
+                 if (txOut.GetHash() != hash)
+                     return error("%s() : txid mismatch", __PRETTY_FUNCTION__);
+                 return true;
+@@ -1596,6 +1625,32 @@
+     scriptcheckqueue.Thread();
+ }
+ 
++// Index either: a) every data push >=8 bytes,  b) if no such pushes, the entire script
++void static BuildAddrIndex(const CScript &script, const CExtDiskTxPos &pos, std::vector<std::pair<uint160, CExtDiskTxPos> > &out) {
++    CScript::const_iterator pc = script.begin();
++    CScript::const_iterator pend = script.end();
++    std::vector<unsigned char> data;
++    opcodetype opcode;
++    bool fHaveData = false;
++    while (pc < pend) {
++        script.GetOp(pc, opcode, data);
++        if (0 <= opcode && opcode <= OP_PUSHDATA4 && data.size() >= 8) { // data element
++            uint160 addrid = 0;
++            if (data.size() <= 20) {
++                memcpy(&addrid, &data[0], data.size());
++            } else {
++                addrid = Hash160(data);
++            }
++            out.push_back(std::make_pair(addrid, pos));
++            fHaveData = true;
++        }
++    }
++    if (!fHaveData) {
++        uint160 addrid = Hash160(script);
++        out.push_back(std::make_pair(addrid, pos));
++    }
++}
++
+ bool CBlock::ConnectBlock(CValidationState &state, CBlockIndex* pindex, CCoinsViewCache &view, bool fJustCheck)
+ {
+     // Check it again in case a previous version let a bad block in
+@@ -1653,9 +1708,13 @@
+     int64 nFees = 0;
+     int nInputs = 0;
+     unsigned int nSigOps = 0;
+-    CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(vtx.size()));
+-    std::vector<std::pair<uint256, CDiskTxPos> > vPos;
+-    vPos.reserve(vtx.size());
++    CExtDiskTxPos pos(CDiskTxPos(pindex->GetBlockPos(), GetSizeOfCompactSize(vtx.size())), pindex->nHeight);
++    std::vector<std::pair<uint256, CDiskTxPos> > vPosTxid;
++    std::vector<std::pair<uint160, CExtDiskTxPos> > vPosAddrid;
++    if (fTxIndex)
++        vPosTxid.reserve(vtx.size());
++    if (fAddrIndex)
++        vPosAddrid.reserve(4*vtx.size());
+     for (unsigned int i=0; i<vtx.size(); i++)
+     {
+         const CTransaction &tx = vtx[i];
+@@ -1687,13 +1746,24 @@
+                 return false;
+             control.Add(vChecks);
+         }
++        if (fTxIndex)
++            vPosTxid.push_back(std::make_pair(GetTxHash(i), pos));
++        if (fAddrIndex) {
++            if (!tx.IsCoinBase()) {
++                BOOST_FOREACH(const CTxIn &txin, tx.vin) {
++                    const CCoins &coins = view.GetCoins(txin.prevout.hash);
++                    BuildAddrIndex(coins.vout[txin.prevout.n].scriptPubKey, pos, vPosAddrid);
++                }
++            }
++            BOOST_FOREACH(const CTxOut &txout, tx.vout)
++                BuildAddrIndex(txout.scriptPubKey, pos, vPosAddrid);
++        }
+ 
+         CTxUndo txundo;
+         tx.UpdateCoins(state, view, txundo, pindex->nHeight, GetTxHash(i));
+         if (!tx.IsCoinBase())
+             blockundo.vtxundo.push_back(txundo);
+ 
+-        vPos.push_back(std::make_pair(GetTxHash(i), pos));
+         pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
+     }
+     int64 nTime = GetTimeMicros() - nStart;
+@@ -1735,8 +1805,11 @@
+     }
+ 
+     if (fTxIndex)
+-        if (!pblocktree->WriteTxIndex(vPos))
++        if (!pblocktree->WriteTxIndex(vPosTxid))
+             return state.Abort(_("Failed to write transaction index"));
++    if (fAddrIndex)
++        if (!pblocktree->AddAddrIndex(vPosAddrid))
++            return state.Abort(_("Failed to write address index"));
+ 
+     // add this block to the view's block chain
+     assert(view.SetBestBlock(pindex));
+@@ -2608,6 +2681,9 @@
+     pblocktree->ReadFlag("txindex", fTxIndex);
+     printf("LoadBlockIndexDB(): transaction index %s\n", fTxIndex ? "enabled" : "disabled");
+ 
++    pblocktree->ReadFlag("addrindex", fAddrIndex);
++    printf("LoadBlockIndexDB(): address index %s\n", fAddrIndex ? "enabled" : "disabled");
++
+     // Load hashBestChain pointer to end of best chain
+     pindexBest = pcoinsTip->GetBestBlock();
+     if (pindexBest == NULL)
+@@ -2745,6 +2821,8 @@
+     // Use the provided setting for -txindex in the new database
+     fTxIndex = GetBoolArg("-txindex", false);
+     pblocktree->WriteFlag("txindex", fTxIndex);
++    fAddrIndex = GetBoolArg("-addrindex", false);
++    pblocktree->WriteFlag("addrindex", fAddrIndex);
+     printf("Initializing databases...\n");
+ 
+     // Only add the genesis block if not reindexing (in which case we reuse the one already on disk)

Added: users/anddam/bitcoin/patch_src_main_h.diff
===================================================================
--- users/anddam/bitcoin/patch_src_main_h.diff	                        (rev 0)
+++ users/anddam/bitcoin/patch_src_main_h.diff	2014-02-15 08:24:58 UTC (rev 117082)
@@ -0,0 +1,77 @@
+--- src/main.h.orig	2014-02-15 08:19:57.000000000 +0100
++++ src/main.h	2014-02-15 08:20:42.000000000 +0100
+@@ -96,6 +96,7 @@
+ extern bool fBenchmark;
+ extern int nScriptCheckThreads;
+ extern bool fTxIndex;
++extern bool fAddrIndex;
+ extern unsigned int nCoinCacheSize;
+ 
+ // Settings
+@@ -248,8 +249,57 @@
+         CDiskBlockPos::SetNull();
+         nTxOffset = 0;
+     }
++    
++    friend bool operator==(const CDiskTxPos &a, const CDiskTxPos &b) {
++        return (a.nFile == b.nFile && a.nPos == b.nPos && a.nTxOffset == b.nTxOffset);
++    }
++
++    friend bool operator!=(const CDiskTxPos &a, const CDiskTxPos &b) {
++        return !(a == b);
++    }
++
++    friend bool operator<(const CDiskTxPos &a, const CDiskTxPos &b) {
++        return  (a.nFile < b.nFile || (
++                (a.nFile == b.nFile) && (a.nPos < b.nPos || (
++                                        (a.nPos == b.nPos) && (a.nTxOffset < b.nTxOffset)))));
++    }
+ };
+ 
++struct CExtDiskTxPos : public CDiskTxPos
++{
++    unsigned int nHeight;
++
++    IMPLEMENT_SERIALIZE(
++        READWRITE(*(CDiskTxPos*)this);
++        READWRITE(VARINT(nHeight));
++    )
++
++    CExtDiskTxPos(const CDiskTxPos &pos, int nHeightIn) : CDiskTxPos(pos), nHeight(nHeightIn) {
++    }
++
++    CExtDiskTxPos() {
++        SetNull();
++    }
++
++    void SetNull() {
++        CDiskTxPos::SetNull();
++        nHeight = 0;
++    }
++
++    friend bool operator==(const CExtDiskTxPos &a, const CExtDiskTxPos &b) {
++        return (a.nHeight == b.nHeight && a.nFile == b.nFile && a.nPos == b.nPos && a.nTxOffset == b.nTxOffset);
++    }
++ 
++    friend bool operator!=(const CExtDiskTxPos &a, const CExtDiskTxPos &b) {
++        return !(a == b);
++    }
++
++    friend bool operator<(const CExtDiskTxPos &a, const CExtDiskTxPos &b) {
++        if (a.nHeight < b.nHeight) return true;
++        if (a.nHeight > b.nHeight) return false;
++        return ((const CDiskTxPos)a < (const CDiskTxPos)b);
++    }
++};
+ 
+ /** An inpoint - a combination of a transaction and an index n into its vin */
+ class CInPoint
+@@ -264,6 +314,8 @@
+     bool IsNull() const { return (ptx == NULL && n == (unsigned int) -1); }
+ };
+ 
++bool ReadTransaction(CTransaction& tx, const CDiskTxPos &pos, uint256 &hashBlock);
++bool FindTransactionsByDestination(const CTxDestination &dest, std::set<CExtDiskTxPos> &setpos);
+ 
+ 
+ /** An outpoint - a combination of a transaction hash and an index n into its vout */

Added: users/anddam/bitcoin/patch_src_src_serialize_h.diff
===================================================================
--- users/anddam/bitcoin/patch_src_src_serialize_h.diff	                        (rev 0)
+++ users/anddam/bitcoin/patch_src_src_serialize_h.diff	2014-02-15 08:24:58 UTC (rev 117082)
@@ -0,0 +1,22 @@
+--- src/serialize.h.orig	2014-02-13 19:17:19.000000000 +0100
++++ src/serialize.h	2014-02-13 19:19:00.000000000 +0100
+@@ -895,19 +895,6 @@
+     iterator insert(iterator it, const char& x=char()) { return vch.insert(it, x); }
+     void insert(iterator it, size_type n, const char& x) { vch.insert(it, n, x); }
+ 
+-    void insert(iterator it, const_iterator first, const_iterator last)
+-    {
+-        assert(last - first >= 0);
+-        if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos)
+-        {
+-            // special case for inserting at the front when there's room
+-            nReadPos -= (last - first);
+-            memcpy(&vch[nReadPos], &first[0], last - first);
+-        }
+-        else
+-            vch.insert(it, first, last);
+-    }
+-
+     void insert(iterator it, std::vector<char>::const_iterator first, std::vector<char>::const_iterator last)
+     {
+         assert(last - first >= 0);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/macports-changes/attachments/20140215/7c253a0e/attachment-0001.html>


More information about the macports-changes mailing list