<commit_before>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    // How many times we expect transactions after the last checkpoint to
    // be slower. This number is a compromise, as it can't be accurate for
    // every system. When reindexing from a fast disk with a slow CPU, it
    // can be up to 20, while when downloading from a slow network with a
    // fast multicore CPU, it won't be much higher than 1.
    static const double fSigcheckVerificationFactor = 5.0;

    struct CCheckpointData {
        const MapCheckpoints *mapCheckpoints;
        int64 nTimeLastCheckpoint;
        int64 nTransactionsLastCheckpoint;
        double fTransactionsPerDay;
    };

    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        ( 0, uint256("0x000000dcb4434e2148558a0a5c71e5c06d864accef97d75ac1c031405deb3371"))
        ( 145025, uint256("0x0316c10a202c2bde44628c8cac2d75d61f078a1d961ae1499eaa98eb643b5068"))
        ( 179266, uint256("0x7b102e1f37971dcd4311cc64f83fc62da0f75c22270e831be0a6c8cc38ddd5c8"))
	( 338643, uint256("0xdd79a4b1ac2a91d9666d97a2654ee826c84e55495665bacaac2b9a953616f8d6"))
	( 406644, uint256("0xc0f29fe22936216e6a90a4178967ba8ffa9ad78930aa1a369a6fc727a3d2f8e5"))
        ( 845000, uint256("0xa32d61133e22687a63c0c2769552a851a484b030cda02f8a1def5a506d368e33"))
	( 900000, uint256("0x1054253e8fd7b596cdddd562619da01022024623ee72ed3b37ea909c3caa5cc7"))
        ( 950000, uint256("0xdd4b0d5c8ae8dca9b0fd8ebee3fdf1312c47cdf73f18bff2379d5e4e2d1e59c8"))
        ( 966200, uint256("0xb4d0943e70a43256e5a329e7f7450abc42cd1aa9a8f277b0ef7a990dccbbe800"))
	;
    static const CCheckpointData data = {
        &mapCheckpoints,
        1450009340, // * UNIX timestamp of last checkpoint block
        674257,     // * total number of transactions between genesis and last checkpoint
                    //   (the tx=... number in the SetBestChain debug.log lines)
        60000.0     // * estimated number of transactions per day after checkpoint
    };

    static MapCheckpoints mapCheckpointsTestnet =
        boost::assign::map_list_of
        ( 0, uint256("0x00000052d978f26d698e0c4dbce9f8139a69f2fbda37715149146776aeb70d5b"))
        ;
    static const CCheckpointData dataTestnet = {
        &mapCheckpointsTestnet,
        1392351202,
        0,
        60000.0
    };

    const CCheckpointData &Checkpoints() {
        if (fTestNet)
            return dataTestnet;
        else
            return data;
    }

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (!GetBoolArg("-checkpoints", true))
            return true;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    // Guess how far we are in the verification process at the given block index
    double GuessVerificationProgress(CBlockIndex *pindex) {
        if (pindex==NULL)
            return 0.0;

        int64 nNow = time(NULL);

        double fWorkBefore = 0.0; // Amount of work done before pindex
        double fWorkAfter = 0.0;  // Amount of work left after pindex (estimated)
        // Work is defined as: 1.0 per transaction before the last checkoint, and
        // fSigcheckVerificationFactor per transaction after.

        const CCheckpointData &data = Checkpoints();

        if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) {
            double nCheapBefore = pindex->nChainTx;
            double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx;
            double nExpensiveAfter = (nNow - data.nTimeLastCheckpoint)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore;
            fWorkAfter = nCheapAfter + nExpensiveAfter*fSigcheckVerificationFactor;
        } else {
            double nCheapBefore = data.nTransactionsLastCheckpoint;
            double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint;
            double nExpensiveAfter = (nNow - pindex->nTime)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore + nExpensiveBefore*fSigcheckVerificationFactor;
            fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor;
        }

        return fWorkBefore / (fWorkBefore + fWorkAfter);
    }

    int GetTotalBlocksEstimate()
    {
        if (!GetBoolArg("-checkpoints", true))
            return 0;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (!GetBoolArg("-checkpoints", true))
            return NULL;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<commit_msg>Update checkpoints.cpp<commit_after>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    // How many times we expect transactions after the last checkpoint to
    // be slower. This number is a compromise, as it can't be accurate for
    // every system. When reindexing from a fast disk with a slow CPU, it
    // can be up to 20, while when downloading from a slow network with a
    // fast multicore CPU, it won't be much higher than 1.
    static const double fSigcheckVerificationFactor = 5.0;

    struct CCheckpointData {
        const MapCheckpoints *mapCheckpoints;
        int64 nTimeLastCheckpoint;
        int64 nTransactionsLastCheckpoint;
        double fTransactionsPerDay;
    };

    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        ( 0, uint256("0x000000dcb4434e2148558a0a5c71e5c06d864accef97d75ac1c031405deb3371"))
        ( 145025, uint256("0x0316c10a202c2bde44628c8cac2d75d61f078a1d961ae1499eaa98eb643b5068"))
        ( 179266, uint256("0x7b102e1f37971dcd4311cc64f83fc62da0f75c22270e831be0a6c8cc38ddd5c8"))
	( 338643, uint256("0xdd79a4b1ac2a91d9666d97a2654ee826c84e55495665bacaac2b9a953616f8d6"))
	( 406644, uint256("0xc0f29fe22936216e6a90a4178967ba8ffa9ad78930aa1a369a6fc727a3d2f8e5"))
        ( 845000, uint256("0xa32d61133e22687a63c0c2769552a851a484b030cda02f8a1def5a506d368e33"))
	( 900000, uint256("0x1054253e8fd7b596cdddd562619da01022024623ee72ed3b37ea909c3caa5cc7"))
        ( 950000, uint256("0xdd4b0d5c8ae8dca9b0fd8ebee3fdf1312c47cdf73f18bff2379d5e4e2d1e59c8"))
        ( 966300, uint256("0xb4d0943e70a43256e5a329e7f7450abc42cd1aa9a8f277b0ef7a990dccbbe800"))
	;
    static const CCheckpointData data = {
        &mapCheckpoints,
        1450009340, // * UNIX timestamp of last checkpoint block
        674257,     // * total number of transactions between genesis and last checkpoint
                    //   (the tx=... number in the SetBestChain debug.log lines)
        60000.0     // * estimated number of transactions per day after checkpoint
    };

    static MapCheckpoints mapCheckpointsTestnet =
        boost::assign::map_list_of
        ( 0, uint256("0x00000052d978f26d698e0c4dbce9f8139a69f2fbda37715149146776aeb70d5b"))
        ;
    static const CCheckpointData dataTestnet = {
        &mapCheckpointsTestnet,
        1392351202,
        0,
        60000.0
    };

    const CCheckpointData &Checkpoints() {
        if (fTestNet)
            return dataTestnet;
        else
            return data;
    }

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (!GetBoolArg("-checkpoints", true))
            return true;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    // Guess how far we are in the verification process at the given block index
    double GuessVerificationProgress(CBlockIndex *pindex) {
        if (pindex==NULL)
            return 0.0;

        int64 nNow = time(NULL);

        double fWorkBefore = 0.0; // Amount of work done before pindex
        double fWorkAfter = 0.0;  // Amount of work left after pindex (estimated)
        // Work is defined as: 1.0 per transaction before the last checkoint, and
        // fSigcheckVerificationFactor per transaction after.

        const CCheckpointData &data = Checkpoints();

        if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) {
            double nCheapBefore = pindex->nChainTx;
            double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx;
            double nExpensiveAfter = (nNow - data.nTimeLastCheckpoint)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore;
            fWorkAfter = nCheapAfter + nExpensiveAfter*fSigcheckVerificationFactor;
        } else {
            double nCheapBefore = data.nTransactionsLastCheckpoint;
            double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint;
            double nExpensiveAfter = (nNow - pindex->nTime)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore + nExpensiveBefore*fSigcheckVerificationFactor;
            fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor;
        }

        return fWorkBefore / (fWorkBefore + fWorkAfter);
    }

    int GetTotalBlocksEstimate()
    {
        if (!GetBoolArg("-checkpoints", true))
            return 0;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (!GetBoolArg("-checkpoints", true))
            return NULL;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    //
    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    //
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        ( 11111, uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
        ( 33333, uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6"))
        ( 68555, uint256("0x00000000001e1b4903550a0b96e9a9405c8a95f387162e4944e8d9fbe501cd6a"))
        ( 70567, uint256("0x00000000006a49b14bcf27462068f1264c961f11fa2e0eddd2be0791e1d4124a"))
        ( 74000, uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))
        (105000, uint256("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97"))
        (118000, uint256("0x000000000000774a7f8a7a12dc906ddb9e17e75d684f15e00f8767f9e8f36553"))
        (134444, uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))
        (140700, uint256("0x000000000000033b512028abb90e1626d8b346fd0ed598ac0a3c371138dce2bd"))
        (168000, uint256("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"))
        ;

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (fTestNet) return true; // Testnet has no checkpoints

        MapCheckpoints::const_iterator i = mapCheckpoints.find(nHeight);
        if (i == mapCheckpoints.end()) return true;
        return hash == i->second;
    }

    int GetTotalBlocksEstimate()
    {
        if (fTestNet) return 0;

        return mapCheckpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (fTestNet) return NULL;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, mapCheckpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<commit_msg>Add a testnet checkpoint at block 546<commit_after>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    //
    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    //
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        ( 11111, uint256("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d"))
        ( 33333, uint256("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6"))
        ( 68555, uint256("0x00000000001e1b4903550a0b96e9a9405c8a95f387162e4944e8d9fbe501cd6a"))
        ( 70567, uint256("0x00000000006a49b14bcf27462068f1264c961f11fa2e0eddd2be0791e1d4124a"))
        ( 74000, uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))
        (105000, uint256("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97"))
        (118000, uint256("0x000000000000774a7f8a7a12dc906ddb9e17e75d684f15e00f8767f9e8f36553"))
        (134444, uint256("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe"))
        (140700, uint256("0x000000000000033b512028abb90e1626d8b346fd0ed598ac0a3c371138dce2bd"))
        (168000, uint256("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763"))
        ;

    static MapCheckpoints mapCheckpointsTestnet =
        boost::assign::map_list_of
        ( 546, uint256("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70"))
        ;

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints);

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    int GetTotalBlocksEstimate()
    {
        MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints);

        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        MapCheckpoints& checkpoints = (fTestNet ? mapCheckpointsTestnet : mapCheckpoints);

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "txdb.h"
#include "main.h"
#include "uint256.h"

static const int nCheckpointSpan = 100;

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    //
    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    //
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        (0,	Params().HashGenesisBlock() )
        (14, uint256("0xeb1a88f40f84c13d061a4ededd50f03977cb815f459b44f0acf8bbc3593cd57e"))
        (38, uint256("0xdb2420ff33b119de3bf0eda27c3e4653aa13a63b21009fb2412b3e45dce9a136"))
        (776, uint256("0x19fae8ae0a8c77a239ab8551b57f02cf0ac584a6eaab2b4cc9195745839b24b6"))
        (1863, uint256("0xb9ca005de3783c7be996fc95901394dd08a2213e480015f32ef671e9ed47c7b1"))
        (2578, uint256("0x2984f39527006fe0206a0ae76717f7f193b3007e61cb39e9befab3902c74bb2b"))
        (4381, uint256("0x2e52f5d4bd18f4a413697dfd4913728bfb2a2f680377d7096f31c1399df0ece7"))
        (6347, uint256("0x256b0d65bf31f0a1a2cdaefae07e1b832b8bfe339248af070338a85880cf6f8d"))
        (9139, uint256("0x01d892847b2c609ea2ff06c804fc36cf784da590ca5657a0661970ddc2ff61d2"))
        (13782, uint256("0xe0be7d54614fb55329e8a0a9d2865da0ccca54d032fbc30d3a551644d8be9292"))
        (15420, uint256("0x2a592c35d8b7e26a8d642f2b3e27fb586884b5f12fee6f52b09a1fea5edf2fa1"))
        (19909, uint256("0xf9c933d941b39698dea5078bd5270cc4af0af11b6302c51ca87cf2a13c1cafdc"))
        (24938, uint256("0xb33bd09e56e696e5e0547845c9646d2cefc04ef25e1b90bb9018d9fb89f788da"))
        (28308, uint256("0x77b1e4d7a29655dc33c38d32fa833407f5ad59c7dee76fcc78231387e7311360"))
        (32000, uint256("0x17f909ef335c27bf44655377622927122c5b6824815a867d52cd31d5aaac2873"))
        (48398, uint256("0xdfe376d27cf8c6f11beaa29f4a3966f1011847b9af91ff81fbe69fc03178294b"))
    ;

    // TestNet has no checkpoints
    static MapCheckpoints mapCheckpointsTestnet;

    bool CheckHardened(int nHeight, const uint256& hash)
    {
        MapCheckpoints& checkpoints = (TestNet() ? mapCheckpointsTestnet : mapCheckpoints);

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    int GetTotalBlocksEstimate()
    {
        MapCheckpoints& checkpoints = (TestNet() ? mapCheckpointsTestnet : mapCheckpoints);

        if (checkpoints.empty())
            return 0;
        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        MapCheckpoints& checkpoints = (TestNet() ? mapCheckpointsTestnet : mapCheckpoints);

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }

    // Automatically select a suitable sync-checkpoint
    const CBlockIndex* AutoSelectSyncCheckpoint()
    {
        const CBlockIndex *pindex = pindexBest;
        // Search backward for a block within max span and maturity window
        while (pindex->pprev && pindex->nHeight + nCheckpointSpan > pindexBest->nHeight)
            pindex = pindex->pprev;
        return pindex;
    }

    // Check against synchronized checkpoint
    bool CheckSync(int nHeight)
    {
        const CBlockIndex* pindexSync = AutoSelectSyncCheckpoint();
        if (nHeight <= pindexSync->nHeight){
            return false;
        }
        return true;
    }
}
<commit_msg>Checkpoint block 71320 to main nodes & exchanges<commit_after>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "txdb.h"
#include "main.h"
#include "uint256.h"

static const int nCheckpointSpan = 100;

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    //
    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    //
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        (0,	Params().HashGenesisBlock() )
        (14, uint256("0xeb1a88f40f84c13d061a4ededd50f03977cb815f459b44f0acf8bbc3593cd57e"))
        (38, uint256("0xdb2420ff33b119de3bf0eda27c3e4653aa13a63b21009fb2412b3e45dce9a136"))
        (776, uint256("0x19fae8ae0a8c77a239ab8551b57f02cf0ac584a6eaab2b4cc9195745839b24b6"))
        (1863, uint256("0xb9ca005de3783c7be996fc95901394dd08a2213e480015f32ef671e9ed47c7b1"))
        (2578, uint256("0x2984f39527006fe0206a0ae76717f7f193b3007e61cb39e9befab3902c74bb2b"))
        (4381, uint256("0x2e52f5d4bd18f4a413697dfd4913728bfb2a2f680377d7096f31c1399df0ece7"))
        (6347, uint256("0x256b0d65bf31f0a1a2cdaefae07e1b832b8bfe339248af070338a85880cf6f8d"))
        (9139, uint256("0x01d892847b2c609ea2ff06c804fc36cf784da590ca5657a0661970ddc2ff61d2"))
        (13782, uint256("0xe0be7d54614fb55329e8a0a9d2865da0ccca54d032fbc30d3a551644d8be9292"))
        (15420, uint256("0x2a592c35d8b7e26a8d642f2b3e27fb586884b5f12fee6f52b09a1fea5edf2fa1"))
        (19909, uint256("0xf9c933d941b39698dea5078bd5270cc4af0af11b6302c51ca87cf2a13c1cafdc"))
        (24938, uint256("0xb33bd09e56e696e5e0547845c9646d2cefc04ef25e1b90bb9018d9fb89f788da"))
        (28308, uint256("0x77b1e4d7a29655dc33c38d32fa833407f5ad59c7dee76fcc78231387e7311360"))
        (32000, uint256("0x17f909ef335c27bf44655377622927122c5b6824815a867d52cd31d5aaac2873"))
        (48398, uint256("0xdfe376d27cf8c6f11beaa29f4a3966f1011847b9af91ff81fbe69fc03178294b"))
        (71320, uint256("0x4298a1d06c0effb8a6f15205bb5e6d7c6ea3d6ef68a16a40ef9480c49a3cf212"))
    ;

    // TestNet has no checkpoints
    static MapCheckpoints mapCheckpointsTestnet;

    bool CheckHardened(int nHeight, const uint256& hash)
    {
        MapCheckpoints& checkpoints = (TestNet() ? mapCheckpointsTestnet : mapCheckpoints);

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    int GetTotalBlocksEstimate()
    {
        MapCheckpoints& checkpoints = (TestNet() ? mapCheckpointsTestnet : mapCheckpoints);

        if (checkpoints.empty())
            return 0;
        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        MapCheckpoints& checkpoints = (TestNet() ? mapCheckpointsTestnet : mapCheckpoints);

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }

    // Automatically select a suitable sync-checkpoint
    const CBlockIndex* AutoSelectSyncCheckpoint()
    {
        const CBlockIndex *pindex = pindexBest;
        // Search backward for a block within max span and maturity window
        while (pindex->pprev && pindex->nHeight + nCheckpointSpan > pindexBest->nHeight)
            pindex = pindex->pprev;
        return pindex;
    }

    // Check against synchronized checkpoint
    bool CheckSync(int nHeight)
    {
        const CBlockIndex* pindexSync = AutoSelectSyncCheckpoint();
        if (nHeight <= pindexSync->nHeight){
            return false;
        }
        return true;
    }
}
<|endoftext|>


<commit_before>/*!
  \copyright (c) RDO-Team, 2011
  \file      rdofile.cpp
  \authors   Урусов Андрей (rdo@rk9.bmstu.ru)
  \authors   Пройдаков Евгений (lord.tiran@gmail.com)
  \date      07.11.2020
  \brief
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
// ----------------------------------------------------------------------- PLATFORM
#include "utils/platform.h"
// ----------------------------------------------------------------------- INCLUDES
#ifdef COMPILER_VISUAL_STUDIO
#   include <Windows.h>
#   include <io.h>
#else
#   include <unistd.h>
#endif // COMPILER_VISUAL_STUDIO
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/uuid/uuid_generators.hpp>
// ----------------------------------------------------------------------- SYNOPSIS
#include "utils/rdofile.h"
#include "utils/rdocommon.h"
#include "utils/rdolocale.h"
// --------------------------------------------------------------------------------

OPEN_RDO_NAMESPACE

rbool File::create(CREF(tstring) name)
{
	return create(name, "");
}

rbool File::create(CREF(tstring) name, CREF(tstring) content)
{
	boost::filesystem::fstream file(rdo::locale::convertToWStr(name).c_str(), std::ios::out | std::ios::binary);
	file << content << std::endl;
	file.close();
	return true;
}

rbool File::exist(CREF(tstring) name)
{
	return  boost::filesystem::exists(rdo::locale::convertToWStr(name));
}

rbool File::read_only(CREF(tstring) name)
{
#ifdef COMPILER_VISUAL_STUDIO
	return _access(name.c_str(), 04) == 0 && _access(name.c_str(), 06) == -1;
#endif  // COMPILER_VISUAL_STUDIO
#ifdef COMPILER_GCC
	return access(name.c_str(), R_OK) == 0 && access(name.c_str(), W_OK) == -1;
#endif // COMPILER_GCC
}

rbool File::unlink(CREF(tstring) name)
{
	return boost::filesystem::remove(rdo::locale::convertToWStr(name));
}

rbool File::splitpath(CREF(tstring) name, REF(tstring) fileDir, REF(tstring) fileName, REF(tstring) fileExt)
{
	boost::filesystem::path from(name);
	boost::filesystem::path parentDir(from.parent_path());
	boost::filesystem::path rootName      = parentDir.root_name();
	boost::filesystem::path rootDirectory = parentDir.root_directory();
	if ((rootName.empty() && rootDirectory.empty()) || parentDir != (rootName / rootDirectory))
	{
		parentDir /= boost::filesystem::path("/").make_preferred();
	}

	fileDir  = parentDir.string();
	fileName = from.stem().string();
	fileExt  = from.extension().string();

	return true;
}

tstring File::getTempFileName()
{
#ifdef COMPILER_VISUAL_STUDIO
	const ruint BUFSIZE = 4096;
	tchar lpPathBuffer[BUFSIZE];

	if (::GetTempPath(BUFSIZE, lpPathBuffer) == 0)
	{
		return tstring();
	}
	tchar szTempName[MAX_PATH];
	if (::GetTempFileName(lpPathBuffer, NULL, 0, szTempName) == 0)
	{
		return tstring();
	}
	return szTempName;
#endif // COMPILER_VISUAL_STUDIO
#ifdef COMPILER_GCC
	boost::uuids::random_generator random_gen;
	tstring tempFileName = tstring("/tmp/rdo_temp_file_num_") + boost::uuids::to_string(random_gen());
	create(tempFileName);
	return tempFileName;
#endif // COMPILER_GCC
}

tstring File::extractFilePath(CREF(tstring) fileName)
{
	boost::filesystem::path fullFileName(fileName);
	tstring result = (fullFileName.make_preferred().parent_path() / boost::filesystem::path("/").make_preferred()).string();
	return result;
}

rbool File::trimLeft(CREF(tstring) name)
{
	boost::filesystem::ifstream inputStream(rdo::locale::convertToWStr(name).c_str(), std::ios::binary);
	std::stringstream sstream;

	if (!inputStream.good())
	{
		return false;
	}

	rbool empty = true;
	while (!inputStream.eof())
	{
		char byte;
		inputStream.get(byte);

		if (empty)
		{
			if (byte != ' ' && byte != '\t' && byte != '\n' && byte != '\r')
			{
				empty = false;
			}
		}

		if (!empty)
		{
			sstream.write(&byte, 1);
		}
	}

	inputStream.close();

	boost::filesystem::path to(name);

	try
	{
		if (!boost::filesystem::remove(to))
		{
			return false;
		}
		boost::filesystem::ofstream outStream(name.c_str(), std::ios::binary);
		outStream << sstream.str();
	}
	catch (CREF(boost::system::error_code))
	{
		return false;
	}
	return true;
}

CLOSE_RDO_NAMESPACE
<commit_msg> - исправлен слеш<commit_after>/*!
  \copyright (c) RDO-Team, 2011
  \file      rdofile.cpp
  \authors   Урусов Андрей (rdo@rk9.bmstu.ru)
  \authors   Пройдаков Евгений (lord.tiran@gmail.com)
  \date      07.11.2020
  \brief
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
// ----------------------------------------------------------------------- PLATFORM
#include "utils/platform.h"
// ----------------------------------------------------------------------- INCLUDES
#ifdef COMPILER_VISUAL_STUDIO
#   include <Windows.h>
#   include <io.h>
#else
#   include <unistd.h>
#endif // COMPILER_VISUAL_STUDIO
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/uuid/uuid_generators.hpp>
// ----------------------------------------------------------------------- SYNOPSIS
#include "utils/rdofile.h"
#include "utils/rdocommon.h"
#include "utils/rdolocale.h"
// --------------------------------------------------------------------------------

OPEN_RDO_NAMESPACE

rbool File::create(CREF(tstring) name)
{
	return create(name, "");
}

rbool File::create(CREF(tstring) name, CREF(tstring) content)
{
	boost::filesystem::fstream file(rdo::locale::convertToWStr(name).c_str(), std::ios::out | std::ios::binary);
	file << content << std::endl;
	file.close();
	return true;
}

rbool File::exist(CREF(tstring) name)
{
	return  boost::filesystem::exists(rdo::locale::convertToWStr(name));
}

rbool File::read_only(CREF(tstring) name)
{
#ifdef COMPILER_VISUAL_STUDIO
	return _access(name.c_str(), 04) == 0 && _access(name.c_str(), 06) == -1;
#endif  // COMPILER_VISUAL_STUDIO
#ifdef COMPILER_GCC
	return access(name.c_str(), R_OK) == 0 && access(name.c_str(), W_OK) == -1;
#endif // COMPILER_GCC
}

rbool File::unlink(CREF(tstring) name)
{
	return boost::filesystem::remove(rdo::locale::convertToWStr(name));
}

rbool File::splitpath(CREF(tstring) name, REF(tstring) fileDir, REF(tstring) fileName, REF(tstring) fileExt)
{
	boost::filesystem::path from(name);
	boost::filesystem::path parentDir(from.parent_path());
	boost::filesystem::path rootName      = parentDir.root_name();
	boost::filesystem::path rootDirectory = parentDir.root_directory();
	if ((rootName.empty() && rootDirectory.empty()) || parentDir != (rootName / rootDirectory))
	{
		parentDir /= boost::filesystem::path("/");
	}

	fileDir  = parentDir.make_preferred().string();
	fileName = from.stem().string();
	fileExt  = from.extension().string();

	return true;
}

tstring File::getTempFileName()
{
#ifdef COMPILER_VISUAL_STUDIO
	const ruint BUFSIZE = 4096;
	tchar lpPathBuffer[BUFSIZE];

	if (::GetTempPath(BUFSIZE, lpPathBuffer) == 0)
	{
		return tstring();
	}
	tchar szTempName[MAX_PATH];
	if (::GetTempFileName(lpPathBuffer, NULL, 0, szTempName) == 0)
	{
		return tstring();
	}
	return szTempName;
#endif // COMPILER_VISUAL_STUDIO
#ifdef COMPILER_GCC
	boost::uuids::random_generator random_gen;
	tstring tempFileName = tstring("/tmp/rdo_temp_file_num_") + boost::uuids::to_string(random_gen());
	create(tempFileName);
	return tempFileName;
#endif // COMPILER_GCC
}

tstring File::extractFilePath(CREF(tstring) fileName)
{
	boost::filesystem::path fullFileName(fileName);
	tstring result = (fullFileName.make_preferred().parent_path() / boost::filesystem::path("/").make_preferred()).string();
	return result;
}

rbool File::trimLeft(CREF(tstring) name)
{
	boost::filesystem::ifstream inputStream(rdo::locale::convertToWStr(name).c_str(), std::ios::binary);
	std::stringstream sstream;

	if (!inputStream.good())
	{
		return false;
	}

	rbool empty = true;
	while (!inputStream.eof())
	{
		char byte;
		inputStream.get(byte);

		if (empty)
		{
			if (byte != ' ' && byte != '\t' && byte != '\n' && byte != '\r')
			{
				empty = false;
			}
		}

		if (!empty)
		{
			sstream.write(&byte, 1);
		}
	}

	inputStream.close();

	boost::filesystem::path to(name);

	try
	{
		if (!boost::filesystem::remove(to))
		{
			return false;
		}
		boost::filesystem::ofstream outStream(name.c_str(), std::ios::binary);
		outStream << sstream.str();
	}
	catch (CREF(boost::system::error_code))
	{
		return false;
	}
	return true;
}

CLOSE_RDO_NAMESPACE
<|endoftext|>


<commit_before>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "txdb.h"
#include "main.h"
#include "uint256.h"

static const int nCheckpointSpan = 500;

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    //
    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    //
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        ( 0,   uint256("0x00000393a7de08ce23b3882ae7b5c1567e83bda4849ed24b52610a9b2541c6c9") ) // genesis
        ( 10000,   uint256("0x0000000000063417ad195c561ec8b6b894211c6d3fe122e797dc77e6d0ade650") ) // end of PoW
        ( 300000,   uint256("0x062b8908da998ae7df5b7b805fcc8967a9697ec720ac3afcf2e6d20ab90914cc") )
        ( 400000,   uint256("0xc00ba4a72b66085cb573c7b1d1a34732eb2a10d1a5d2df9db5629c2d50593d84") )
        ( 500000,   uint256("0x1a7fca1992590ac712252afa566df72560b2802a5661e5f37fe8ff661a8107a6") )
        ( 1000000,   uint256("0xa4ce3f7c12eccd78c797d29be6e5ac0ceed6685854970db7845a144461be5aab") )
        ( 1500000,   uint256("0xd7e5029ca9befa88d59b185701818219ec3ec0a1ef73188d39edaef287c044b5") )
        ( 1800000,   uint256("0xd815ae37bce7e01407fd31b7e56ea53a83241a0b243793246491133e8af7ccf5") )
        ( 2000000,   uint256("0x1bdb357438611a9b0c38270977294a5b597645e85a1d8e744f08afdd0244558f") )
        ( 2153782,   uint256("0x65ebd05b0f53743c82447e1451d3168c5e06df81396afa95dc296cbd78eebc9e") )
        ( 2217538,   uint256("0xf7e7e290f5d1ca707630b78f8f33cb89f58a427ddc48f3ba99584a4f35cd8aa6") )
        ( 2261540,   uint256("0x650bac3288e6aa452a12bc8f874ffce6b1fc44ed0e80d20aca9df4b0bacff97d") )
        ( 2351393,   uint256("0x96cd4d12a00c26139ba7be246f23f7a8ec3b72ff6901600d5662d5a7bc104faa") )
        ( 2401111,   uint256("0x040304917804bf41efd36b9a3a7b3588005fb04903176dbff58ebc970095c7bf") )
        ( 2523564,   uint256("0xf60b1f44a71b023035fcc1065314c6c30a50a100816c4cf358c651fbd6214f9a") )
        ( 2583614,   uint256("0x6d1b60719fcc44374b1f3eee81bc0fb3638bc45b66e800916e891b3868d2ddf9") )
        ( 2751396,   uint256("0x3af3493c1af4a3468da1a134e9ebb99c2e48c7c09d4c2be528f67f8298a52350") )
        ( 2875510,   uint256("0xe72106a8a210338c3291d78be3782162de16ce270635adc336bbd2b2c441c4d3") )
    ;

    // TestNet has no checkpoints
    static MapCheckpoints mapCheckpointsTestnet;

    bool CheckHardened(int nHeight, const uint256& hash)
    {
        MapCheckpoints& checkpoints = (TestNet() ? mapCheckpointsTestnet : mapCheckpoints);

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    int GetTotalBlocksEstimate()
    {
        MapCheckpoints& checkpoints = (TestNet() ? mapCheckpointsTestnet : mapCheckpoints);

        if (checkpoints.empty())
            return 0;
        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        MapCheckpoints& checkpoints = (TestNet() ? mapCheckpointsTestnet : mapCheckpoints);

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }

    // Automatically select a suitable sync-checkpoint
    const CBlockIndex* AutoSelectSyncCheckpoint()
    {
        const CBlockIndex *pindex = pindexBest;
        // Search backward for a block within max span and maturity window
        while (pindex->pprev && pindex->nHeight + nCheckpointSpan > pindexBest->nHeight)
            pindex = pindex->pprev;
        return pindex;
    }

    // Check against synchronized checkpoint
    bool CheckSync(int nHeight)
    {
        const CBlockIndex* pindexSync = AutoSelectSyncCheckpoint();

        if (nHeight <= pindexSync->nHeight)
            return false;
        return true;
    }
}
<commit_msg>Add CP at block 3057273<commit_after>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "txdb.h"
#include "main.h"
#include "uint256.h"

static const int nCheckpointSpan = 500;

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    //
    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    //
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        ( 0,   uint256("0x00000393a7de08ce23b3882ae7b5c1567e83bda4849ed24b52610a9b2541c6c9") ) // genesis
        ( 10000,   uint256("0x0000000000063417ad195c561ec8b6b894211c6d3fe122e797dc77e6d0ade650") ) // end of PoW
        ( 300000,   uint256("0x062b8908da998ae7df5b7b805fcc8967a9697ec720ac3afcf2e6d20ab90914cc") )
        ( 400000,   uint256("0xc00ba4a72b66085cb573c7b1d1a34732eb2a10d1a5d2df9db5629c2d50593d84") )
        ( 500000,   uint256("0x1a7fca1992590ac712252afa566df72560b2802a5661e5f37fe8ff661a8107a6") )
        ( 1000000,   uint256("0xa4ce3f7c12eccd78c797d29be6e5ac0ceed6685854970db7845a144461be5aab") )
        ( 1500000,   uint256("0xd7e5029ca9befa88d59b185701818219ec3ec0a1ef73188d39edaef287c044b5") )
        ( 1800000,   uint256("0xd815ae37bce7e01407fd31b7e56ea53a83241a0b243793246491133e8af7ccf5") )
        ( 2000000,   uint256("0x1bdb357438611a9b0c38270977294a5b597645e85a1d8e744f08afdd0244558f") )
        ( 2153782,   uint256("0x65ebd05b0f53743c82447e1451d3168c5e06df81396afa95dc296cbd78eebc9e") )
        ( 2217538,   uint256("0xf7e7e290f5d1ca707630b78f8f33cb89f58a427ddc48f3ba99584a4f35cd8aa6") )
        ( 2261540,   uint256("0x650bac3288e6aa452a12bc8f874ffce6b1fc44ed0e80d20aca9df4b0bacff97d") )
        ( 2351393,   uint256("0x96cd4d12a00c26139ba7be246f23f7a8ec3b72ff6901600d5662d5a7bc104faa") )
        ( 2401111,   uint256("0x040304917804bf41efd36b9a3a7b3588005fb04903176dbff58ebc970095c7bf") )
        ( 2523564,   uint256("0xf60b1f44a71b023035fcc1065314c6c30a50a100816c4cf358c651fbd6214f9a") )
        ( 2583614,   uint256("0x6d1b60719fcc44374b1f3eee81bc0fb3638bc45b66e800916e891b3868d2ddf9") )
        ( 2751396,   uint256("0x3af3493c1af4a3468da1a134e9ebb99c2e48c7c09d4c2be528f67f8298a52350") )
        ( 2875510,   uint256("0xe72106a8a210338c3291d78be3782162de16ce270635adc336bbd2b2c441c4d3") )
        ( 3057273,   uint256("0xef74beb7166632570a33924e34f77f9df0572ddc0d311bbc7de6bc3851a9f7bc") )
    ;

    // TestNet has no checkpoints
    static MapCheckpoints mapCheckpointsTestnet;

    bool CheckHardened(int nHeight, const uint256& hash)
    {
        MapCheckpoints& checkpoints = (TestNet() ? mapCheckpointsTestnet : mapCheckpoints);

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    int GetTotalBlocksEstimate()
    {
        MapCheckpoints& checkpoints = (TestNet() ? mapCheckpointsTestnet : mapCheckpoints);

        if (checkpoints.empty())
            return 0;
        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        MapCheckpoints& checkpoints = (TestNet() ? mapCheckpointsTestnet : mapCheckpoints);

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }

    // Automatically select a suitable sync-checkpoint
    const CBlockIndex* AutoSelectSyncCheckpoint()
    {
        const CBlockIndex *pindex = pindexBest;
        // Search backward for a block within max span and maturity window
        while (pindex->pprev && pindex->nHeight + nCheckpointSpan > pindexBest->nHeight)
            pindex = pindex->pprev;
        return pindex;
    }

    // Check against synchronized checkpoint
    bool CheckSync(int nHeight)
    {
        const CBlockIndex* pindexSync = AutoSelectSyncCheckpoint();

        if (nHeight <= pindexSync->nHeight)
            return false;
        return true;
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    // How many times we expect transactions after the last checkpoint to
    // be slower. This number is a compromise, as it can't be accurate for
    // every system. When reindexing from a fast disk with a slow CPU, it
    // can be up to 20, while when downloading from a slow network with a
    // fast multicore CPU, it won't be much higher than 1.
    static const double fSigcheckVerificationFactor = 5.0;

    struct CCheckpointData {
        const MapCheckpoints *mapCheckpoints;
        int64 nTimeLastCheckpoint;
        int64 nTransactionsLastCheckpoint;
        double fTransactionsPerDay;
    };

    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        ( 0,      uint256("0x6d39f28ad01a7edd3e2374b355cf8c7f8dbc1c5e4596ad3642fa6d10c2599217"))
        ( 25000,  uint256("0x99ffd2f7230224586c61deb459fa1cde94bda2876aed8bb791f4e3b5d485ef59"))
        ( 40000,  uint256("0xbec732146705189352bb0007c4a26345a3ddf0eac1e8721e2fbb121b7d7c04b6"))
        ( 50000,  uint256("0x08ac154d59f223c3c6912a03ba44487bedabd27147e0da05a7aa339fcc84e011"))
        ( 75000,  uint256("0xd5e057b7a45fe9eb72326b5e7d7caaf31e0fd8f016425e41d8f88c9c196417c5"))
        ( 100000, uint256("0xde49a9254ea2f01287a8b2f9d97438a52809cfd78d3c5bcc13fa529a07989083"))
        ( 125000, uint256("0x8f817d3fdeb7fbb338d29dc8587a127c34d98617acadfd4248e4f9dfd23fd672"))
        ( 150000, uint256("0x14eac37f76d8be510df10526e3ff053aa472d7f2e507ea3562a74b60e7174961"))
        ( 175000, uint256("0x9d7d7db04e9dc15aa06abb45346b9a96a9136c76b6d52465eea5c3f01f861ad7"))
        ;
    static const CCheckpointData data = {
        &mapCheckpoints,
        1411766077, // * UNIX timestamp of last checkpoint block
        4896865,    // * total number of transactions between genesis and last checkpoint
                    //   (the tx=... number in the SetBestChain debug.log lines)
        7000.0     // * estimated number of transactions per day after checkpoint
    };

    static MapCheckpoints mapCheckpointsTestnet =
        boost::assign::map_list_of
        (   546, uint256("0xa0fea99a6897f531600c8ae53367b126824fd6a847b2b2b73817a95b8e27e602"))
        ;
    static const CCheckpointData dataTestnet = {
        &mapCheckpointsTestnet,
        1365458829,
        547,
        576
    };

    const CCheckpointData &Checkpoints() {
        if (fTestNet)
            return dataTestnet;
        else
            return data;
    }

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (!GetBoolArg("-checkpoints", true))
            return true;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    // Guess how far we are in the verification process at the given block index
    double GuessVerificationProgress(CBlockIndex *pindex) {
        if (pindex==NULL)
            return 0.0;

        int64 nNow = time(NULL);

        double fWorkBefore = 0.0; // Amount of work done before pindex
        double fWorkAfter = 0.0;  // Amount of work left after pindex (estimated)
        // Work is defined as: 1.0 per transaction before the last checkoint, and
        // fSigcheckVerificationFactor per transaction after.

        const CCheckpointData &data = Checkpoints();

        if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) {
            double nCheapBefore = pindex->nChainTx;
            double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx;
            double nExpensiveAfter = (nNow - data.nTimeLastCheckpoint)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore;
            fWorkAfter = nCheapAfter + nExpensiveAfter*fSigcheckVerificationFactor;
        } else {
            double nCheapBefore = data.nTransactionsLastCheckpoint;
            double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint;
            double nExpensiveAfter = (nNow - pindex->nTime)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore + nExpensiveBefore*fSigcheckVerificationFactor;
            fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor;
        }

        return fWorkBefore / (fWorkBefore + fWorkAfter);
    }

    int GetTotalBlocksEstimate()
    {
        if (!GetBoolArg("-checkpoints", true))
            return 0;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (!GetBoolArg("-checkpoints", true))
            return NULL;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<commit_msg>Updated checkpoints<commit_after>// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    // How many times we expect transactions after the last checkpoint to
    // be slower. This number is a compromise, as it can't be accurate for
    // every system. When reindexing from a fast disk with a slow CPU, it
    // can be up to 20, while when downloading from a slow network with a
    // fast multicore CPU, it won't be much higher than 1.
    static const double fSigcheckVerificationFactor = 5.0;

    struct CCheckpointData {
        const MapCheckpoints *mapCheckpoints;
        int64 nTimeLastCheckpoint;
        int64 nTransactionsLastCheckpoint;
        double fTransactionsPerDay;
    };

    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        ( 0,      uint256("0x6d39f28ad01a7edd3e2374b355cf8c7f8dbc1c5e4596ad3642fa6d10c2599217"))
        ( 25000,  uint256("0x99ffd2f7230224586c61deb459fa1cde94bda2876aed8bb791f4e3b5d485ef59"))
        ( 40000,  uint256("0xbec732146705189352bb0007c4a26345a3ddf0eac1e8721e2fbb121b7d7c04b6"))
        ( 50000,  uint256("0x08ac154d59f223c3c6912a03ba44487bedabd27147e0da05a7aa339fcc84e011"))
        ( 75000,  uint256("0xd5e057b7a45fe9eb72326b5e7d7caaf31e0fd8f016425e41d8f88c9c196417c5"))
        ( 100000, uint256("0xde49a9254ea2f01287a8b2f9d97438a52809cfd78d3c5bcc13fa529a07989083"))
        ( 125000, uint256("0x8f817d3fdeb7fbb338d29dc8587a127c34d98617acadfd4248e4f9dfd23fd672"))
        ( 150000, uint256("0x14eac37f76d8be510df10526e3ff053aa472d7f2e507ea3562a74b60e7174961"))
        ( 175000, uint256("0x9d7d7db04e9dc15aa06abb45346b9a96a9136c76b6d52465eea5c3f01f861ad7"))
        ( 200000, uint256("0x856d56f908ecde89d24ed216978f5b9898000defc15f8dcfac83a3a6eaeea9b9"))
        ( 225000, uint256("0x1ab99f5f8ea110de1a57e128e883b760152dba409c2c1130353edcea67643277"))
        ( 250000, uint256("0x0086da045fd362f346d1e7dcc12fe41e7eca4dc6bcd2515bdec7b7a1383c0ec9"))
        ;
    static const CCheckpointData data = {
        &mapCheckpoints,
        1421000263, // * UNIX timestamp of last checkpoint block
        92000,      // * total number of transactions between genesis and last checkpoint
                    //   (the tx=... number in the SetBestChain debug.log lines)
        150.0       // * estimated number of transactions per day after checkpoint
    };

    static MapCheckpoints mapCheckpointsTestnet =
        boost::assign::map_list_of
        (   546, uint256("0xa0fea99a6897f531600c8ae53367b126824fd6a847b2b2b73817a95b8e27e602"))
        ;
    static const CCheckpointData dataTestnet = {
        &mapCheckpointsTestnet,
        1365458829,
        547,
        576
    };

    const CCheckpointData &Checkpoints() {
        if (fTestNet)
            return dataTestnet;
        else
            return data;
    }

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (!GetBoolArg("-checkpoints", true))
            return true;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        MapCheckpoints::const_iterator i = checkpoints.find(nHeight);
        if (i == checkpoints.end()) return true;
        return hash == i->second;
    }

    // Guess how far we are in the verification process at the given block index
    double GuessVerificationProgress(CBlockIndex *pindex) {
        if (pindex==NULL)
            return 0.0;

        int64 nNow = time(NULL);

        double fWorkBefore = 0.0; // Amount of work done before pindex
        double fWorkAfter = 0.0;  // Amount of work left after pindex (estimated)
        // Work is defined as: 1.0 per transaction before the last checkoint, and
        // fSigcheckVerificationFactor per transaction after.

        const CCheckpointData &data = Checkpoints();

        if (pindex->nChainTx <= data.nTransactionsLastCheckpoint) {
            double nCheapBefore = pindex->nChainTx;
            double nCheapAfter = data.nTransactionsLastCheckpoint - pindex->nChainTx;
            double nExpensiveAfter = (nNow - data.nTimeLastCheckpoint)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore;
            fWorkAfter = nCheapAfter + nExpensiveAfter*fSigcheckVerificationFactor;
        } else {
            double nCheapBefore = data.nTransactionsLastCheckpoint;
            double nExpensiveBefore = pindex->nChainTx - data.nTransactionsLastCheckpoint;
            double nExpensiveAfter = (nNow - pindex->nTime)/86400.0*data.fTransactionsPerDay;
            fWorkBefore = nCheapBefore + nExpensiveBefore*fSigcheckVerificationFactor;
            fWorkAfter = nExpensiveAfter*fSigcheckVerificationFactor;
        }

        return fWorkBefore / (fWorkBefore + fWorkAfter);
    }

    int GetTotalBlocksEstimate()
    {
        if (!GetBoolArg("-checkpoints", true))
            return 0;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        return checkpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (!GetBoolArg("-checkpoints", true))
            return NULL;

        const MapCheckpoints& checkpoints = *Checkpoints().mapCheckpoints;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2012 The Bitcoin developers
// Copyright (c) 2011-2012 Litecoin Developers
// Copyright (c) 2013 Florincoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    //
    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    //
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        (     0, hashGenesisBlock)
        (  8002, uint256("0x73bc3b16d99bbf797f396c9532f80c3b73bb21304280de2efbc5edcb75739234"))
        ( 18001, uint256("0x5a7a4821aa4fc7ee3dea2f8319e9fa4d991a8c6762e79cb624c64e4cf1031582"))
        ( 38002, uint256("0x4962437c6d0a450f44c1e40cd38ff220f8122af1517e1329f1abd07fb7791e40"))
        (160002, uint256("0x478d381c92298614c3a05fb934a4fffc4d3e5b573efbba9b3e8b2ce8d26a0f8f"))
        (208001, uint256("0x2bb3f8b2d5081aefa0af9f5d8de42bd73a5d89eebf78aa7421cd63dc40a56d4c"))
        (270001, uint256("0x74988a3179ae6bbc5986e63f71bafc855202502b07e4d9331015eee82df80860"))
        (290036, uint256("0x145994381e5e4f0e5674adc1ace9a03b670838792f6bd6b650c80466453c2da3"))
        (344665, uint256("0x40fe36d8dec357aa529b6b1d99b2989a37ed8c7b065a0e3345cd15a751b9c1ad"))
        (400236, uint256("0xf9a4b8e21d410539e45ff3f11c28dee8966de7edffc45fd02dd1a5f4e7d4ef38"))
        (415000, uint256("0x16ef8ab98a7300039a5755d5bdc00e31dada9d2f1c440ff7928f43c4ea41c0a8"))
        ;

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (fTestNet) return true; // Testnet has no checkpoints

        MapCheckpoints::const_iterator i = mapCheckpoints.find(nHeight);
        if (i == mapCheckpoints.end()) return true;
        return hash == i->second;
    }

    int GetTotalBlocksEstimate()
    {
        if (fTestNet) return 0;

        return mapCheckpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (fTestNet) return NULL;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, mapCheckpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<commit_msg>Checkpoint<commit_after>// Copyright (c) 2009-2012 The Bitcoin developers
// Copyright (c) 2011-2012 Litecoin Developers
// Copyright (c) 2013 Florincoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <boost/assign/list_of.hpp> // for 'map_list_of()'
#include <boost/foreach.hpp>

#include "checkpoints.h"

#include "main.h"
#include "uint256.h"

namespace Checkpoints
{
    typedef std::map<int, uint256> MapCheckpoints;

    //
    // What makes a good checkpoint block?
    // + Is surrounded by blocks with reasonable timestamps
    //   (no blocks before with a timestamp after, none after with
    //    timestamp before)
    // + Contains no strange transactions
    //
    static MapCheckpoints mapCheckpoints =
        boost::assign::map_list_of
        (     0, hashGenesisBlock)
        (  8002, uint256("0x73bc3b16d99bbf797f396c9532f80c3b73bb21304280de2efbc5edcb75739234"))
        ( 18001, uint256("0x5a7a4821aa4fc7ee3dea2f8319e9fa4d991a8c6762e79cb624c64e4cf1031582"))
        ( 38002, uint256("0x4962437c6d0a450f44c1e40cd38ff220f8122af1517e1329f1abd07fb7791e40"))
        (160002, uint256("0x478d381c92298614c3a05fb934a4fffc4d3e5b573efbba9b3e8b2ce8d26a0f8f"))
        (208001, uint256("0x2bb3f8b2d5081aefa0af9f5d8de42bd73a5d89eebf78aa7421cd63dc40a56d4c"))
        (270001, uint256("0x74988a3179ae6bbc5986e63f71bafc855202502b07e4d9331015eee82df80860"))
        (290036, uint256("0x145994381e5e4f0e5674adc1ace9a03b670838792f6bd6b650c80466453c2da3"))
        (344665, uint256("0x40fe36d8dec357aa529b6b1d99b2989a37ed8c7b065a0e3345cd15a751b9c1ad"))
        (400236, uint256("0xf9a4b8e21d410539e45ff3f11c28dee8966de7edffc45fd02dd1a5f4e7d4ef38"))
        (415000, uint256("0x16ef8ab98a7300039a5755d5bdc00e31dada9d2f1c440ff7928f43c4ea41c0a8"))
        (420937, uint256("0x48a75e4687021ec0dda2031439de50b61933e197a4e1a1185d131cc2b59b8444"))
        ;

    bool CheckBlock(int nHeight, const uint256& hash)
    {
        if (fTestNet) return true; // Testnet has no checkpoints

        MapCheckpoints::const_iterator i = mapCheckpoints.find(nHeight);
        if (i == mapCheckpoints.end()) return true;
        return hash == i->second;
    }

    int GetTotalBlocksEstimate()
    {
        if (fTestNet) return 0;

        return mapCheckpoints.rbegin()->first;
    }

    CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex)
    {
        if (fTestNet) return NULL;

        BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, mapCheckpoints)
        {
            const uint256& hash = i.second;
            std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash);
            if (t != mapBlockIndex.end())
                return t->second;
        }
        return NULL;
    }
}
<|endoftext|>


<commit_before>// Copyright (C) 2010-2016  Lukas Lalinsky
// Distributed under the MIT license, see the LICENSE file for details.

#include <vector>
#include <string>
#include <algorithm>
#include <memory>
#include <cstring>
#include <chromaprint.h>
#include "fingerprinter.h"
#include "fingerprint_compressor.h"
#include "fingerprint_decompressor.h"
#include "fingerprint_matcher.h"
#include "fingerprinter_configuration.h"
#include "base64.h"
#include "simhash.h"
#include "debug.h"

using namespace chromaprint;

struct ChromaprintContextPrivate {
	ChromaprintContextPrivate(int algorithm)
		: algorithm(algorithm),
		  fingerprinter(CreateFingerprinterConfiguration(algorithm)) {}
	int algorithm;
	Fingerprinter fingerprinter;
};

struct ChromaprintMatcherContextPrivate {
	int algorithm = -1;
	std::unique_ptr<FingerprintMatcher> matcher;
	std::vector<uint32_t> fp[2];
};

extern "C" {

#define FAIL_IF(x, msg) if (x) { DEBUG(msg); return 0; }

#define STR(x) #x
#define VERSION_STR(major, minor, patch) \
	STR(major) "." STR(minor) "." STR(patch)

static const char *version_str = VERSION_STR(
	CHROMAPRINT_VERSION_MAJOR,
	CHROMAPRINT_VERSION_MINOR,
	CHROMAPRINT_VERSION_PATCH);

const char *chromaprint_get_version(void)
{
	return version_str;
}

ChromaprintContext *chromaprint_new(int algorithm)
{
	return new ChromaprintContextPrivate(algorithm);
}

void chromaprint_free(ChromaprintContext *ctx)
{
	if (ctx) {
		delete ctx;
	}
}

int chromaprint_set_option(ChromaprintContext *ctx, const char *name, int value)
{
	FAIL_IF(!ctx, "context can't be NULL");
	return ctx->fingerprinter.SetOption(name, value) ? 1 : 0;
}

int chromaprint_start(ChromaprintContext *ctx, int sample_rate, int num_channels)
{
	FAIL_IF(!ctx, "context can't be NULL");
	return ctx->fingerprinter.Start(sample_rate, num_channels) ? 1 : 0;
}

int chromaprint_feed(ChromaprintContext *ctx, const int16_t *data, int length)
{
	FAIL_IF(!ctx, "context can't be NULL");
	ctx->fingerprinter.Consume(data, length);
	return 1;
}

int chromaprint_finish(ChromaprintContext *ctx)
{
	FAIL_IF(!ctx, "context can't be NULL");
	ctx->fingerprinter.Finish();
	return 1;
}

int chromaprint_get_fingerprint(ChromaprintContext *ctx, char **data)
{
	FAIL_IF(!ctx, "context can't be NULL");
	std::string fingerprint = CompressFingerprint(ctx->fingerprinter.GetFingerprint(), ctx->algorithm);
	*data = (char *) malloc(GetBase64EncodedSize(fingerprint.size()) + 1);
	Base64Encode(fingerprint.begin(), fingerprint.end(), *data, true);
	return 1;
}

int chromaprint_get_raw_fingerprint(ChromaprintContext *ctx, uint32_t **data, int *size)
{
	FAIL_IF(!ctx, "context can't be NULL");
	const auto fingerprint = ctx->fingerprinter.GetFingerprint();
	*data = (uint32_t *) malloc(sizeof(uint32_t) * fingerprint.size());
	if (!*data) {
		return 0;
	}
	*size = fingerprint.size();
	std::copy(fingerprint.begin(), fingerprint.end(), *data);
	return 1;
}

int chromaprint_get_fingerprint_hash(ChromaprintContext *ctx, uint32_t *hash)
{
	FAIL_IF(!ctx, "context can't be NULL");
	*hash = SimHash(ctx->fingerprinter.GetFingerprint());
	return 1;
}

int chromaprint_clear_fingerprint(ChromaprintContext *ctx)
{
	FAIL_IF(!ctx, "context can't be NULL");
	ctx->fingerprinter.ClearFingerprint();
	return 1;
}

int chromaprint_encode_fingerprint(const uint32_t *fp, int size, int algorithm, char **encoded_fp, int *encoded_size, int base64)
{
	std::vector<uint32_t> uncompressed(fp, fp + size);
	std::string encoded = CompressFingerprint(uncompressed, algorithm);
	if (base64) {
		encoded = Base64Encode(encoded);
	}
	*encoded_fp = (char *) malloc(encoded.size() + 1);
	*encoded_size = encoded.size();
	std::copy(encoded.data(), encoded.data() + encoded.size() + 1, *encoded_fp);
	return 1;
}

int chromaprint_decode_fingerprint(const char *encoded_fp, int encoded_size, uint32_t **fp, int *size, int *algorithm, int base64)
{
	std::string encoded(encoded_fp, encoded_size);
	if (base64) {
		encoded = Base64Decode(encoded);
	}
	std::vector<uint32_t> uncompressed = DecompressFingerprint(encoded, algorithm);
	*fp = (uint32_t *) malloc(sizeof(uint32_t) * uncompressed.size());
	*size = uncompressed.size();
	std::copy(uncompressed.begin(), uncompressed.end(), *fp);
	return 1;
}

int chromaprint_hash_fingerprint(const uint32_t *fp, int size, uint32_t *hash)
{
	if (fp == NULL || size < 0 || hash == NULL) {
		return 0;
	}
	*hash = SimHash(fp, size);
	return 1;
}

ChromaprintMatcherContext *chromaprint_matcher_new()
{
	return new ChromaprintMatcherContext();
}

void chromaprint_matcher_free(ChromaprintMatcherContext *ctx)
{
	if (ctx) {
		delete ctx;
	}
}

int chromaprint_matcher_set_fingerprint(ChromaprintMatcherContext *ctx, int idx, const char *fp)
{
	FAIL_IF(!ctx, "context can't be NULL");
	FAIL_IF(idx < 0 || idx > 1, "idx can be only 0 or 1");

	int algorithm;
	ctx->fp[idx] = DecompressFingerprint(Base64Decode(fp), &algorithm);

	if (ctx->algorithm == -1) {
		ctx->matcher.reset(new FingerprintMatcher(CreateFingerprinterConfiguration(algorithm)));
	} else {
		FAIL_IF(algorithm != ctx->algorithm, "invalid fingerprint algorithm");
	}

	return 1;
}

int chromaprint_matcher_set_raw_fingerprint(ChromaprintMatcherContext *ctx, int idx, const uint32_t *fp, int size, int algorithm)
{
	FAIL_IF(!ctx, "context can't be NULL");
	FAIL_IF(idx < 0 || idx > 1, "idx can be only 0 or 1");

	if (ctx->algorithm == -1) {
		ctx->matcher.reset(new FingerprintMatcher(CreateFingerprinterConfiguration(algorithm)));
	} else {
		FAIL_IF(algorithm != ctx->algorithm, "invalid fingerprint algorithm");
	}

	ctx->fp[idx].assign(fp, fp + size);
	return 1;
}

int chromaprint_matcher_run(ChromaprintMatcherContext *ctx)
{
	FAIL_IF(!ctx, "context can't be NULL");
	FAIL_IF(ctx->fp[0].empty(), "fingerprint 0 is empty");
	FAIL_IF(ctx->fp[1].empty(), "fingerprint 1 is empty");

	return ctx->matcher->Match(ctx->fp[0], ctx->fp[1]) ? 1 : 0;
}

int chromaprint_matcher_get_num_segments(ChromaprintMatcherContext *ctx, int *num_segments)
{
	FAIL_IF(!ctx, "context can't be NULL");
	FAIL_IF(!num_segments, "num_segments can't be NULL");

	*num_segments = ctx->matcher->segments().size();
	return 1;
}

int chromaprint_matcher_get_segment_position(ChromaprintMatcherContext *ctx, int idx, int *pos1, int *pos2, int *duration)
{
	FAIL_IF(!ctx, "context can't be NULL");

	const auto &segments = ctx->matcher->segments();
	const int num_segments = segments.size();
	FAIL_IF(idx < 0 || idx >= num_segments, "invalid idx");

	*pos1 = segments[idx].pos1;
	*pos2 = segments[idx].pos2;
	*duration = segments[idx].duration;
	return 1;
}

int chromaprint_matcher_get_segment_position_ms(ChromaprintMatcherContext *ctx, int idx, int *pos1, int *pos2, int *duration)
{
	FAIL_IF(!ctx, "context can't be NULL");

	const auto &segments = ctx->matcher->segments();
	const int num_segments = segments.size();
	FAIL_IF(idx < 0 || idx >= num_segments, "invalid idx");

	*pos1 = round(1000 * ctx->matcher->GetHashTime(segments[idx].pos1));
	*pos2 = round(1000 * ctx->matcher->GetHashTime(segments[idx].pos2));
	*duration = round(1000 * ctx->matcher->GetHashTime(segments[idx].duration));
	return 1;
}

int chromaprint_matcher_get_segment_score(ChromaprintMatcherContext *ctx, int idx, int *score)
{
	FAIL_IF(!ctx, "context can't be NULL");

	const auto &segments = ctx->matcher->segments();
	const int num_segments = segments.size();
	FAIL_IF(idx < 0 || idx >= num_segments, "invalid idx");

	*score = segments[idx].public_score();
	return 1;
}

void chromaprint_dealloc(void *ptr)
{
	free(ptr);
}

}; // extern "C"
<commit_msg>Use compressor/decompressor objects in the C API<commit_after>// Copyright (C) 2010-2016  Lukas Lalinsky
// Distributed under the MIT license, see the LICENSE file for details.

#include <vector>
#include <string>
#include <algorithm>
#include <memory>
#include <cstring>
#include <chromaprint.h>
#include "fingerprinter.h"
#include "fingerprint_compressor.h"
#include "fingerprint_decompressor.h"
#include "fingerprint_matcher.h"
#include "fingerprinter_configuration.h"
#include "base64.h"
#include "simhash.h"
#include "debug.h"

using namespace chromaprint;

struct ChromaprintContextPrivate {
	ChromaprintContextPrivate(int algorithm)
		: algorithm(algorithm),
		  fingerprinter(CreateFingerprinterConfiguration(algorithm)) {}
	int algorithm;
	Fingerprinter fingerprinter;
	FingerprintCompressor compressor;
};

struct ChromaprintMatcherContextPrivate {
	int algorithm = -1;
	std::unique_ptr<FingerprintMatcher> matcher;
	std::vector<uint32_t> fp[2];
	FingerprintDecompressor decompressor;
};

extern "C" {

#define FAIL_IF(x, msg) if (x) { DEBUG(msg); return 0; }

#define STR(x) #x
#define VERSION_STR(major, minor, patch) \
	STR(major) "." STR(minor) "." STR(patch)

static const char *version_str = VERSION_STR(
	CHROMAPRINT_VERSION_MAJOR,
	CHROMAPRINT_VERSION_MINOR,
	CHROMAPRINT_VERSION_PATCH);

const char *chromaprint_get_version(void)
{
	return version_str;
}

ChromaprintContext *chromaprint_new(int algorithm)
{
	return new ChromaprintContextPrivate(algorithm);
}

void chromaprint_free(ChromaprintContext *ctx)
{
	if (ctx) {
		delete ctx;
	}
}

int chromaprint_set_option(ChromaprintContext *ctx, const char *name, int value)
{
	FAIL_IF(!ctx, "context can't be NULL");
	return ctx->fingerprinter.SetOption(name, value) ? 1 : 0;
}

int chromaprint_start(ChromaprintContext *ctx, int sample_rate, int num_channels)
{
	FAIL_IF(!ctx, "context can't be NULL");
	return ctx->fingerprinter.Start(sample_rate, num_channels) ? 1 : 0;
}

int chromaprint_feed(ChromaprintContext *ctx, const int16_t *data, int length)
{
	FAIL_IF(!ctx, "context can't be NULL");
	ctx->fingerprinter.Consume(data, length);
	return 1;
}

int chromaprint_finish(ChromaprintContext *ctx)
{
	FAIL_IF(!ctx, "context can't be NULL");
	ctx->fingerprinter.Finish();
	return 1;
}

int chromaprint_get_fingerprint(ChromaprintContext *ctx, char **data)
{
	FAIL_IF(!ctx, "context can't be NULL");
	std::string fingerprint = ctx->compressor.Compress(ctx->fingerprinter.GetFingerprint(), ctx->algorithm);
	*data = (char *) malloc(GetBase64EncodedSize(fingerprint.size()) + 1);
	Base64Encode(fingerprint.begin(), fingerprint.end(), *data, true);
	return 1;
}

int chromaprint_get_raw_fingerprint(ChromaprintContext *ctx, uint32_t **data, int *size)
{
	FAIL_IF(!ctx, "context can't be NULL");
	const auto fingerprint = ctx->fingerprinter.GetFingerprint();
	*data = (uint32_t *) malloc(sizeof(uint32_t) * fingerprint.size());
	if (!*data) {
		return 0;
	}
	*size = fingerprint.size();
	std::copy(fingerprint.begin(), fingerprint.end(), *data);
	return 1;
}

int chromaprint_get_fingerprint_hash(ChromaprintContext *ctx, uint32_t *hash)
{
	FAIL_IF(!ctx, "context can't be NULL");
	*hash = SimHash(ctx->fingerprinter.GetFingerprint());
	return 1;
}

int chromaprint_clear_fingerprint(ChromaprintContext *ctx)
{
	FAIL_IF(!ctx, "context can't be NULL");
	ctx->fingerprinter.ClearFingerprint();
	return 1;
}

int chromaprint_encode_fingerprint(const uint32_t *fp, int size, int algorithm, char **encoded_fp, int *encoded_size, int base64)
{
	std::vector<uint32_t> uncompressed(fp, fp + size);
	std::string encoded = CompressFingerprint(uncompressed, algorithm);
	if (base64) {
		encoded = Base64Encode(encoded);
	}
	*encoded_fp = (char *) malloc(encoded.size() + 1);
	*encoded_size = encoded.size();
	std::copy(encoded.data(), encoded.data() + encoded.size() + 1, *encoded_fp);
	return 1;
}

int chromaprint_decode_fingerprint(const char *encoded_fp, int encoded_size, uint32_t **fp, int *size, int *algorithm, int base64)
{
	std::string encoded(encoded_fp, encoded_size);
	if (base64) {
		encoded = Base64Decode(encoded);
	}
	std::vector<uint32_t> uncompressed = DecompressFingerprint(encoded, algorithm);
	*fp = (uint32_t *) malloc(sizeof(uint32_t) * uncompressed.size());
	*size = uncompressed.size();
	std::copy(uncompressed.begin(), uncompressed.end(), *fp);
	return 1;
}

int chromaprint_hash_fingerprint(const uint32_t *fp, int size, uint32_t *hash)
{
	if (fp == NULL || size < 0 || hash == NULL) {
		return 0;
	}
	*hash = SimHash(fp, size);
	return 1;
}

ChromaprintMatcherContext *chromaprint_matcher_new()
{
	return new ChromaprintMatcherContext();
}

void chromaprint_matcher_free(ChromaprintMatcherContext *ctx)
{
	if (ctx) {
		delete ctx;
	}
}

int chromaprint_matcher_set_fingerprint(ChromaprintMatcherContext *ctx, int idx, const char *fp)
{
	FAIL_IF(!ctx, "context can't be NULL");
	FAIL_IF(idx < 0 || idx > 1, "idx can be only 0 or 1");

	int algorithm;
	ctx->fp[idx] = ctx->decompressor.Decompress(Base64Decode(fp), &algorithm);

	if (ctx->algorithm == -1) {
		ctx->matcher.reset(new FingerprintMatcher(CreateFingerprinterConfiguration(algorithm)));
	} else {
		FAIL_IF(algorithm != ctx->algorithm, "invalid fingerprint algorithm");
	}

	return 1;
}

int chromaprint_matcher_set_raw_fingerprint(ChromaprintMatcherContext *ctx, int idx, const uint32_t *fp, int size, int algorithm)
{
	FAIL_IF(!ctx, "context can't be NULL");
	FAIL_IF(idx < 0 || idx > 1, "idx can be only 0 or 1");

	if (ctx->algorithm == -1) {
		ctx->matcher.reset(new FingerprintMatcher(CreateFingerprinterConfiguration(algorithm)));
	} else {
		FAIL_IF(algorithm != ctx->algorithm, "invalid fingerprint algorithm");
	}

	ctx->fp[idx].assign(fp, fp + size);
	return 1;
}

int chromaprint_matcher_run(ChromaprintMatcherContext *ctx)
{
	FAIL_IF(!ctx, "context can't be NULL");
	FAIL_IF(ctx->fp[0].empty(), "fingerprint 0 is empty");
	FAIL_IF(ctx->fp[1].empty(), "fingerprint 1 is empty");

	return ctx->matcher->Match(ctx->fp[0], ctx->fp[1]) ? 1 : 0;
}

int chromaprint_matcher_get_num_segments(ChromaprintMatcherContext *ctx, int *num_segments)
{
	FAIL_IF(!ctx, "context can't be NULL");
	FAIL_IF(!num_segments, "num_segments can't be NULL");

	*num_segments = ctx->matcher->segments().size();
	return 1;
}

int chromaprint_matcher_get_segment_position(ChromaprintMatcherContext *ctx, int idx, int *pos1, int *pos2, int *duration)
{
	FAIL_IF(!ctx, "context can't be NULL");

	const auto &segments = ctx->matcher->segments();
	const int num_segments = segments.size();
	FAIL_IF(idx < 0 || idx >= num_segments, "invalid idx");

	*pos1 = segments[idx].pos1;
	*pos2 = segments[idx].pos2;
	*duration = segments[idx].duration;
	return 1;
}

int chromaprint_matcher_get_segment_position_ms(ChromaprintMatcherContext *ctx, int idx, int *pos1, int *pos2, int *duration)
{
	FAIL_IF(!ctx, "context can't be NULL");

	const auto &segments = ctx->matcher->segments();
	const int num_segments = segments.size();
	FAIL_IF(idx < 0 || idx >= num_segments, "invalid idx");

	*pos1 = round(1000 * ctx->matcher->GetHashTime(segments[idx].pos1));
	*pos2 = round(1000 * ctx->matcher->GetHashTime(segments[idx].pos2));
	*duration = round(1000 * ctx->matcher->GetHashTime(segments[idx].duration));
	return 1;
}

int chromaprint_matcher_get_segment_score(ChromaprintMatcherContext *ctx, int idx, int *score)
{
	FAIL_IF(!ctx, "context can't be NULL");

	const auto &segments = ctx->matcher->segments();
	const int num_segments = segments.size();
	FAIL_IF(idx < 0 || idx >= num_segments, "invalid idx");

	*score = segments[idx].public_score();
	return 1;
}

void chromaprint_dealloc(void *ptr)
{
	free(ptr);
}

}; // extern "C"
<|endoftext|>


<commit_before>/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2013 Couchbase, Inc.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

#include "internal.h"
#include "clconfig.h"
#include <list>
#include <algorithm>
#include "trace.h"

#define LOGARGS(mon, lvlbase) mon->settings, "confmon", LCB_LOG_##lvlbase, __FILE__, __LINE__
#define LOG(mon, lvlbase, msg) lcb_log(mon->settings, "confmon", LCB_LOG_##lvlbase, __FILE__, __LINE__, msg)

using namespace lcb::clconfig;

Provider* Confmon::next_active(Provider *cur) {
    ProviderList::iterator ii = std::find(
        active_providers.begin(), active_providers.end(), cur);

    if (ii == active_providers.end() || (++ii) == active_providers.end()) {
        return NULL;
    } else {
        return *ii;
    }
}

Provider* Confmon::first_active()
{
    if (active_providers.empty()) {
        return NULL;
    } else {
        return active_providers.front();
    }
}

static const char *
provider_string(Method type) {
    if (type == CLCONFIG_HTTP) { return "HTTP"; }
    if (type == CLCONFIG_CCCP) { return "CCCP"; }
    if (type == CLCONFIG_FILE) { return "FILE"; }
    if (type == CLCONFIG_MCRAW) { return "MCRAW"; }
    if (type == CLCONFIG_CLADMIN) { return "CLADMIN"; }
    return "";
}

Confmon::Confmon(lcb_settings *settings_, lcbio_pTABLE iot_, lcb_t instance_)
    : cur_provider(NULL),
      config(NULL),
      settings(settings_),
      last_error(LCB_SUCCESS),
      iot(iot_),
      as_start(iot_, this),
      as_stop(iot_, this),
      state(0),
      last_stop_us(0),
      instance(instance_) {

    lcbio_table_ref(iot);
    lcb_settings_ref(settings);

    all_providers[CLCONFIG_FILE] = new_file_provider(this);
    all_providers[CLCONFIG_CCCP] = new_cccp_provider(this);
    all_providers[CLCONFIG_HTTP] = new_http_provider(this);
    all_providers[CLCONFIG_MCRAW] = new_mcraw_provider(this);
    all_providers[CLCONFIG_CLADMIN] = new_cladmin_provider(this);

    for (size_t ii = 0; ii < CLCONFIG_MAX; ii++) {
        all_providers[ii]->parent = this;
    }
}

void Confmon::prepare() {
    active_providers.clear();
    lcb_log(LOGARGS(this, DEBUG), "Preparing providers (this may be called multiple times)");

    for (size_t ii = 0; ii < CLCONFIG_MAX; ii++) {
        Provider *cur = all_providers[ii];
        if (cur) {
            if (cur->enabled) {
                active_providers.push_back(cur);
                lcb_log(LOGARGS(this, DEBUG), "Provider %s is ENABLED", provider_string(cur->type));
            } else if (cur->pause()) {
                lcb_log(LOGARGS(this, DEBUG), "Provider %s is DISABLED", provider_string(cur->type));
            }
        }
    }

    lcb_assert(!active_providers.empty());
    cur_provider = first_active();
}

Confmon::~Confmon() {
    as_start.release();
    as_stop.release();

    if (config) {
        config->decref();
        config = NULL;
    }

    for (size_t ii = 0; ii < CLCONFIG_MAX; ii++) {
        Provider *provider = all_providers[ii];
        if (provider == NULL) {
            continue;
        }
        delete provider;
        all_providers[ii] = NULL;
    }

    lcbio_table_unref(iot);
    lcb_settings_unref(settings);
}

int Confmon::do_set_next(ConfigInfo *new_config, bool notify_miss)
{
    unsigned ii;

    if (config && new_config == config) {
        return 0;
    }
    if (config) {
        lcbvb_CHANGETYPE chstatus = LCBVB_NO_CHANGES;
        lcbvb_CONFIGDIFF *diff = lcbvb_compare(config->vbc, new_config->vbc);

        if (!diff) {
            lcb_log(LOGARGS(this, DEBUG), "Couldn't create vbucket diff");
            return 0;
        }

        chstatus = lcbvb_get_changetype(diff);
        lcbvb_free_diff(diff);

        if (chstatus == 0 || config->compare(*new_config) >= 0) {
            const lcbvb_CONFIG *ca, *cb;

            ca = config->vbc;
            cb = new_config->vbc;

            lcb_log(LOGARGS(this, TRACE), "Not applying configuration received via %s. No changes detected. A.rev=%d, B.rev=%d", provider_string(new_config->get_origin()), ca->revid, cb->revid);
            if (notify_miss) {
                invoke_listeners(CLCONFIG_EVENT_GOT_ANY_CONFIG, new_config);
            }
            return 0;
        }
    }

    lcb_log(LOGARGS(this, INFO), "Setting new configuration. Received via %s", provider_string(new_config->get_origin()));
    TRACE_NEW_CONFIG(instance, new_config);

    if (config) {
        /** DECREF the old one */
        config->decref();
    }

    for (ii = 0; ii < CLCONFIG_MAX; ii++) {
        Provider *cur = all_providers[ii];
        if (cur && cur->enabled) {
            cur->config_updated(new_config->vbc);
        }
    }

    new_config->incref();
    config = new_config;
    stop();

    invoke_listeners(CLCONFIG_EVENT_GOT_NEW_CONFIG, new_config);

    return 1;
}

void Confmon::provider_failed(Provider *provider, lcb_error_t reason) {
    lcb_log(LOGARGS(this, INFO), "Provider '%s' failed", provider_string(provider->type));

    if (provider != cur_provider) {
        lcb_log(LOGARGS(this, TRACE), "Ignoring failure. Current=%p (%s)", (void*)cur_provider, provider_string(cur_provider->type));
        return;
    }
    if (!is_refreshing()) {
        lcb_log(LOGARGS(this, DEBUG), "Ignoring failure. Refresh not active");
    }

    if (reason != LCB_SUCCESS) {
        if (settings->detailed_neterr && last_error != LCB_SUCCESS) {
            /* Filter out any artificial 'connect error' or 'network error' codes */
            if (reason != LCB_CONNECT_ERROR && reason != LCB_NETWORK_ERROR) {
                last_error = reason;
            }
        } else {
            last_error = reason;
        }
        if (reason == LCB_AUTH_ERROR) {
            goto GT_ERROR;
        }
    }

    if (settings->conntype == LCB_TYPE_CLUSTER && provider->type == CLCONFIG_HTTP) {
        Provider *cladmin = get_provider(CLCONFIG_CLADMIN);
        if (!cladmin->enabled) {
            cladmin->enable();
            cladmin->configure_nodes(*provider->get_nodes());
            active_providers.push_back(cladmin);
            lcb_log(LOGARGS(this, DEBUG), "Static configuration provider has been enabled");
        }
    }

    cur_provider = next_active(cur_provider);
    if (cur_provider) {
        uint32_t interval = 0;
        if (config) {
            /* Not first */
            interval = settings->grace_next_provider;
        }
        lcb_log(LOGARGS(this, DEBUG), "Will try next provider in %uus", interval);
        state |= CONFMON_S_ITERGRACE;
        as_start.rearm(interval);
        return;
    } else {
        LOG(this, TRACE, "Maximum provider reached. Resetting index");
    }

GT_ERROR:
    invoke_listeners(CLCONFIG_EVENT_PROVIDERS_CYCLED, NULL);
    cur_provider = first_active();
    stop();
}

void Confmon::provider_got_config(Provider *, ConfigInfo *config_) {
    do_set_next(config_, true);
    stop();
}

void Confmon::do_next_provider()
{
    state &= ~CONFMON_S_ITERGRACE;
    for (ProviderList::const_iterator ii = active_providers.begin();
            ii != active_providers.end(); ++ii) {
        ConfigInfo *info;
        Provider* cached_provider = *ii;
        info = cached_provider->get_cached();
        if (!info) {
            continue;
        }

        if (do_set_next(info, false)) {
            LOG(this, DEBUG, "Using cached configuration");
        }
    }

    lcb_log(LOGARGS(this, TRACE), "Attempting to retrieve cluster map via %s", provider_string(cur_provider->type));

    cur_provider->refresh();
}

void Confmon::start() {
    lcb_U32 tmonext = 0;
    as_stop.cancel();
    if (is_refreshing()) {
        LOG(this, DEBUG, "Cluster map refresh already in progress");
        return;
    }

    LOG(this, TRACE, "Refreshing current cluster map");
    lcb_assert(cur_provider);
    state = CONFMON_S_ACTIVE|CONFMON_S_ITERGRACE;

    if (last_stop_us > 0) {
        lcb_U32 diff = LCB_NS2US(gethrtime()) - last_stop_us;
        if (diff <= settings->grace_next_cycle) {
            tmonext = settings->grace_next_cycle - diff;
        }
    }

    as_start.rearm(tmonext);
}

void Confmon::stop_real() {
    ProviderList::const_iterator ii;
    for (ii = active_providers.begin(); ii != active_providers.end(); ++ii) {
        (*ii)->pause();
    }

    last_stop_us = LCB_NS2US(gethrtime());
    invoke_listeners(CLCONFIG_EVENT_MONITOR_STOPPED, NULL);
}

void Confmon::stop() {
    if (!is_refreshing()) {
        return;
    }
    as_start.cancel();
    as_stop.cancel();
    state = CONFMON_S_INACTIVE;
}

Provider::Provider(Confmon *parent_, Method type_)
    : type(type_), enabled(false), parent(parent_) {
}

Provider::~Provider() {
    parent = NULL;
}

ConfigInfo::~ConfigInfo() {
    if (vbc) {
        lcbvb_destroy(vbc);
    }
}

int ConfigInfo::compare(const ConfigInfo& other) {
    /** First check if both have revisions */
    int rev_a, rev_b;
    rev_a = lcbvb_get_revision(this->vbc);
    rev_b = lcbvb_get_revision(other.vbc);
    if (rev_a >= 0  && rev_b >= 0) {
        return rev_a - rev_b;
    }

    if (this->cmpclock == other.cmpclock) {
        return 0;

    } else if (this->cmpclock < other.cmpclock) {
        return -1;
    }

    return 1;
}

ConfigInfo::ConfigInfo(lcbvb_CONFIG *config_, Method origin_)
    : vbc(config_), cmpclock(gethrtime()), refcount(1), origin(origin_) {
}

void Confmon::add_listener(Listener *lsn) {
    listeners.push_back(lsn);
}

void Confmon::remove_listener(Listener *lsn) {
    listeners.remove(lsn);
}

void Confmon::invoke_listeners(EventType event, ConfigInfo *info) {
    ListenerList::iterator ii = listeners.begin();
    while (ii != listeners.end()) {
        ListenerList::iterator cur = ii++;
        (*cur)->clconfig_lsn(event, info);
    }
}

void Confmon::set_active(Method type, bool enabled)
{
    Provider *provider = all_providers[type];
    if (provider->enabled == enabled) {
        return;
    } else {
        provider->enabled = enabled;
    }
    prepare();
}

void Confmon::dump(FILE *fp) {
    fprintf(fp, "CONFMON=%p\n", (void*)this);
    fprintf(fp, "STATE= (0x%x)", state);
    if (state & CONFMON_S_ACTIVE) {
        fprintf(fp, "ACTIVE|");
    }
    if (state == CONFMON_S_INACTIVE) {
        fprintf(fp, "INACTIVE/IDLE");
    }
    if (state & CONFMON_S_ITERGRACE) {
        fprintf(fp, "ITERGRACE");
    }
    fprintf(fp, "\n");
    fprintf(fp, "LAST ERROR: 0x%x\n", last_error);

    for (size_t ii = 0; ii < CLCONFIG_MAX; ii++) {
        Provider *cur = all_providers[ii];
        if (!cur) {
            continue;
        }

        fprintf(fp, "** PROVIDER: 0x%x (%s) %p\n", cur->type, provider_string(cur->type), (void*)cur);
        fprintf(fp, "** ENABLED: %s\n", cur->enabled ? "YES" : "NO");
        fprintf(fp, "** CURRENT: %s\n", cur == cur_provider ? "YES" : "NO");
        cur->dump(fp);
        fprintf(fp, "\n");
    }
}
<commit_msg>CCBC-866: check cached provider isn't NULL<commit_after>/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2013 Couchbase, Inc.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

#include "internal.h"
#include "clconfig.h"
#include <list>
#include <algorithm>
#include "trace.h"

#define LOGARGS(mon, lvlbase) mon->settings, "confmon", LCB_LOG_##lvlbase, __FILE__, __LINE__
#define LOG(mon, lvlbase, msg) lcb_log(mon->settings, "confmon", LCB_LOG_##lvlbase, __FILE__, __LINE__, msg)

using namespace lcb::clconfig;

Provider* Confmon::next_active(Provider *cur) {
    ProviderList::iterator ii = std::find(
        active_providers.begin(), active_providers.end(), cur);

    if (ii == active_providers.end() || (++ii) == active_providers.end()) {
        return NULL;
    } else {
        return *ii;
    }
}

Provider* Confmon::first_active()
{
    if (active_providers.empty()) {
        return NULL;
    } else {
        return active_providers.front();
    }
}

static const char *
provider_string(Method type) {
    if (type == CLCONFIG_HTTP) { return "HTTP"; }
    if (type == CLCONFIG_CCCP) { return "CCCP"; }
    if (type == CLCONFIG_FILE) { return "FILE"; }
    if (type == CLCONFIG_MCRAW) { return "MCRAW"; }
    if (type == CLCONFIG_CLADMIN) { return "CLADMIN"; }
    return "";
}

Confmon::Confmon(lcb_settings *settings_, lcbio_pTABLE iot_, lcb_t instance_)
    : cur_provider(NULL),
      config(NULL),
      settings(settings_),
      last_error(LCB_SUCCESS),
      iot(iot_),
      as_start(iot_, this),
      as_stop(iot_, this),
      state(0),
      last_stop_us(0),
      instance(instance_) {

    lcbio_table_ref(iot);
    lcb_settings_ref(settings);

    all_providers[CLCONFIG_FILE] = new_file_provider(this);
    all_providers[CLCONFIG_CCCP] = new_cccp_provider(this);
    all_providers[CLCONFIG_HTTP] = new_http_provider(this);
    all_providers[CLCONFIG_MCRAW] = new_mcraw_provider(this);
    all_providers[CLCONFIG_CLADMIN] = new_cladmin_provider(this);

    for (size_t ii = 0; ii < CLCONFIG_MAX; ii++) {
        all_providers[ii]->parent = this;
    }
}

void Confmon::prepare() {
    active_providers.clear();
    lcb_log(LOGARGS(this, DEBUG), "Preparing providers (this may be called multiple times)");

    for (size_t ii = 0; ii < CLCONFIG_MAX; ii++) {
        Provider *cur = all_providers[ii];
        if (cur) {
            if (cur->enabled) {
                active_providers.push_back(cur);
                lcb_log(LOGARGS(this, DEBUG), "Provider %s is ENABLED", provider_string(cur->type));
            } else if (cur->pause()) {
                lcb_log(LOGARGS(this, DEBUG), "Provider %s is DISABLED", provider_string(cur->type));
            }
        }
    }

    lcb_assert(!active_providers.empty());
    cur_provider = first_active();
}

Confmon::~Confmon() {
    as_start.release();
    as_stop.release();

    if (config) {
        config->decref();
        config = NULL;
    }

    for (size_t ii = 0; ii < CLCONFIG_MAX; ii++) {
        Provider *provider = all_providers[ii];
        if (provider == NULL) {
            continue;
        }
        delete provider;
        all_providers[ii] = NULL;
    }

    lcbio_table_unref(iot);
    lcb_settings_unref(settings);
}

int Confmon::do_set_next(ConfigInfo *new_config, bool notify_miss)
{
    unsigned ii;

    if (config && new_config == config) {
        return 0;
    }
    if (config) {
        lcbvb_CHANGETYPE chstatus = LCBVB_NO_CHANGES;
        lcbvb_CONFIGDIFF *diff = lcbvb_compare(config->vbc, new_config->vbc);

        if (!diff) {
            lcb_log(LOGARGS(this, DEBUG), "Couldn't create vbucket diff");
            return 0;
        }

        chstatus = lcbvb_get_changetype(diff);
        lcbvb_free_diff(diff);

        if (chstatus == 0 || config->compare(*new_config) >= 0) {
            const lcbvb_CONFIG *ca, *cb;

            ca = config->vbc;
            cb = new_config->vbc;

            lcb_log(LOGARGS(this, TRACE), "Not applying configuration received via %s. No changes detected. A.rev=%d, B.rev=%d", provider_string(new_config->get_origin()), ca->revid, cb->revid);
            if (notify_miss) {
                invoke_listeners(CLCONFIG_EVENT_GOT_ANY_CONFIG, new_config);
            }
            return 0;
        }
    }

    lcb_log(LOGARGS(this, INFO), "Setting new configuration. Received via %s", provider_string(new_config->get_origin()));
    TRACE_NEW_CONFIG(instance, new_config);

    if (config) {
        /** DECREF the old one */
        config->decref();
    }

    for (ii = 0; ii < CLCONFIG_MAX; ii++) {
        Provider *cur = all_providers[ii];
        if (cur && cur->enabled) {
            cur->config_updated(new_config->vbc);
        }
    }

    new_config->incref();
    config = new_config;
    stop();

    invoke_listeners(CLCONFIG_EVENT_GOT_NEW_CONFIG, new_config);

    return 1;
}

void Confmon::provider_failed(Provider *provider, lcb_error_t reason) {
    lcb_log(LOGARGS(this, INFO), "Provider '%s' failed", provider_string(provider->type));

    if (provider != cur_provider) {
        lcb_log(LOGARGS(this, TRACE), "Ignoring failure. Current=%p (%s)", (void*)cur_provider, provider_string(cur_provider->type));
        return;
    }
    if (!is_refreshing()) {
        lcb_log(LOGARGS(this, DEBUG), "Ignoring failure. Refresh not active");
    }

    if (reason != LCB_SUCCESS) {
        if (settings->detailed_neterr && last_error != LCB_SUCCESS) {
            /* Filter out any artificial 'connect error' or 'network error' codes */
            if (reason != LCB_CONNECT_ERROR && reason != LCB_NETWORK_ERROR) {
                last_error = reason;
            }
        } else {
            last_error = reason;
        }
        if (reason == LCB_AUTH_ERROR) {
            goto GT_ERROR;
        }
    }

    if (settings->conntype == LCB_TYPE_CLUSTER && provider->type == CLCONFIG_HTTP) {
        Provider *cladmin = get_provider(CLCONFIG_CLADMIN);
        if (!cladmin->enabled) {
            cladmin->enable();
            cladmin->configure_nodes(*provider->get_nodes());
            active_providers.push_back(cladmin);
            lcb_log(LOGARGS(this, DEBUG), "Static configuration provider has been enabled");
        }
    }

    cur_provider = next_active(cur_provider);
    if (cur_provider) {
        uint32_t interval = 0;
        if (config) {
            /* Not first */
            interval = settings->grace_next_provider;
        }
        lcb_log(LOGARGS(this, DEBUG), "Will try next provider in %uus", interval);
        state |= CONFMON_S_ITERGRACE;
        as_start.rearm(interval);
        return;
    } else {
        LOG(this, TRACE, "Maximum provider reached. Resetting index");
    }

GT_ERROR:
    invoke_listeners(CLCONFIG_EVENT_PROVIDERS_CYCLED, NULL);
    cur_provider = first_active();
    stop();
}

void Confmon::provider_got_config(Provider *, ConfigInfo *config_) {
    do_set_next(config_, true);
    stop();
}

void Confmon::do_next_provider()
{
    state &= ~CONFMON_S_ITERGRACE;
    for (ProviderList::const_iterator ii = active_providers.begin();
            ii != active_providers.end(); ++ii) {
        Provider* cached_provider = *ii;
        if (!cached_provider) {
            continue;
        }
        ConfigInfo *info = cached_provider->get_cached();
        if (!info) {
            continue;
        }

        if (do_set_next(info, false)) {
            LOG(this, DEBUG, "Using cached configuration");
        }
    }

    lcb_log(LOGARGS(this, TRACE), "Attempting to retrieve cluster map via %s", provider_string(cur_provider->type));

    cur_provider->refresh();
}

void Confmon::start() {
    lcb_U32 tmonext = 0;
    as_stop.cancel();
    if (is_refreshing()) {
        LOG(this, DEBUG, "Cluster map refresh already in progress");
        return;
    }

    LOG(this, TRACE, "Refreshing current cluster map");
    lcb_assert(cur_provider);
    state = CONFMON_S_ACTIVE|CONFMON_S_ITERGRACE;

    if (last_stop_us > 0) {
        lcb_U32 diff = LCB_NS2US(gethrtime()) - last_stop_us;
        if (diff <= settings->grace_next_cycle) {
            tmonext = settings->grace_next_cycle - diff;
        }
    }

    as_start.rearm(tmonext);
}

void Confmon::stop_real() {
    ProviderList::const_iterator ii;
    for (ii = active_providers.begin(); ii != active_providers.end(); ++ii) {
        (*ii)->pause();
    }

    last_stop_us = LCB_NS2US(gethrtime());
    invoke_listeners(CLCONFIG_EVENT_MONITOR_STOPPED, NULL);
}

void Confmon::stop() {
    if (!is_refreshing()) {
        return;
    }
    as_start.cancel();
    as_stop.cancel();
    state = CONFMON_S_INACTIVE;
}

Provider::Provider(Confmon *parent_, Method type_)
    : type(type_), enabled(false), parent(parent_) {
}

Provider::~Provider() {
    parent = NULL;
}

ConfigInfo::~ConfigInfo() {
    if (vbc) {
        lcbvb_destroy(vbc);
    }
}

int ConfigInfo::compare(const ConfigInfo& other) {
    /** First check if both have revisions */
    int rev_a, rev_b;
    rev_a = lcbvb_get_revision(this->vbc);
    rev_b = lcbvb_get_revision(other.vbc);
    if (rev_a >= 0  && rev_b >= 0) {
        return rev_a - rev_b;
    }

    if (this->cmpclock == other.cmpclock) {
        return 0;

    } else if (this->cmpclock < other.cmpclock) {
        return -1;
    }

    return 1;
}

ConfigInfo::ConfigInfo(lcbvb_CONFIG *config_, Method origin_)
    : vbc(config_), cmpclock(gethrtime()), refcount(1), origin(origin_) {
}

void Confmon::add_listener(Listener *lsn) {
    listeners.push_back(lsn);
}

void Confmon::remove_listener(Listener *lsn) {
    listeners.remove(lsn);
}

void Confmon::invoke_listeners(EventType event, ConfigInfo *info) {
    ListenerList::iterator ii = listeners.begin();
    while (ii != listeners.end()) {
        ListenerList::iterator cur = ii++;
        (*cur)->clconfig_lsn(event, info);
    }
}

void Confmon::set_active(Method type, bool enabled)
{
    Provider *provider = all_providers[type];
    if (provider->enabled == enabled) {
        return;
    } else {
        provider->enabled = enabled;
    }
    prepare();
}

void Confmon::dump(FILE *fp) {
    fprintf(fp, "CONFMON=%p\n", (void*)this);
    fprintf(fp, "STATE= (0x%x)", state);
    if (state & CONFMON_S_ACTIVE) {
        fprintf(fp, "ACTIVE|");
    }
    if (state == CONFMON_S_INACTIVE) {
        fprintf(fp, "INACTIVE/IDLE");
    }
    if (state & CONFMON_S_ITERGRACE) {
        fprintf(fp, "ITERGRACE");
    }
    fprintf(fp, "\n");
    fprintf(fp, "LAST ERROR: 0x%x\n", last_error);

    for (size_t ii = 0; ii < CLCONFIG_MAX; ii++) {
        Provider *cur = all_providers[ii];
        if (!cur) {
            continue;
        }

        fprintf(fp, "** PROVIDER: 0x%x (%s) %p\n", cur->type, provider_string(cur->type), (void*)cur);
        fprintf(fp, "** ENABLED: %s\n", cur->enabled ? "YES" : "NO");
        fprintf(fp, "** CURRENT: %s\n", cur == cur_provider ? "YES" : "NO");
        cur->dump(fp);
        fprintf(fp, "\n");
    }
}
<|endoftext|>