shohu / c0ban

c0ban source tree
MIT License
0 stars 0 forks source link

Check difficulty algorithms #45

Closed shohu closed 6 years ago

shohu commented 6 years ago
  1. set "algo change block height" = 200
  2. mine 1000 block
  3. check "difficulty value" between 1 and 1000

I will try to do above check on GKE

shohu commented 6 years ago

I got follwoing error after node mine for a while.

2018-06-08 00:32:21 WARNING: request rejected because http work queue depth exceeded, it can be increased with the -rpcworkqueue= setting
shohu commented 6 years ago

I found following log.

Potential stale tip detected, will try using extra outbound peer

Didn't create Block after Above log was occured.

shohu commented 6 years ago

I tried to change rpcworkqueue values from 128 to 256. But I couldn't solve this problem ...

shohu commented 6 years ago

I set c0band parameter's "-rpcthreads " to 16, so the program continued to run for one hour. (default rpcthreads value is 4) When rpcthreads = 1, so the program continued to run for one minute. So rpcthreads is very important for this problem

shohu commented 6 years ago

I tried to mine by https://github.com/pooler/cpuminer with rpcthreads = 4 The program continued to run for XXX hours, and didn't stoppe this program.

shohu commented 6 years ago

5 threads by pooler/cpuminer

# ps huH p 1
root         1  0.0  0.1 397696  6632 ?        Ssl  04:37   0:00 minerd -a sha256d -o miner-parent-lyra2:
root         1  0.0  0.1 397696  6632 ?        Ssl  04:37   0:00 minerd -a sha256d -o miner-parent-lyra2:
root         1  0.0  0.1 397696  6632 ?        Ssl  04:37   0:00 minerd -a sha256d -o miner-parent-lyra2:
root         1  0.0  0.1 397696  6632 ?        Ssl  04:37   0:00 minerd -a sha256d -o miner-parent-lyra2:
root         1 60.9  0.1 397696  6632 ?        RNsl 04:37   9:56 minerd -a sha256d -o miner-parent-lyra2:

6 threads by pooler/cpuminer

# ps huH p 1
root         1  0.0  0.5 490600 21888 ?        Ssl  05:47   0:00 /miner/cpuminer-multi/cpuminer -a sha256
root         1  0.0  0.5 490600 21888 ?        Ssl  05:47   0:00 /miner/cpuminer-multi/cpuminer -a sha256
root         1  0.0  0.5 490600 21888 ?        Ssl  05:47   0:00 /miner/cpuminer-multi/cpuminer -a sha256
root         1  0.0  0.5 490600 21888 ?        Ssl  05:47   0:00 /miner/cpuminer-multi/cpuminer -a sha256
root         1  0.0  0.5 490600 21888 ?        Ssl  05:47   0:00 /miner/cpuminer-multi/cpuminer -a sha256
root         1 47.9  0.5 490600 21888 ?        RNsl 05:47   0:44 /miner/cpuminer-multi/cpuminer -a sha256
shohu commented 6 years ago

Set 50 to rpcthreads, but I got same error(c0band can't receive rpc command) again.

shohu commented 6 years ago

https://cpprefjp.github.io/reference/thread/thread.html

bool StartHTTPServer()
{
    LogPrint(BCLog::HTTP, "Starting HTTP server\n");
    int rpcThreads = std::max((long)gArgs.GetArg("-rpcthreads", DEFAULT_HTTP_THREADS), 1L);
    LogPrintf("HTTP: starting %d worker threads\n", rpcThreads);
    std::packaged_task<bool(event_base*, evhttp*)> task(ThreadHTTP);
    threadResult = task.get_future();
    threadHTTP = std::thread(std::move(task), eventBase, eventHTTP);

    for (int i = 0; i < rpcThreads; i++) {
        std::thread rpc_worker(HTTPWorkQueueRun, workQueue);
        rpc_worker.detach();
    }
    return true;
}
shohu commented 6 years ago

I will try to use cpuminer-opt https://github.com/JayDDee/cpuminer-opt

shohu commented 6 years ago

target = 0 is wired ??

# /c0ban/bin/c0ban-cli-test -conf=/c0ban/c0ban.conf -datadir=/c0ban-block/ getblocktemplate
{
  "capabilities": [
    "proposal"
  ],
  "version": 536870912,
  "rules": [
  ],
  "vbavailable": {
  },
  "vbrequired": 0,
  "previousblockhash": 
"0000000038b70ad69da80d8ed4901dde55b1d3988e03a9ced235b06f7ae65f84",
  "transactions": [
  ],
  "coinbaseaux": {
    "flags": ""
  },
  "coinbasevalue": 2200000000000,
  "longpollid": "0000000038b70ad69da80d8ed4901dde55b1d3988e03a9ced235b06f7ae65f842",
  "target": "0000000000000000000000000000000000000000000000000000000000000000",
  "mintime": 1528477850,
  "mutable": [
    "time",
    "transactions",
    "prevblock"
  ],
  "noncerange": "00000000ffffffff",
  "sigoplimit": 20000,
  "sizelimit": 4000000,
  "curtime": 1528708843,
  "bits": "00000001",
  "height": 150
}

target = "arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);"

std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn, bool fMineWitnessTx)
{
 :
    pblock->nBits          = GetNextWorkRequired(pindexPrev, pblock, chainparams.GetConsensus());
 :

pblock->nBits = 1 is wrong orz so I changed to following source

    else if (pindexLast->nHeight+1 < Params().SwitchLyra2REv2_LWMA()+Params().AveragingWindow())
    {
        // Reset difficulty for transition period NDA -> LWMA
        return 0x207fffff;
    } else {
shohu commented 6 years ago
  1. Get target by getblocktemplate
  2. miner got hash by calculate nonce.
  3. miner got correct nonce and send hash by submitblock method
  4. submitblock -> ProcessNewBlock(mining.cpp 756) -> CheckBlock -> CheckBlockHeader -> CheckProofOfWork = false -> high-hash
shohu commented 6 years ago
UniValue submitblock(const JSONRPCRequest& request)
{
    // We allow 2 arguments for compliance with BIP22. Argument 2 is ignored.
    if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
        throw std::runtime_error(
            "submitblock \"hexdata\"  ( \"dummy\" )\n"
            "\nAttempts to submit new block to network.\n"
            "See https://en.bitcoin.it/wiki/BIP_0022 for full specification.\n"

            "\nArguments\n"
            "1. \"hexdata\"        (string, required) the hex-encoded block data to submit\n"
            "2. \"dummy\"          (optional) dummy value, for compatibility with BIP22. This value is ignored.\n"
            "\nResult:\n"
            "\nExamples:\n"
            + HelpExampleCli("submitblock", "\"mydata\"")
            + HelpExampleRpc("submitblock", "\"mydata\"")
        );
    }

    std::shared_ptr<CBlock> blockptr = std::make_shared<CBlock>();
    CBlock& block = *blockptr;
    if (!DecodeHexBlk(block, request.params[0].get_str())) {
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
    }

    if (block.vtx.empty() || !block.vtx[0]->IsCoinBase()) {
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block does not start with a coinbase");
    }

    uint256 hash = block.GetHash();
    bool fBlockPresent = false;
    {
        LOCK(cs_main);
        BlockMap::iterator mi = mapBlockIndex.find(hash);
        if (mi != mapBlockIndex.end()) {
            CBlockIndex *pindex = mi->second;
            if (pindex->IsValid(BLOCK_VALID_SCRIPTS)) {
                return "duplicate";
            }
            if (pindex->nStatus & BLOCK_FAILED_MASK) {
                return "duplicate-invalid";
            }
            // Otherwise, we might only have the header - process the block before returning
            fBlockPresent = true;
        }
    }

    {
        LOCK(cs_main);
        BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
        if (mi != mapBlockIndex.end()) {
            UpdateUncommittedBlockStructures(block, mi->second, Params().GetConsensus());
        }
    }

    submitblock_StateCatcher sc(block.GetHash());
    RegisterValidationInterface(&sc);
    bool fAccepted = ProcessNewBlock(Params(), blockptr, true, nullptr);
    UnregisterValidationInterface(&sc);
    if (fBlockPresent) {
        if (fAccepted && !sc.found) {
            return "duplicate-inconclusive";
        }
        return "duplicate";
    }
    if (!sc.found) {
        return "inconclusive";
    }
    return BIP22ValidationResult(sc.state);
}
bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<const CBlock> pblock, bool fForceProcessing, bool *fNewBlock)
{
    {
        CBlockIndex *pindex = nullptr;
        if (fNewBlock) *fNewBlock = false;
        CValidationState state;
        // Ensure that CheckBlock() passes before calling AcceptBlock, as
        // belt-and-suspenders.
        bool ret = CheckBlock(*pblock, state, chainparams.GetConsensus());

        LOCK(cs_main);

        if (ret) {
            // Store to disk
            ret = AcceptBlock(pblock, state, chainparams, &pindex, fForceProcessing, nullptr, fNewBlock);
        }
        CheckBlockIndex(chainparams.GetConsensus());
        if (!ret) {
            GetMainSignals().BlockChecked(*pblock, state);
            return error("%s: AcceptBlock FAILED", __func__);
        }
    }

    NotifyHeaderTip();

    CValidationState state; // Only used to report errors, not invalidity - ignore it
    if (!ActivateBestChain(state, chainparams, pblock))
        return error("%s: ActivateBestChain failed", __func__);

    return true;
}
bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW, bool fCheckMerkleRoot)
{
    // These are checks that are independent of context.

    if (block.fChecked)
        return true;

    // Check that the header is valid (particularly PoW).  This is mostly
    // redundant with the call in AcceptBlockHeader.
    if (!CheckBlockHeader(block, state, consensusParams, fCheckPOW))
        return false;
static bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW = true)
{
    // Get prev block index
    CBlockIndex* pindexPrev = NULL;
    int nHeight = 0;
    BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock);
    if (mi != mapBlockIndex.end()) {
        pindexPrev = (*mi).second;
        nHeight = pindexPrev->nHeight + 1;
    }

    // Check proof of work matches claimed amount
    if (fCheckPOW && !CheckProofOfWork(block.GetPoWHash(nHeight >= Params().SwitchLyra2REv2_LWMA()), block.nBits, consensusParams)) {
        return state.DoS(50, false, REJECT_INVALID, "high-hash", false, "proof of work failed");
    }

    return true;
}
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
{
    bool fNegative;
    bool fOverflow;
    arith_uint256 bnTarget;

    bnTarget.SetCompact(nBits, &fNegative, &fOverflow);

    // Check range
    if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit))
        return false;

    // Check proof of work matches claimed amount
    if (UintToArith256(hash) > bnTarget)
        return false;

    return true;
}

powlimit is affected this problem ?

# main net 
        consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
# regtest
        consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
shohu commented 6 years ago

This problem was occured by powLimit

bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
{
    bool fNegative;
    bool fOverflow;
    arith_uint256 bnTarget;

    bnTarget.SetCompact(nBits, &fNegative, &fOverflow);

    // Check range
    if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit)) {
        LogPrintf("TESTTTT CheckProofOfWork bnTarget = %s, params.powLimit = %s\n", bnTarget.GetHex(), UintToArith256(params.powLimit).GetHex());
        return false;
    }

debug.log

2018-06-12 06:09:36 TESTTTT CheckProofOfWork bnTarget = 7fffff0000000000000000000000000000000000000000000000000000000000, params.powLimit = 00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
2018-06-12 06:09:36 ERROR: ProcessNewBlock: AcceptBlock FAILED