Beispiel #1
0
void ab() {
  /*
   * Test a `inclusive-or` b:
   * This should produce the following automaton:
   *
   * = (prefix*(a) || b) | (a || prefix*(b)) | (a || b)
   * = (ø || b          | (a || ø          | (a || b)
   * = b                 | a                 | ab | ba
   *
   * CHECK: digraph automaton_{{[0-9]+}}
   */
  int x, y;
  TESLA_PERTHREAD(strict(call(ab)), strict(returnfrom(ab)),
                  strict(a(x) == 0 || b(y) == 0));

  /*
   * Transitions, grouped into equivalence classes:
   *
   * ab(): 0->1
   * CHECKX: label = "ab(){{.*}}Entry{{.*}}init{{.*}}
   * CHECKX: 0 -> [[CALL:[0-9]+]]
   *
   * a(x): [ 2->4, 5->7 ]
   * CHECKX: label = "a(x)
   * CHECKX: [[INIT1:[0-9]+]] -> [[A1:[0-9]+]]
   * CHECKX: [[B1:[0-9]+]] -> [[A2:[0-9]+]]
   *
   * b(y): [ 3->5, 4->7 ]
   * CHECKX: label = "b(y)
   * CHECKX: [[INIT2:[0-9]+]] -> [[B1]]
   * CHECKX: [[A1]] -> [[A2]]
   *
   * ø: [ 5->6, 4->6, 7->6, 1->2, 1->3 ]
   * CHECKX: label = "[[EPSILON:&#[0-9a-f]+;]]"
   * CHECKX: [[B1]] -> [[FINAL:[0-9]+]]
   * CHECKX: [[A1]] -> [[FINAL]]
   * CHECKX: [[CALL]] -> [[INIT2]]
   * CHECKX: [[A2]] -> [[FINAL]]
   * CHECKX: [[CALL]] -> [[INIT1]]
   */

  /*
   * Graph footer:
   * CHECKX: label = "{{.*inclusive-or.c:[0-9]+#[0-9]+}}
   */
}
std::error_code organizer_impl::verify(size_t fork_point,
    const block_detail_list& orphan_chain, size_t orphan_index)
{
    BITCOIN_ASSERT(orphan_index < orphan_chain.size());
    const auto& current_block = orphan_chain[orphan_index]->actual();
    const size_t height = fork_point + orphan_index + 1;
    BITCOIN_ASSERT(height != 0);

    validate_block_impl validate(interface_, fork_point, orphan_chain,
        orphan_index, height, current_block, checkpoints_);

    // Checks that are independent of the chain.
    auto ec = validate.check_block();
    if (ec)
        return ec;

    // Checks that are dependent on height and preceding blocks.
    ec = validate.accept_block();
    if (ec)
        return ec;

    // Start strict validation if past last checkpoint.
    if (strict(fork_point))
    {
        const auto total_inputs = count_inputs(current_block);
        const auto total_transactions = current_block.transactions.size();

        log_info(LOG_BLOCKCHAIN)
            << "Block [" << height << "] verify ("
            << total_transactions << ") txs and ("
            << total_inputs << ") inputs";

        // Time this for logging.
        const auto timed = [&ec, &validate]()
        {
            // Checks that include input->output traversal.
            ec = validate.connect_block();
        };

        // Execute the timed validation.
        const auto elapsed = timer<std::chrono::milliseconds>::duration(timed);
        const auto ms_per_block = static_cast<float>(elapsed.count());
        const auto ms_per_input = ms_per_block / total_inputs;
        const auto secs_per_block = ms_per_block / 1000;
        const auto verified = ec ? "unverified" : "verified";

        log_info(LOG_BLOCKCHAIN)
            << "Block [" << height << "] " << verified << " in ("
            << secs_per_block << ") secs or ("
            << ms_per_input << ") ms/input";
    }

    return ec;
}