Exemplo n.º 1
0
/* This makes sure to call functions on the node which only return cached
   data. This ensures it returns promptly, and doesn't hang waiting for a
   response when the node is having issues. */
void status(CryptoNote::INode &node, CryptoNote::WalletGreen &wallet)
{
    uint32_t localHeight = node.getLastLocalBlockHeight();
    uint32_t remoteHeight = node.getLastKnownBlockHeight();
    uint32_t walletHeight = wallet.getBlockCount() - 1;

    /* Print the heights of local, remote, and wallet */
    printHeights(localHeight, remoteHeight, walletHeight);

    std::cout << std::endl;

    /* Print the network and wallet sync status in percentage */
    printSyncStatus(localHeight, remoteHeight, walletHeight);

    std::cout << std::endl;

    /* Print the network hashrate, based on the last local block */
    printHashrate(node.getLastLocalBlockHeaderInfo().difficulty);

    /* Print the amount of peers we have */
    printPeerCount(node.getPeerCount());

    std::cout << std::endl;

    /* Print a summary of the sync status */
    printSyncSummary(localHeight, remoteHeight, walletHeight);
}
Exemplo n.º 2
0
bool BaseFunctionalTests::waitForPeerCount(CryptoNote::INode& node, size_t expectedPeerCount) {
  PeerCountWaiter peerCountWaiter(m_dispatcher);
  node.addObserver(&peerCountWaiter);
  if (node.getPeerCount() != expectedPeerCount) {
    peerCountWaiter.wait(expectedPeerCount);
  }
  node.removeObserver(&peerCountWaiter);
  // TODO workaround: make sure ObserverManager doesn't have local pointers to peerCountWaiter, so it can be destroyed
  std::this_thread::sleep_for(std::chrono::milliseconds(100));
  // Run all spawned handlers from PeerCountWaiter::peerCountUpdated
  m_dispatcher.yield();

  return !peerCountWaiter.m_timedout;
}
Exemplo n.º 3
0
void balance(CryptoNote::INode &node, CryptoNote::WalletGreen &wallet,
             bool viewWallet)
{
    const uint64_t unconfirmedBalance = wallet.getPendingBalance();
    const uint64_t confirmedBalance = wallet.getActualBalance();
    const uint64_t totalBalance = unconfirmedBalance + confirmedBalance;

    const uint32_t localHeight = node.getLastLocalBlockHeight();
    const uint32_t remoteHeight = node.getLastKnownBlockHeight();
    const uint32_t walletHeight = wallet.getBlockCount();

    std::cout << "Available balance: "
              << SuccessMsg(formatAmount(confirmedBalance)) << std::endl
              << "Locked (unconfirmed) balance: "
              << WarningMsg(formatAmount(unconfirmedBalance))
              << std::endl << "Total balance: "
              << InformationMsg(formatAmount(totalBalance)) << std::endl;

    if (viewWallet)
    {
        std::cout << std::endl 
                  << InformationMsg("Please note that view only wallets "
                                    "can only track incoming transactions,")
                  << std::endl
                  << InformationMsg("and so your wallet balance may appear "
                                    "inflated.") << std::endl;
    }

    if (localHeight < remoteHeight)
    {
        std::cout << std::endl
                  << InformationMsg("Your daemon is not fully synced with "
                                    "the network!")
                  << std::endl
                  << "Your balance may be incorrect until you are fully "
                  << "synced!" << std::endl;
    }
    /* Small buffer because wallet height doesn't update instantly like node
       height does */
    else if (walletHeight + 1000 < remoteHeight)
    {
        std::cout << std::endl
                  << InformationMsg("The blockchain is still being scanned for "
                                    "your transactions.")
                  << std::endl
                  << "Balances might be incorrect whilst this is ongoing."
                  << std::endl;
    }
}
Exemplo n.º 4
0
bool checkNodeStatus(CryptoNote::INode &node)
{
    while (node.getLastKnownBlockHeight() == 0)
    {
        std::stringstream msg;

        msg << "It looks like " << WalletConfig::daemonName << " isn't open!"
            << std::endl << std::endl
            << "Ensure " << WalletConfig::daemonName
            << " is open and has finished initializing." << std::endl
            << "If it's still not working, try restarting "
            << WalletConfig::daemonName << "."
            << "The daemon sometimes gets stuck."
            << std::endl << "Alternatively, perhaps "
            << WalletConfig::daemonName << " can't communicate with any peers."
            << std::endl << std::endl
            << "The wallet can't function fully until it can communicate with "
            << "the network.";

        std::cout << WarningMsg(msg.str()) << std::endl;

        /* Print the commands */
        printCommands(nodeDownCommands());

        /* See what the user wants to do */
        std::string command = parseCommand(nodeDownCommands(),
                                           nodeDownCommands(),
                                           "What would you like to do?: ",
                                           false,
                                           nullptr);

        /* If they want to try again, check the node height again */
        if (command == "try_again")
        {
            continue;
        }
        /* If they want to exit, exit */
        else if (command == "exit")
        {
            return false;
        }
        /* If they want to continue, proceed to the menu screen */
        else if (command == "continue")
        {
            return true;
        }
    }

    return true;
}
Exemplo n.º 5
0
bool BaseFunctionalTests::waitForPoolSize(size_t nodeIndex, CryptoNote::INode& node, size_t expectedPoolSize,
  std::vector<std::unique_ptr<CryptoNote::ITransactionReader>>& txPool) {
  System::Event event(m_dispatcher);
  PoolUpdateWaiter poolUpdateWaiter(m_dispatcher, event);
  node.addObserver(&poolUpdateWaiter);

  bool ok;
  for (size_t i = 0; ; ++i) {
    ok = getNodeTransactionPool(nodeIndex, node, txPool);
    if (!ok) {
      break;
    }
    if (txPool.size() == expectedPoolSize) {
      break;
    }

    // TODO NodeRpcProxy doesn't send poolChanged() notification!!!
    //event.wait();
    //event.clear();
    // WORKAROUND
    if (i < 3 * P2P_DEFAULT_HANDSHAKE_INTERVAL) {
      std::this_thread::sleep_for(std::chrono::seconds(1));
    } else {
      ok = false;
      break;
    }
  }

  node.removeObserver(&poolUpdateWaiter);
  // TODO workaround: make sure ObserverManager doesn't have local pointers to poolUpdateWaiter, so it can be destroyed
  std::this_thread::sleep_for(std::chrono::milliseconds(100));
  // Run all spawned handlers from PoolUpdateWaiter::poolChanged
  m_dispatcher.yield();

  return ok;
}
Exemplo n.º 6
0
bool BaseFunctionalTests::getNodeTransactionPool(size_t nodeIndex, CryptoNote::INode& node,
        std::vector<std::unique_ptr<CryptoNote::ITransactionReader>>& txPool) {

    assert(nodeIndex < nodeDaemons.size() && nodeDaemons[nodeIndex].get() != nullptr);
    auto& daemon = *nodeDaemons[nodeIndex];

    Crypto::Hash tailBlockId;
    bool updateTailBlockId = true;
    while (true) {
        if (updateTailBlockId) {
            if (!daemon.getTailBlockId(tailBlockId)) {
                return false;
            }
            updateTailBlockId = false;
        }

        System::Event poolReceivedEvent(m_dispatcher);
        std::error_code ec;
        bool isTailBlockActual;
        std::vector<std::unique_ptr<ITransactionReader>> addedTxs;
        std::vector<Crypto::Hash> deletedTxsIds;
        node.getPoolSymmetricDifference(std::vector<Crypto::Hash>(), tailBlockId, isTailBlockActual, addedTxs, deletedTxsIds,
        [this, &poolReceivedEvent, &ec](std::error_code result) {
            ec = result;
            m_dispatcher.remoteSpawn([&poolReceivedEvent]() {
                poolReceivedEvent.set();
            });
        }
                                       );
        poolReceivedEvent.wait();

        if (ec) {
            return false;
        } else if (!isTailBlockActual) {
            updateTailBlockId = true;
        } else {
            txPool = std::move(addedTxs);
            break;
        }
    }

    return true;
}
Exemplo n.º 7
0
void blockchainHeight(CryptoNote::INode &node, CryptoNote::WalletGreen &wallet)
{
    const uint32_t localHeight = node.getLastLocalBlockHeight();
    const uint32_t remoteHeight = node.getLastKnownBlockHeight();
    const uint32_t walletHeight = wallet.getBlockCount() - 1;

    /* This is the height that the wallet has been scanned to. The blockchain
       can be fully updated, but we have to walk the chain to find our
       transactions, and this number indicates that progress. */
    std::cout << "Wallet blockchain height: ";

    /* Small buffer because wallet height doesn't update instantly like node
       height does */
    if (walletHeight + 1000 > remoteHeight)
    {
        std::cout << SuccessMsg(std::to_string(walletHeight));
    }
    else
    {
        std::cout << WarningMsg(std::to_string(walletHeight));
    }

    std::cout << std::endl << "Local blockchain height: ";

    if (localHeight == remoteHeight)
    {
        std::cout << SuccessMsg(std::to_string(localHeight));
    }
    else
    {
        std::cout << WarningMsg(std::to_string(localHeight));
    }

    std::cout << std::endl << "Network blockchain height: "
              << SuccessMsg(std::to_string(remoteHeight)) << std::endl;

    if (localHeight == 0 && remoteHeight == 0)
    {
        std::cout << WarningMsg("Uh oh, it looks like you don't have ")
                  << WarningMsg(WalletConfig::daemonName)
                  << WarningMsg(" open!")
                  << std::endl;
    }
    else if (walletHeight + 1000 < remoteHeight && localHeight == remoteHeight)
    {
        std::cout << InformationMsg("You are synced with the network, but the "
                                    "blockchain is still being scanned for "
                                    "your transactions.")
                  << std::endl
                  << "Balances might be incorrect whilst this is ongoing."
                  << std::endl;
    }
    else if (localHeight == remoteHeight)
    {
        std::cout << SuccessMsg("Yay! You are synced!") << std::endl;
    }
    else
    {
        std::cout << WarningMsg("Be patient, you are still syncing with the "
                                "network!") << std::endl;
    }
}