Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: CuriousCarl on January 25, 2015, 05:21:31 PM



Title: Remove block validations in order to speed up initial sync from known client
Post by: CuriousCarl on January 25, 2015, 05:21:31 PM

I only connect to a known host so I trust everything that comes from it. What can I remove in order to speed up the initial sync with the blockchain?

I have already commented out a few things in CheckBlock (main.cpp). My version looks like this now:

Code:
bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot)
{
    // These are checks that are independent of context
    // that can be verified before saving an orphan block.
/*
    // Size limits
    if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
        return state.DoS(100, error("CheckBlock() : size limits failed"),
                         REJECT_INVALID, "bad-blk-length");


    // Check proof of work matches claimed amount
    if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits))
        return state.DoS(50, error("CheckBlock() : proof of work failed"),
                         REJECT_INVALID, "high-hash");
*/

    // Check timestamp
    if (block.GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60)
        return state.Invalid(error("CheckBlock() : block timestamp too far in the future"),
                             REJECT_INVALID, "time-too-new");
/*
    // First transaction must be coinbase, the rest must not be
    if (block.vtx.empty() || !block.vtx[0].IsCoinBase())
        return state.DoS(100, error("CheckBlock() : first tx is not coinbase"),
                         REJECT_INVALID, "bad-cb-missing");
    for (unsigned int i = 1; i < block.vtx.size(); i++)
        if (block.vtx[i].IsCoinBase())
            return state.DoS(100, error("CheckBlock() : more than one coinbase"),
                             REJECT_INVALID, "bad-cb-multiple");
*/

/*
    // Check transactions
    BOOST_FOREACH(const CTransaction& tx, block.vtx)
        if (!CheckTransaction(tx, state))
            return error("CheckBlock() : CheckTransaction failed");
*/

    // Build the merkle tree already. We need it anyway later, and it makes the
    // block cache the transaction hashes, which means they don't need to be
    // recalculated many times during this block's validation.
    block.BuildMerkleTree();

    // Check for duplicate txids. This is caught by ConnectInputs(),
    // but catching it earlier avoids a potential DoS attack:
    set<uint256> uniqueTx;
    for (unsigned int i = 0; i < block.vtx.size(); i++) {
        uniqueTx.insert(block.GetTxHash(i));
    }
    if (uniqueTx.size() != block.vtx.size())
        return state.DoS(100, error("CheckBlock() : duplicate transaction"),
                         REJECT_INVALID, "bad-txns-duplicate", true);

/*
    unsigned int nSigOps = 0;
    BOOST_FOREACH(const CTransaction& tx, block.vtx)
    {
        nSigOps += GetLegacySigOpCount(tx);
    }
    if (nSigOps > MAX_BLOCK_SIGOPS)
        return state.DoS(100, error("CheckBlock() : out-of-bounds SigOpCount"),
                         REJECT_INVALID, "bad-blk-sigops", true);


    // Check merkle root
    if (fCheckMerkleRoot && block.hashMerkleRoot != block.vMerkleTree.back())
        return state.DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"),
                         REJECT_INVALID, "bad-txnmrklroot", true);
*/

    return true;
}

What other changes can I do to speed it up?


Title: Re: Remove block validations in order to speed up initial sync from known client
Post by: Sukrim on January 25, 2015, 05:45:58 PM
You could manually add a very recent checkpoint...

I don't think the initial checking is THAT problematic though, just let it run overnight and be done with it. Afaik there are also different levels of verification that you could try to set.


Title: Re: Remove block validations in order to speed up initial sync from known client
Post by: CuriousCarl on January 25, 2015, 06:00:31 PM
Interesting. How to you set those verification levels?


Title: Re: Remove block validations in order to speed up initial sync from known client
Post by: Sukrim on January 25, 2015, 06:14:09 PM
https://en.bitcoin.it/wiki/Running_Bitcoin

Quote
-checklevel=<n>        How thorough the block verification is (0-4, default: 3)


Title: Re: Remove block validations in order to speed up initial sync from known client
Post by: gmaxwell on January 25, 2015, 06:24:45 PM
This is inadvisable. It doesn't speed things up that much, and it removes the syncup as a check on the correct behavior of your hosts (you may be surprised at how many systems suffer from hardware problems which are exposed by Bitcoin).


Title: Re: Remove block validations in order to speed up initial sync from known client
Post by: Sukrim on January 25, 2015, 06:48:29 PM
Yes, there is a reason why these checks are in place and as rigorous as they are!


Title: Re: Remove block validations in order to speed up initial sync from known client
Post by: Pieter Wuille on January 26, 2015, 05:51:05 AM
-checklevel only changes the level of consistency checks done at startup, it doesn't affect actual validation during network synchronization or otherwise.

If you're syncing from a known node which you fully trust, just copy its $DATADIR/blocks and $DATADIR/chainstate directories to the new system.



Title: Re: Remove block validations in order to speed up initial sync from known client
Post by: elbandi on January 26, 2015, 09:43:01 AM
gethash() is called repeatedly, maybe th result can be cached. like in bitcoinj:
https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/org/bitcoinj/core/Block.java#L534


Title: Re: Remove block validations in order to speed up initial sync from known client
Post by: DeathAndTaxes on January 27, 2015, 05:57:28 PM
What other changes can I do to speed it up?
Remove all transaction validation as well.  ECDSA signature validation is especially CPU heavy. 

However I wonder if this is an xy problem.  If this is just for an initial sync (i.e. one time) then it is far easier to transfer the blockchain as Pieter pointed out and run the stock client.  However if you intend to remain connected to the trusted node(s) (and no other untrusted nodes) then you might as well be running an SPV client/codebase to reduce the resource requirements on the target machine continually.  In essence the bitcoind on the remote computer is asking as an border router for your custom application/code.