Пример #1
0
    virtual int init(
        int argc,
        const char *argv[]
    )
    {
        txID = 0;
        blkID = 0;
        active = 0;

        optparse::Values &values = parser.parse_args(argc, argv);
        firstBlock = values.get("firstBlock");
        lastBlock = values.get("lastBlock");

        info("Dumping the blockchain...");

        blockFile = fopen("blocks.csv", "w");
        if(!blockFile) sysErrFatal("couldn't open file blocks.csv for writing\n");
        fprintf(blockFile, "ID,Hash,Version,Timestamp,Nonce,Difficulty,Merkle,NumTransactions,OutputValue,FeesValue,Size\n");

        txFile = fopen("transactions.csv", "w");
        if(!txFile) sysErrFatal("couldn't open file txs.csv for writing\n");
        fprintf(txFile, "ID,Hash,Version,BlockId,NumInputs,NumOutputs,OutputValue,FeesValue,LockTime,Size\n");

        outputFile = fopen("outputs.csv", "w");
        if(!outputFile) sysErrFatal("couldn't open file outputs.csv for writing\n");
        fprintf(outputFile, "TransactionId,Index,Value,Script,ReceivingAddress,InputTxHash,InputTxIndex\n");

        inputFile = fopen("inputs.csv", "w");
        if(!inputFile) sysErrFatal("couldn't open file inputs.csv for writing\n");
        fprintf(inputFile, "TransactionId,Index,Script,OutputTxHash,OutputTxIndex\n");

        return 0;
    }
Пример #2
0
static void findBlockFiles() {

    gChainSize = 0;

    auto blockChainDir = getBlockchainDir();
    auto blockDir = blockChainDir + std::string("/blocks");
    info("loading block chain from directory: %s", blockChainDir.c_str());

    struct stat statBuf;
    auto r = stat(blockDir.c_str(), &statBuf);
    auto oldStyle = (r<0 || !S_ISDIR(statBuf.st_mode));

    int blkDatId = (oldStyle ? 1 : 0);
    auto fmt = oldStyle ? "/blk%04d.dat" : "/blocks/blk%05d.dat";
    while(1) {

        char buf[64];
        sprintf(buf, fmt, blkDatId++);

        auto fileName = blockChainDir + std::string(buf) ;
        auto fd = open(fileName.c_str(), O_RDONLY);
        if(fd<0) {
            if(1<blkDatId) {
                break;
            }
            sysErrFatal(
                "failed to open block chain file %s",
                fileName.c_str()
            );
        }

        struct stat statBuf;
        auto r0 = fstat(fd, &statBuf);
        if(r0<0) {
            sysErrFatal(
                "failed to fstat block chain file %s",
                fileName.c_str()
            );
        }

        auto fileSize = statBuf.st_size;
	#if !defined(_WIN64)
	    auto r1 = posix_fadvise(fd, 0, fileSize, POSIX_FADV_NOREUSE);
	    if(r1<0) {
		warning(
		    "failed to posix_fadvise on block chain file %s",
		    fileName.c_str()
		);
	    }
	#endif

        BlockFile blockFile;
        blockFile.fd = fd;
        blockFile.size = fileSize;
        blockFile.name = fileName;
        blockFiles.push_back(blockFile);
        gChainSize += fileSize;
    }
    info("block chain size = %.3f Gigs", 1e-9*gChainSize);
}
Пример #3
0
static void makeBlockMaps() {

    auto blockChainDir = getBlockchainDir();
    auto blockDir = blockChainDir + std::string("/blocks");
    info("loading block chain from: %s", blockChainDir.c_str());

    struct stat statBuf;
    auto r = stat(blockDir.c_str(), &statBuf);
    auto oldStyle = (r<0 || !S_ISDIR(statBuf.st_mode));

    int blkDatId = (oldStyle ? 1 : 0);
    auto fmt = oldStyle ? "/blk%04d.dat" : "/blocks/blk%05d.dat";
    while(1) {

        char buf[64];
        sprintf(buf, fmt, blkDatId++);

        auto blockMapFileName =
            blockChainDir +
            std::string(buf)
        ;

        auto blockMapFD = open(blockMapFileName.c_str(), O_RDONLY);
        if(blockMapFD<0) {
            if(1<blkDatId) {
                break;
            }
            sysErrFatal(
                "failed to open block chain file %s",
                blockMapFileName.c_str()
            );
        }

        struct stat statBuf;
        int st0 = fstat(blockMapFD, &statBuf);
        if(st0<0) {
            sysErrFatal(
                "failed to fstat block chain file %s",
                blockMapFileName.c_str()
            );
        }

        auto mapSize = statBuf.st_size;
        auto st1 = posix_fadvise(blockMapFD, 0, mapSize, POSIX_FADV_NOREUSE);
        if(st1<0) {
            warning(
                "failed to posix_fadvise on block chain file %s",
                blockMapFileName.c_str()
            );
        }

        Map map;
        map.size = mapSize;
        map.fd = blockMapFD;
        map.name = blockMapFileName;
        mapVec.push_back(map);
    }
}
Пример #4
0
static void findBlockParent(
    Block *b
)
{
    auto where = lseek64(
        b->chunk->getMap()->fd,
        b->chunk->getOffset(),
        SEEK_SET
    );
    if(where!=(signed)b->chunk->getOffset()) {
        sysErrFatal(
            "failed to seek into block chain file %s",
            b->chunk->getMap()->name.c_str()
        );
    }

    uint8_t buf[gHeaderSize];
    auto nbRead = read(
        b->chunk->getMap()->fd,
        buf,
        gHeaderSize
    );
    if(nbRead<(signed)gHeaderSize) {
        sysErrFatal(
            "failed to read from block chain file %s",
            b->chunk->getMap()->name.c_str()
        );
    }

    auto i = gBlockMap.find(4 + buf);
    if(unlikely(gBlockMap.end()==i)) {

        uint8_t bHash[2*kSHA256ByteSize + 1];
        toHex(bHash, b->hash);

        uint8_t pHash[2*kSHA256ByteSize + 1];
        toHex(pHash, 4 + buf);

        warning(
            "in block %s failed to locate parent block %s",
            bHash,
            pHash
        );
        return;
    }
    b->prev = i->second;
}
Пример #5
0
static void mapBlockChainFiles()
{
    std::string coinName(
        #if defined REDDCOIN
            "/.reddcoin/"
        #else
            "/.bitcoin/"
        #endif
    );

    const char *home = getenv("HOME");
    if(0==home) {
        warning("could not getenv(\"HOME\"), using \".\" instead.");
        home = ".";
    }

    std::string homeDir(home);
    std::string blockDir = homeDir + coinName + std::string("blocks");

    struct stat statBuf;
    int r = stat(blockDir.c_str(), &statBuf);
    bool oldStyle = (r<0 || !S_ISDIR(statBuf.st_mode));

    int blkDatId = oldStyle ? 1 : 0;
    const char *fmt = oldStyle ? "blk%04d.dat" : "blocks/blk%05d.dat";
    while(1) {

        char buf[64];
        sprintf(buf, fmt, blkDatId++);

        std::string blockMapFileName =
            homeDir                             +
            coinName                            +
            std::string(buf)
        ;

        int blockMapFD = open(blockMapFileName.c_str(), O_DIRECT | O_RDONLY);
        if(blockMapFD<0) {
            if(1<blkDatId) break;
            sysErrFatal(
                "failed to open block chain file %s",
                blockMapFileName.c_str()
            );
        }

        struct stat statBuf;
        int r = fstat(blockMapFD, &statBuf);
        if(r<0) sysErrFatal( "failed to fstat block chain file %s", blockMapFileName.c_str());

        size_t mapSize = statBuf.st_size;
        void *pMap = mmap(0, mapSize, PROT_READ, MAP_PRIVATE, blockMapFD, 0);
        if(((void*)-1)==pMap) {
            sysErrFatal(
                "failed to mmap block chain file %s",
                blockMapFileName.c_str()
            );
        }

        Map map;
        map.size = mapSize;
        map.fd = blockMapFD;
        map.name = blockMapFileName;
        map.p = (const uint8_t*)pMap;
        mapVec.push_back(map);
    }
}
Пример #6
0
  virtual int init(
    int         argc,
    const char *argv[]
    ) {
    txID     = -1;
    blkID    = 0;
    inputID  = 0;
    outputID = 0;

    static uint64_t sz = 32 * 1000 * 1000;
    outputMap.setEmptyKey(empty);
    outputMap.resize(sz);

    optparse::Values& values = parser.parse_args(argc, argv);
    lastBlock = values.get("atBlock").asUInt64();

    if (!file_exists("../blockchain/blockchain.sqlite"))
    {
      firstBlock = 0;
    }
    else
    {
      sqlite3pp::database db("../blockchain/blockchain.sqlite");
      sqlite3pp::query    qry(db, "SELECT MAX(block_id) FROM blocks");

      sqlite3pp::query::iterator i = qry.begin();

      firstBlock = (uint64_t)atoi((*i).get<char const *>(0)) + 1;

      info("Resuming from block %" PRIu64 ".\n", firstBlock);
    }

    info("Dumping the blockchain...");

    txFile = fopen("tx.txt", "w");

    if (!txFile) sysErrFatal("couldn't open file txs.txt for writing\n");

    blockFile = fopen("blocks.txt", "w");

    if (!blockFile) sysErrFatal("couldn't open file blocks.txt for writing\n");

    inputFile = fopen("txin.txt", "w");

    if (!inputFile) sysErrFatal("couldn't open file inputs.txt for writing\n");

    outputFile = fopen("txout.txt", "w");

    if (!outputFile) sysErrFatal("couldn't open file outputs.txt for writing\n");

    FILE *sqlFile = fopen("blockchain.sql", "w");

    if (!sqlFile) sysErrFatal("couldn't open file blockChain.sql for writing\n");

    fprintf(
      sqlFile,
      "PRAGMA journal_mode=MEMORY;\n"
      "PRAGMA synchronous=0;\n"
      "CREATE TABLE IF NOT EXISTS blocks(\n"
      "    block_id BIGINT NOT NULL PRIMARY KEY,\n"
      "    block_hash TEXT NOT NULL,\n"
      "    time BIGINT NOT NULL\n"
      ");\n"
      "\n"
      "CREATE TABLE IF NOT EXISTS tx(\n"
      "    tx_id BIGINT NOT NULL PRIMARY KEY,\n"
      "    tx_hash TEXT NOT NULL,\n"
      "    block_id BIGINT NOT NULL,\n"
      "    FOREIGN KEY (block_id) REFERENCES blocks (block_id)\n"
      ");\n"
      "\n"
      "CREATE TABLE IF NOT EXISTS txout(\n"
      "    txout_id BIGINT NOT NULL PRIMARY KEY,\n"
      "    address CHAR(40),\n"
      "    txout_value BIGINT NOT NULL,\n"
      "    tx_id BIGINT NOT NULL,\n"
      "    txout_pos INT NOT NULL,\n"
      "    FOREIGN KEY (tx_id) REFERENCES tx (tx_id)\n"
      ");\n"
      "\n"
      "CREATE TABLE IF NOT EXISTS txin(\n"
      "    txin_id BIGINT NOT NULL PRIMARY KEY,\n"
      "    txout_id BIGINT NOT NULL,\n"
      "    tx_id BIGINT NOT NULL,\n"
      "    txin_pos INT NOT NULL,\n"
      "    FOREIGN KEY (tx_id) REFERENCES tx (tx_id)\n"
      ");\n"
      "CREATE INDEX IF NOT EXISTS x_txin_txout ON txin (txout_id);\n"
      "CREATE INDEX IF NOT EXISTS x_txout_address ON txout (address);\n"
      "CREATE INDEX IF NOT EXISTS x_txin_txid ON txin (tx_id);\n"
      "CREATE INDEX IF NOT EXISTS x_txout_txid ON txout (tx_id);\n"
      "CREATE INDEX IF NOT EXISTS x_txout_value ON txout (txout_value);\n"
      "CREATE VIEW IF NOT EXISTS tx_full AS SELECT blocks.time, tx.tx_hash, tx.tx_id, txout.address, txout.txout_value FROM txout LEFT JOIN tx ON (tx.tx_id = txout.tx_id) LEFT JOIN blocks ON (tx.block_id = blocks.block_id);\n"
      "\n"
      );
    fclose(sqlFile);

    FILE *bashFile = fopen("blockchain.sh", "w");

    if (!bashFile) sysErrFatal("Couldn't open file blockchain.sh for writing!\n");


    fprintf(
      bashFile,
      "\n"
      "#!/bin/bash\n"
      "\n"
      "echo 'Recreating DB blockchain...'\n"
      "mkdir ../blockchain\n"
      "sqlite3 ../blockchain/blockchain.sqlite < blockchain.sql\n"
      "rm -f blockchain.sql\n"
      "echo done.\n"
      "echo\n"
      "rm -f blockchain.sql\n"
      "\n"
      "for i in blocks txin txout tx\n"
      "do\n"
      "    echo \"Importing table ${i}...\"\n"
      "    echo \".import $i.txt $i\" | sqlite3 ../blockchain/blockchain.sqlite\n"
      "    echo done.\n"
      "    rm -f $i.txt\n"
      "    echo\n"
      "done\n"
      "rm -f blockchain.sh\n"
      "\n"
      );
    fclose(bashFile);

    return 0;
  }
Пример #7
0
    virtual int init(
        int argc,
        const char *argv[]
    )
    {
        txID = 0;
        blkID = 0;
        inputID = 0;
        outputID = 0;

        static uint64_t sz = 32 * 1000 * 1000;
        outputMap.setEmptyKey(empty);
        outputMap.resize(sz);

        optparse::Values &values = parser.parse_args(argc, argv);
        cutoffBlock = values.get("atBlock");

        info("dumping the blockchain ...");

        txFile = fopen("transactions.txt", "w");
        if(!txFile) sysErrFatal("couldn't open file txs.txt for writing\n");

        blockFile = fopen("blocks.txt", "w");
        if(!blockFile) sysErrFatal("couldn't open file blocks.txt for writing\n");

        inputFile = fopen("inputs.txt", "w");
        if(!inputFile) sysErrFatal("couldn't open file inputs.txt for writing\n");

        outputFile = fopen("outputs.txt", "w");
        if(!outputFile) sysErrFatal("couldn't open file outputs.txt for writing\n");

        FILE *sqlFile = fopen("blockChain.sql", "w");
        if(!sqlFile) sysErrFatal("couldn't open file blockChain.sql for writing\n");

        fprintf(
            sqlFile,
            "\n"
            "DROP DATABASE IF EXISTS blockChain;\n"
            "CREATE DATABASE blockChain;\n"
            "USE blockChain;\n"
            "\n"
            "DROP TABLE IF EXISTS transactions;\n"
            "DROP TABLE IF EXISTS outputs;\n"
            "DROP TABLE IF EXISTS inputs;\n"
            "DROP TABLE IF EXISTS blocks;\n"
            "\n"
            "CREATE TABLE blocks(\n"
            "    id BIGINT PRIMARY KEY,\n"
            "    hash BINARY(32),\n"
            "    time BIGINT\n"
            ");\n"
            "\n"
            "CREATE TABLE transactions(\n"
            "    id BIGINT PRIMARY KEY,\n"
            "    hash BINARY(32),\n"
            "    blockID BIGINT\n"
            ");\n"
            "\n"
            "CREATE TABLE outputs(\n"
            "    id BIGINT PRIMARY KEY,\n"
            "    dstAddress CHAR(36),\n"
            "    value BIGINT,\n"
            "    txID BIGINT,\n"
            "    offset INT\n"
            ");\n"
            "\n"
            "CREATE TABLE inputs(\n"
            "    id BIGINT PRIMARY KEY,\n"
            "    outputID BIGINT,\n"
            "    txID BIGINT,\n"
            "    offset INT\n"
            ");\n"
            "\n"
        );
        fclose(sqlFile);

        FILE *bashFile = fopen("blockChain.bash", "w");
        if(!bashFile) sysErrFatal("couldn't open file blockChain.bash for writing\n");

        fprintf(
            bashFile,
            "\n"
            "#!/bin/bash\n"
            "\n"
            "echo\n"
            "\n"
            "echo 'wiping/re-creating DB blockChain ...'\n"
            "time mysql -u root -p -hlocalhost --password='' < blockChain.sql\n"
            "echo done\n"
            "echo\n"
            "\n"
            "for i in blocks inputs outputs transactions\n"
            "do\n"
            "    echo Importing table $i ...\n"
            "    time mysqlimport -u root -p -hlocalhost --password='' --lock-tables --use-threads=3 --local blockChain $i.txt\n"
            "    echo done\n"
            "    echo\n"
            "done\n"
            "\n"
        );
        fclose(bashFile);

        return 0;
    }