2015-09-18 11:55:31 +00:00
|
|
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
|
|
|
// Distributed under the MIT/X11 software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
2015-04-06 16:13:07 +00:00
|
|
|
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
|
|
|
|
#include <system_error>
|
|
|
|
|
2015-07-15 12:23:00 +00:00
|
|
|
#include <boost/range/combine.hpp>
|
|
|
|
|
2015-04-06 16:13:07 +00:00
|
|
|
#include "EventWaiter.h"
|
|
|
|
#include "ICoreStub.h"
|
2015-07-30 15:22:07 +00:00
|
|
|
#include "ICryptoNoteProtocolQueryStub.h"
|
2015-05-27 12:08:46 +00:00
|
|
|
#include "InProcessNode/InProcessNode.h"
|
2015-07-15 12:23:00 +00:00
|
|
|
#include "TestBlockchainGenerator.h"
|
|
|
|
#include "Logging/FileLogger.h"
|
2015-07-30 15:22:07 +00:00
|
|
|
#include "CryptoNoteCore/TransactionApi.h"
|
|
|
|
#include "CryptoNoteCore/CryptoNoteTools.h"
|
2015-08-27 18:55:14 +00:00
|
|
|
#include "CryptoNoteCore/VerificationContext.h"
|
2015-07-30 15:22:07 +00:00
|
|
|
#include "Common/StringTools.h"
|
|
|
|
|
|
|
|
using namespace Crypto;
|
|
|
|
using namespace CryptoNote;
|
|
|
|
using namespace Common;
|
2015-04-06 16:13:07 +00:00
|
|
|
|
|
|
|
struct CallbackStatus {
|
|
|
|
CallbackStatus() {}
|
|
|
|
|
|
|
|
bool wait() { return waiter.wait_for(std::chrono::milliseconds(3000)); }
|
|
|
|
bool ok() { return waiter.wait_for(std::chrono::milliseconds(3000)) && !static_cast<bool>(code); }
|
|
|
|
void setStatus(const std::error_code& ec) { code = ec; waiter.notify(); }
|
|
|
|
std::error_code getStatus() const { return code; }
|
|
|
|
|
|
|
|
std::error_code code;
|
|
|
|
EventWaiter waiter;
|
|
|
|
};
|
|
|
|
|
2015-07-15 12:23:00 +00:00
|
|
|
namespace {
|
|
|
|
CryptoNote::Transaction createTx(CryptoNote::ITransactionReader& tx) {
|
|
|
|
CryptoNote::Transaction outTx;
|
2015-07-30 15:22:07 +00:00
|
|
|
fromBinaryArray(outTx, tx.getTransactionData());
|
2015-07-15 12:23:00 +00:00
|
|
|
return outTx;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
class InProcessNodeTests : public ::testing::Test {
|
2015-04-06 16:13:07 +00:00
|
|
|
public:
|
2015-07-30 15:22:07 +00:00
|
|
|
InProcessNodeTests() :
|
2015-07-15 12:23:00 +00:00
|
|
|
node(coreStub, protocolQueryStub),
|
|
|
|
currency(CryptoNote::CurrencyBuilder(logger).currency()),
|
|
|
|
generator(currency) {}
|
2015-04-06 16:13:07 +00:00
|
|
|
void SetUp();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
void initNode();
|
|
|
|
|
|
|
|
ICoreStub coreStub;
|
2015-07-30 15:22:07 +00:00
|
|
|
ICryptoNoteProtocolQueryStub protocolQueryStub;
|
2015-04-06 16:13:07 +00:00
|
|
|
CryptoNote::InProcessNode node;
|
2015-07-15 12:23:00 +00:00
|
|
|
|
|
|
|
CryptoNote::Currency currency;
|
|
|
|
TestBlockchainGenerator generator;
|
|
|
|
Logging::FileLogger logger;
|
2015-04-06 16:13:07 +00:00
|
|
|
};
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
void InProcessNodeTests::SetUp() {
|
2015-07-15 12:23:00 +00:00
|
|
|
logger.init("/dev/null");
|
2015-04-06 16:13:07 +00:00
|
|
|
initNode();
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
void InProcessNodeTests::initNode() {
|
2015-04-06 16:13:07 +00:00
|
|
|
CallbackStatus status;
|
|
|
|
|
|
|
|
node.init([&status] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.ok());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, initOk) {
|
2015-04-06 16:13:07 +00:00
|
|
|
CryptoNote::InProcessNode newNode(coreStub, protocolQueryStub);
|
|
|
|
CallbackStatus status;
|
|
|
|
|
|
|
|
newNode.init([&status] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.ok());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, doubleInit) {
|
2015-04-06 16:13:07 +00:00
|
|
|
CallbackStatus status;
|
|
|
|
node.init([&status] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
|
|
|
|
std::error_code ec = status.getStatus();
|
|
|
|
ASSERT_NE(ec, std::error_code());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, shutdownNotInited) {
|
2015-04-06 16:13:07 +00:00
|
|
|
CryptoNote::InProcessNode newNode(coreStub, protocolQueryStub);
|
|
|
|
ASSERT_FALSE(newNode.shutdown());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, shutdown) {
|
2015-04-06 16:13:07 +00:00
|
|
|
ASSERT_TRUE(node.shutdown());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getPeersCountSuccess) {
|
2015-04-06 16:13:07 +00:00
|
|
|
protocolQueryStub.setPeerCount(1);
|
|
|
|
ASSERT_EQ(1, node.getPeerCount());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getLastLocalBlockHeightSuccess) {
|
|
|
|
Crypto::Hash ignore;
|
|
|
|
coreStub.set_blockchain_top(10, ignore);
|
2015-04-06 16:13:07 +00:00
|
|
|
|
|
|
|
ASSERT_EQ(10, node.getLastLocalBlockHeight());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getLastKnownBlockHeightSuccess) {
|
2015-04-06 16:13:07 +00:00
|
|
|
protocolQueryStub.setObservedHeight(10);
|
2015-05-27 12:08:46 +00:00
|
|
|
ASSERT_EQ(10, node.getLastKnownBlockHeight() + 1);
|
2015-04-06 16:13:07 +00:00
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getTransactionOutsGlobalIndicesSuccess) {
|
|
|
|
Crypto::Hash ignore;
|
|
|
|
std::vector<uint32_t> indices;
|
|
|
|
std::vector<uint32_t> expectedIndices;
|
2015-04-06 16:13:07 +00:00
|
|
|
|
|
|
|
uint64_t start = 10;
|
|
|
|
std::generate_n(std::back_inserter(expectedIndices), 5, [&start] () { return start++; });
|
|
|
|
coreStub.set_outputs_gindexs(expectedIndices, true);
|
|
|
|
|
|
|
|
CallbackStatus status;
|
|
|
|
node.getTransactionOutsGlobalIndices(ignore, indices, [&status] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.ok());
|
|
|
|
|
|
|
|
ASSERT_EQ(expectedIndices.size(), indices.size());
|
|
|
|
std::sort(indices.begin(), indices.end());
|
|
|
|
ASSERT_TRUE(std::equal(indices.begin(), indices.end(), expectedIndices.begin()));
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getTransactionOutsGlobalIndicesFailure) {
|
|
|
|
Crypto::Hash ignore;
|
|
|
|
std::vector<uint32_t> indices;
|
2015-04-06 16:13:07 +00:00
|
|
|
coreStub.set_outputs_gindexs(indices, false);
|
|
|
|
|
|
|
|
CallbackStatus status;
|
|
|
|
node.getTransactionOutsGlobalIndices(ignore, indices, [&status] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_NE(std::error_code(), status.getStatus());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getRandomOutsByAmountsSuccess) {
|
|
|
|
Crypto::PublicKey ignoredPublicKey;
|
|
|
|
Crypto::SecretKey ignoredSectetKey;
|
|
|
|
Crypto::generate_keys(ignoredPublicKey, ignoredSectetKey);
|
2015-04-06 16:13:07 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
CryptoNote::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_response expectedResp;
|
|
|
|
CryptoNote::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_outs_for_amount out;
|
2015-04-06 16:13:07 +00:00
|
|
|
out.amount = 10;
|
|
|
|
out.outs.push_back({ 11, ignoredPublicKey });
|
|
|
|
expectedResp.outs.push_back(out);
|
|
|
|
coreStub.set_random_outs(expectedResp, true);
|
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
std::vector<CryptoNote::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_outs_for_amount> outs;
|
2015-04-06 16:13:07 +00:00
|
|
|
|
|
|
|
CallbackStatus status;
|
|
|
|
node.getRandomOutsByAmounts({1,2,3}, 1, outs, [&status] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.ok());
|
|
|
|
ASSERT_EQ(1, outs.size());
|
|
|
|
|
|
|
|
ASSERT_EQ(10, outs[0].amount);
|
|
|
|
ASSERT_EQ(1, outs[0].outs.size());
|
|
|
|
ASSERT_EQ(11, outs[0].outs.front().global_amount_index);
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getRandomOutsByAmountsFailure) {
|
2015-05-27 12:08:46 +00:00
|
|
|
CryptoNote::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_response expectedResp;
|
2015-04-06 16:13:07 +00:00
|
|
|
coreStub.set_random_outs(expectedResp, false);
|
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
std::vector<CryptoNote::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_outs_for_amount> outs;
|
2015-04-06 16:13:07 +00:00
|
|
|
|
|
|
|
CallbackStatus status;
|
|
|
|
node.getRandomOutsByAmounts({1,2,3}, 1, outs, [&status] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_NE(std::error_code(), status.getStatus());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getPeerCountUninitialized) {
|
2015-04-06 16:13:07 +00:00
|
|
|
CryptoNote::InProcessNode newNode(coreStub, protocolQueryStub);
|
|
|
|
ASSERT_ANY_THROW(newNode.getPeerCount());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getLastLocalBlockHeightUninitialized) {
|
2015-04-06 16:13:07 +00:00
|
|
|
CryptoNote::InProcessNode newNode(coreStub, protocolQueryStub);
|
|
|
|
ASSERT_ANY_THROW(newNode.getLastLocalBlockHeight());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getLastKnownBlockHeightUninitialized) {
|
2015-04-06 16:13:07 +00:00
|
|
|
CryptoNote::InProcessNode newNode(coreStub, protocolQueryStub);
|
|
|
|
ASSERT_ANY_THROW(newNode.getLastKnownBlockHeight());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getNewBlocksUninitialized) {
|
2015-04-06 16:13:07 +00:00
|
|
|
CryptoNote::InProcessNode newNode(coreStub, protocolQueryStub);
|
2015-07-30 15:22:07 +00:00
|
|
|
std::vector<Crypto::Hash> knownBlockIds;
|
|
|
|
std::vector<CryptoNote::block_complete_entry> newBlocks;
|
|
|
|
uint32_t startHeight;
|
2015-04-06 16:13:07 +00:00
|
|
|
|
|
|
|
CallbackStatus status;
|
|
|
|
newNode.getNewBlocks(std::move(knownBlockIds), newBlocks, startHeight, [&] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_NE(std::error_code(), status.getStatus());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getTransactionOutsGlobalIndicesUninitialized) {
|
2015-04-06 16:13:07 +00:00
|
|
|
CryptoNote::InProcessNode newNode(coreStub, protocolQueryStub);
|
2015-07-30 15:22:07 +00:00
|
|
|
std::vector<uint32_t> outsGlobalIndices;
|
2015-04-06 16:13:07 +00:00
|
|
|
|
|
|
|
CallbackStatus status;
|
2015-07-30 15:22:07 +00:00
|
|
|
newNode.getTransactionOutsGlobalIndices(Crypto::Hash(), outsGlobalIndices, [&] (std::error_code ec) { status.setStatus(ec); });
|
2015-04-06 16:13:07 +00:00
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_NE(std::error_code(), status.getStatus());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getRandomOutsByAmountsUninitialized) {
|
2015-04-06 16:13:07 +00:00
|
|
|
CryptoNote::InProcessNode newNode(coreStub, protocolQueryStub);
|
2015-05-27 12:08:46 +00:00
|
|
|
std::vector<CryptoNote::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_outs_for_amount> outs;
|
2015-04-06 16:13:07 +00:00
|
|
|
|
|
|
|
CallbackStatus status;
|
|
|
|
newNode.getRandomOutsByAmounts({1,2,3}, 1, outs, [&] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_NE(std::error_code(), status.getStatus());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, relayTransactionUninitialized) {
|
2015-04-06 16:13:07 +00:00
|
|
|
CryptoNote::InProcessNode newNode(coreStub, protocolQueryStub);
|
|
|
|
|
|
|
|
CallbackStatus status;
|
2015-05-27 12:08:46 +00:00
|
|
|
newNode.relayTransaction(CryptoNote::Transaction(), [&] (std::error_code ec) { status.setStatus(ec); });
|
2015-04-06 16:13:07 +00:00
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_NE(std::error_code(), status.getStatus());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getBlocksByHeightEmpty) {
|
|
|
|
std::vector<uint32_t> blockHeights;
|
2015-07-15 12:23:00 +00:00
|
|
|
std::vector<std::vector<CryptoNote::BlockDetails>> blocks;
|
|
|
|
ASSERT_EQ(blockHeights.size(), 0);
|
|
|
|
ASSERT_EQ(blocks.size(), 0);
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
coreStub.set_blockchain_top(0, boost::value_initialized<Crypto::Hash>());
|
2015-07-15 12:23:00 +00:00
|
|
|
|
|
|
|
CallbackStatus status;
|
|
|
|
node.getBlocks(blockHeights, blocks, [&status] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_EQ(std::error_code(), status.getStatus());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getBlocksByHeightMany) {
|
|
|
|
const uint32_t NUMBER_OF_BLOCKS = 10;
|
2015-07-15 12:23:00 +00:00
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
std::vector<uint32_t> blockHeights;
|
2015-07-15 12:23:00 +00:00
|
|
|
std::vector<std::vector<CryptoNote::BlockDetails>> actualBlocks;
|
|
|
|
|
|
|
|
std::vector<CryptoNote::Block> expectedBlocks;
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
coreStub.set_blockchain_top(0, boost::value_initialized<Crypto::Hash>());
|
2015-07-15 12:23:00 +00:00
|
|
|
|
|
|
|
generator.generateEmptyBlocks(NUMBER_OF_BLOCKS);
|
|
|
|
ASSERT_GE(generator.getBlockchain().size(), NUMBER_OF_BLOCKS);
|
|
|
|
|
|
|
|
for (auto iter = generator.getBlockchain().begin() + 1; iter != generator.getBlockchain().end(); iter++) {
|
|
|
|
expectedBlocks.push_back(*iter);
|
2015-07-30 15:22:07 +00:00
|
|
|
blockHeights.push_back(std::move(boost::get<CryptoNote::BaseInput>(iter->baseTransaction.inputs.front()).blockIndex));
|
2015-07-15 12:23:00 +00:00
|
|
|
coreStub.addBlock(*iter);
|
|
|
|
}
|
|
|
|
|
|
|
|
ASSERT_GE(blockHeights.size(), NUMBER_OF_BLOCKS);
|
|
|
|
ASSERT_EQ(blockHeights.size(), expectedBlocks.size());
|
|
|
|
ASSERT_EQ(actualBlocks.size(), 0);
|
|
|
|
|
|
|
|
CallbackStatus status;
|
|
|
|
node.getBlocks(blockHeights, actualBlocks, [&status] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_EQ(std::error_code(), status.getStatus());
|
|
|
|
|
|
|
|
ASSERT_EQ(blockHeights.size(), expectedBlocks.size());
|
|
|
|
ASSERT_EQ(blockHeights.size(), actualBlocks.size());
|
|
|
|
auto range1 = boost::combine(blockHeights, expectedBlocks);
|
|
|
|
auto range = boost::combine(range1, actualBlocks);
|
|
|
|
for (const boost::tuple<boost::tuple<size_t, CryptoNote::Block>, std::vector<CryptoNote::BlockDetails>>& sameHeight : range) {
|
|
|
|
EXPECT_EQ(sameHeight.get<1>().size(), 1);
|
|
|
|
for (const CryptoNote::BlockDetails& block : sameHeight.get<1>()) {
|
|
|
|
EXPECT_EQ(block.height, sameHeight.get<0>().get<0>());
|
2015-07-30 15:22:07 +00:00
|
|
|
Crypto::Hash expectedCryptoHash = CryptoNote::get_block_hash(sameHeight.get<0>().get<1>());
|
|
|
|
Hash expectedHash = reinterpret_cast<const Hash&>(expectedCryptoHash);
|
2015-07-15 12:23:00 +00:00
|
|
|
EXPECT_EQ(block.hash, expectedHash);
|
|
|
|
EXPECT_FALSE(block.isOrphaned);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getBlocksByHeightFail) {
|
|
|
|
const uint32_t NUMBER_OF_BLOCKS = 10;
|
2015-07-15 12:23:00 +00:00
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
std::vector<uint32_t> blockHeights;
|
2015-07-15 12:23:00 +00:00
|
|
|
std::vector<std::vector<CryptoNote::BlockDetails>> actualBlocks;
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
coreStub.set_blockchain_top(0, boost::value_initialized<Crypto::Hash>());
|
2015-07-15 12:23:00 +00:00
|
|
|
|
|
|
|
generator.generateEmptyBlocks(NUMBER_OF_BLOCKS);
|
|
|
|
ASSERT_LT(generator.getBlockchain().size(), NUMBER_OF_BLOCKS * 2);
|
|
|
|
|
|
|
|
for (const CryptoNote::Block& block : generator.getBlockchain()) {
|
|
|
|
coreStub.addBlock(block);
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
for (uint32_t i = 0; i < NUMBER_OF_BLOCKS * 2; ++i) {
|
2015-07-15 12:23:00 +00:00
|
|
|
blockHeights.push_back(std::move(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
ASSERT_EQ(actualBlocks.size(), 0);
|
|
|
|
|
|
|
|
CallbackStatus status;
|
|
|
|
node.getBlocks(blockHeights, actualBlocks, [&status] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_NE(std::error_code(), status.getStatus());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getBlocksByHeightNotInited) {
|
2015-07-15 12:23:00 +00:00
|
|
|
CryptoNote::InProcessNode newNode(coreStub, protocolQueryStub);
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
std::vector<uint32_t> blockHeights;
|
2015-07-15 12:23:00 +00:00
|
|
|
std::vector<std::vector<CryptoNote::BlockDetails>> blocks;
|
|
|
|
ASSERT_EQ(blockHeights.size(), 0);
|
|
|
|
ASSERT_EQ(blocks.size(), 0);
|
|
|
|
|
|
|
|
CallbackStatus status;
|
|
|
|
newNode.getBlocks(blockHeights, blocks, [&status] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_NE(std::error_code(), status.getStatus());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getBlocksByHashEmpty) {
|
|
|
|
std::vector<Crypto::Hash> blockHashes;
|
2015-07-15 12:23:00 +00:00
|
|
|
std::vector<CryptoNote::BlockDetails> blocks;
|
|
|
|
ASSERT_EQ(blockHashes.size(), 0);
|
|
|
|
ASSERT_EQ(blocks.size(), 0);
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
coreStub.set_blockchain_top(0, boost::value_initialized<Crypto::Hash>());
|
2015-07-15 12:23:00 +00:00
|
|
|
|
|
|
|
CallbackStatus status;
|
|
|
|
node.getBlocks(blockHashes, blocks, [&status] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_EQ(std::error_code(), status.getStatus());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getBlocksByHashMany) {
|
|
|
|
const uint32_t NUMBER_OF_BLOCKS = 10;
|
2015-07-15 12:23:00 +00:00
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
std::vector<Crypto::Hash> blockHashes;
|
2015-07-15 12:23:00 +00:00
|
|
|
std::vector<CryptoNote::BlockDetails> actualBlocks;
|
|
|
|
|
|
|
|
std::vector<CryptoNote::Block> expectedBlocks;
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
coreStub.set_blockchain_top(0, boost::value_initialized<Crypto::Hash>());
|
2015-07-15 12:23:00 +00:00
|
|
|
|
|
|
|
generator.generateEmptyBlocks(NUMBER_OF_BLOCKS);
|
|
|
|
ASSERT_GE(generator.getBlockchain().size(), NUMBER_OF_BLOCKS);
|
|
|
|
|
|
|
|
for (auto iter = generator.getBlockchain().begin() + 1; iter != generator.getBlockchain().end(); iter++) {
|
|
|
|
expectedBlocks.push_back(*iter);
|
|
|
|
blockHashes.push_back(CryptoNote::get_block_hash(*iter));
|
|
|
|
coreStub.addBlock(*iter);
|
|
|
|
}
|
|
|
|
|
|
|
|
ASSERT_GE(blockHashes.size(), NUMBER_OF_BLOCKS);
|
|
|
|
ASSERT_EQ(blockHashes.size(), expectedBlocks.size());
|
|
|
|
ASSERT_EQ(actualBlocks.size(), 0);
|
|
|
|
|
|
|
|
CallbackStatus status;
|
|
|
|
node.getBlocks(blockHashes, actualBlocks, [&status] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_EQ(std::error_code(), status.getStatus());
|
|
|
|
|
|
|
|
ASSERT_EQ(blockHashes.size(), expectedBlocks.size());
|
|
|
|
ASSERT_EQ(blockHashes.size(), actualBlocks.size());
|
|
|
|
auto range1 = boost::combine(blockHashes, expectedBlocks);
|
|
|
|
auto range = boost::combine(range1, actualBlocks);
|
2015-07-30 15:22:07 +00:00
|
|
|
for (const boost::tuple<boost::tuple<Crypto::Hash, CryptoNote::Block>, CryptoNote::BlockDetails>& sameHeight : range) {
|
|
|
|
Crypto::Hash expectedCryptoHash = CryptoNote::get_block_hash(sameHeight.get<0>().get<1>());
|
2015-07-15 12:23:00 +00:00
|
|
|
EXPECT_EQ(expectedCryptoHash, sameHeight.get<0>().get<0>());
|
2015-07-30 15:22:07 +00:00
|
|
|
Hash expectedHash = reinterpret_cast<const Hash&>(expectedCryptoHash);
|
2015-07-15 12:23:00 +00:00
|
|
|
EXPECT_EQ(sameHeight.get<1>().hash, expectedHash);
|
|
|
|
EXPECT_FALSE(sameHeight.get<1>().isOrphaned);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getBlocksByHashFail) {
|
|
|
|
const uint32_t NUMBER_OF_BLOCKS = 10;
|
2015-07-15 12:23:00 +00:00
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
std::vector<Crypto::Hash> blockHashes;
|
2015-07-15 12:23:00 +00:00
|
|
|
std::vector<CryptoNote::BlockDetails> actualBlocks;
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
coreStub.set_blockchain_top(0, boost::value_initialized<Crypto::Hash>());
|
2015-07-15 12:23:00 +00:00
|
|
|
|
|
|
|
generator.generateEmptyBlocks(NUMBER_OF_BLOCKS);
|
|
|
|
ASSERT_LT(generator.getBlockchain().size(), NUMBER_OF_BLOCKS * 2);
|
|
|
|
|
|
|
|
for (const CryptoNote::Block& block : generator.getBlockchain()) {
|
|
|
|
coreStub.addBlock(block);
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
for (uint32_t i = 0; i < NUMBER_OF_BLOCKS * 2; ++i) {
|
|
|
|
blockHashes.push_back(boost::value_initialized<Crypto::Hash>());
|
2015-07-15 12:23:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ASSERT_EQ(actualBlocks.size(), 0);
|
|
|
|
|
|
|
|
CallbackStatus status;
|
|
|
|
node.getBlocks(blockHashes, actualBlocks, [&status] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_NE(std::error_code(), status.getStatus());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getBlocksByHashNotInited) {
|
2015-07-15 12:23:00 +00:00
|
|
|
CryptoNote::InProcessNode newNode(coreStub, protocolQueryStub);
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
std::vector<Crypto::Hash> blockHashes;
|
2015-07-15 12:23:00 +00:00
|
|
|
std::vector<CryptoNote::BlockDetails> blocks;
|
|
|
|
ASSERT_EQ(blockHashes.size(), 0);
|
|
|
|
ASSERT_EQ(blocks.size(), 0);
|
|
|
|
|
|
|
|
CallbackStatus status;
|
|
|
|
newNode.getBlocks(blockHashes, blocks, [&status] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_NE(std::error_code(), status.getStatus());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getTxEmpty) {
|
|
|
|
std::vector<Crypto::Hash> transactionHashes;
|
2015-07-15 12:23:00 +00:00
|
|
|
std::vector<CryptoNote::TransactionDetails> transactions;
|
|
|
|
ASSERT_EQ(transactionHashes.size(), 0);
|
|
|
|
ASSERT_EQ(transactions.size(), 0);
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
coreStub.set_blockchain_top(0, boost::value_initialized<Crypto::Hash>());
|
2015-07-15 12:23:00 +00:00
|
|
|
|
|
|
|
CallbackStatus status;
|
|
|
|
node.getTransactions(transactionHashes, transactions, [&status] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_EQ(std::error_code(), status.getStatus());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getTxMany) {
|
2015-07-15 12:23:00 +00:00
|
|
|
size_t POOL_TX_NUMBER = 10;
|
|
|
|
size_t BLOCKCHAIN_TX_NUMBER = 10;
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
std::vector<Crypto::Hash> transactionHashes;
|
2015-07-15 12:23:00 +00:00
|
|
|
std::vector<CryptoNote::TransactionDetails> actualTransactions;
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
std::vector<std::tuple<CryptoNote::Transaction, Crypto::Hash, uint64_t>> expectedTransactions;
|
2015-07-15 12:23:00 +00:00
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
coreStub.set_blockchain_top(0, boost::value_initialized<Crypto::Hash>());
|
2015-07-15 12:23:00 +00:00
|
|
|
|
|
|
|
size_t prevBlockchainSize = generator.getBlockchain().size();
|
|
|
|
for (size_t i = 0; i < BLOCKCHAIN_TX_NUMBER; ++i) {
|
|
|
|
auto txptr = CryptoNote::createTransaction();
|
|
|
|
auto tx = ::createTx(*txptr.get());
|
2015-07-30 15:22:07 +00:00
|
|
|
transactionHashes.push_back(CryptoNote::getObjectHash(tx));
|
2015-07-15 12:23:00 +00:00
|
|
|
generator.addTxToBlockchain(tx);
|
|
|
|
ASSERT_EQ(generator.getBlockchain().size(), prevBlockchainSize + 1);
|
|
|
|
prevBlockchainSize = generator.getBlockchain().size();
|
|
|
|
coreStub.addBlock(generator.getBlockchain().back());
|
|
|
|
coreStub.addTransaction(tx);
|
2015-07-30 15:22:07 +00:00
|
|
|
expectedTransactions.push_back(std::make_tuple(tx, CryptoNote::get_block_hash(generator.getBlockchain().back()), boost::get<CryptoNote::BaseInput>(generator.getBlockchain().back().baseTransaction.inputs.front()).blockIndex));
|
2015-07-15 12:23:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ASSERT_EQ(transactionHashes.size(), BLOCKCHAIN_TX_NUMBER);
|
|
|
|
ASSERT_EQ(transactionHashes.size(), expectedTransactions.size());
|
|
|
|
ASSERT_EQ(actualTransactions.size(), 0);
|
|
|
|
|
|
|
|
for (size_t i = 0; i < POOL_TX_NUMBER; ++i) {
|
|
|
|
auto txptr = CryptoNote::createTransaction();
|
|
|
|
auto tx = ::createTx(*txptr.get());
|
2015-07-30 15:22:07 +00:00
|
|
|
transactionHashes.push_back(CryptoNote::getObjectHash(tx));
|
2015-07-15 12:23:00 +00:00
|
|
|
coreStub.addTransaction(tx);
|
2015-07-30 15:22:07 +00:00
|
|
|
expectedTransactions.push_back(std::make_tuple(tx, boost::value_initialized<Crypto::Hash>(), boost::value_initialized<uint64_t>()));
|
2015-07-15 12:23:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ASSERT_EQ(transactionHashes.size(), BLOCKCHAIN_TX_NUMBER + POOL_TX_NUMBER);
|
|
|
|
ASSERT_EQ(transactionHashes.size(), expectedTransactions.size());
|
|
|
|
ASSERT_EQ(actualTransactions.size(), 0);
|
|
|
|
|
|
|
|
|
|
|
|
CallbackStatus status;
|
|
|
|
node.getTransactions(transactionHashes, actualTransactions, [&status] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_EQ(std::error_code(), status.getStatus());
|
|
|
|
|
|
|
|
ASSERT_EQ(transactionHashes.size(), expectedTransactions.size());
|
|
|
|
ASSERT_EQ(transactionHashes.size(), actualTransactions.size());
|
|
|
|
auto range1 = boost::combine(transactionHashes, actualTransactions);
|
|
|
|
auto range = boost::combine(range1, expectedTransactions);
|
2015-07-30 15:22:07 +00:00
|
|
|
for (const boost::tuple<boost::tuple<Crypto::Hash, CryptoNote::TransactionDetails>, std::tuple<CryptoNote::Transaction, Crypto::Hash, uint64_t>>& sameHeight : range) {
|
|
|
|
Crypto::Hash expectedCryptoHash = CryptoNote::getObjectHash(std::get<0>(sameHeight.get<1>()));
|
2015-07-15 12:23:00 +00:00
|
|
|
EXPECT_EQ(expectedCryptoHash, sameHeight.get<0>().get<0>());
|
2015-07-30 15:22:07 +00:00
|
|
|
Hash expectedHash = reinterpret_cast<const Hash&>(expectedCryptoHash);
|
2015-07-15 12:23:00 +00:00
|
|
|
EXPECT_EQ(sameHeight.get<0>().get<1>().hash, expectedHash);
|
2015-07-30 15:22:07 +00:00
|
|
|
if (std::get<1>(sameHeight.get<1>()) != boost::value_initialized<Crypto::Hash>()) {
|
2015-07-15 12:23:00 +00:00
|
|
|
EXPECT_TRUE(sameHeight.get<0>().get<1>().inBlockchain);
|
2015-07-30 15:22:07 +00:00
|
|
|
Hash expectedBlockHash = reinterpret_cast<const Hash&>(std::get<1>(sameHeight.get<1>()));
|
2015-07-15 12:23:00 +00:00
|
|
|
EXPECT_EQ(sameHeight.get<0>().get<1>().blockHash, expectedBlockHash);
|
|
|
|
EXPECT_EQ(sameHeight.get<0>().get<1>().blockHeight, std::get<2>(sameHeight.get<1>()));
|
|
|
|
} else {
|
|
|
|
EXPECT_FALSE(sameHeight.get<0>().get<1>().inBlockchain);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getTxFail) {
|
2015-08-27 18:55:14 +00:00
|
|
|
size_t POOL_TX_NUMBER = 10;
|
2015-07-15 12:23:00 +00:00
|
|
|
size_t BLOCKCHAIN_TX_NUMBER = 10;
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
std::vector<Crypto::Hash> transactionHashes;
|
2015-07-15 12:23:00 +00:00
|
|
|
std::vector<CryptoNote::TransactionDetails> actualTransactions;
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
std::vector<std::tuple<CryptoNote::Transaction, Crypto::Hash, uint64_t>> expectedTransactions;
|
2015-07-15 12:23:00 +00:00
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
coreStub.set_blockchain_top(0, boost::value_initialized<Crypto::Hash>());
|
2015-07-15 12:23:00 +00:00
|
|
|
|
|
|
|
size_t prevBlockchainSize = generator.getBlockchain().size();
|
|
|
|
for (size_t i = 0; i < BLOCKCHAIN_TX_NUMBER; ++i) {
|
|
|
|
auto txptr = CryptoNote::createTransaction();
|
|
|
|
auto tx = ::createTx(*txptr.get());
|
2015-07-30 15:22:07 +00:00
|
|
|
transactionHashes.push_back(CryptoNote::getObjectHash(tx));
|
2015-07-15 12:23:00 +00:00
|
|
|
generator.addTxToBlockchain(tx);
|
|
|
|
ASSERT_EQ(generator.getBlockchain().size(), prevBlockchainSize + 1);
|
|
|
|
prevBlockchainSize = generator.getBlockchain().size();
|
|
|
|
coreStub.addBlock(generator.getBlockchain().back());
|
|
|
|
coreStub.addTransaction(tx);
|
2015-07-30 15:22:07 +00:00
|
|
|
expectedTransactions.push_back(std::make_tuple(tx, CryptoNote::get_block_hash(generator.getBlockchain().back()), boost::get<CryptoNote::BaseInput>(generator.getBlockchain().back().baseTransaction.inputs.front()).blockIndex));
|
2015-07-15 12:23:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ASSERT_EQ(transactionHashes.size(), BLOCKCHAIN_TX_NUMBER);
|
|
|
|
ASSERT_EQ(transactionHashes.size(), expectedTransactions.size());
|
|
|
|
ASSERT_EQ(actualTransactions.size(), 0);
|
|
|
|
|
|
|
|
for (size_t i = 0; i < POOL_TX_NUMBER; ++i) {
|
|
|
|
auto txptr = CryptoNote::createTransaction();
|
|
|
|
auto tx = ::createTx(*txptr.get());
|
2015-07-30 15:22:07 +00:00
|
|
|
transactionHashes.push_back(CryptoNote::getObjectHash(tx));
|
|
|
|
expectedTransactions.push_back(std::make_tuple(tx, boost::value_initialized<Crypto::Hash>(), boost::value_initialized<uint64_t>()));
|
2015-07-15 12:23:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ASSERT_EQ(transactionHashes.size(), BLOCKCHAIN_TX_NUMBER + POOL_TX_NUMBER);
|
|
|
|
ASSERT_EQ(transactionHashes.size(), expectedTransactions.size());
|
|
|
|
ASSERT_EQ(actualTransactions.size(), 0);
|
|
|
|
|
|
|
|
|
|
|
|
CallbackStatus status;
|
|
|
|
node.getTransactions(transactionHashes, actualTransactions, [&status] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_NE(std::error_code(), status.getStatus());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getTxNotInited) {
|
2015-07-15 12:23:00 +00:00
|
|
|
CryptoNote::InProcessNode newNode(coreStub, protocolQueryStub);
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
std::vector<Crypto::Hash> transactionHashes;
|
2015-07-15 12:23:00 +00:00
|
|
|
std::vector<CryptoNote::TransactionDetails> transactions;
|
|
|
|
ASSERT_EQ(transactionHashes.size(), 0);
|
|
|
|
ASSERT_EQ(transactions.size(), 0);
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
coreStub.set_blockchain_top(0, boost::value_initialized<Crypto::Hash>());
|
2015-07-15 12:23:00 +00:00
|
|
|
|
|
|
|
CallbackStatus status;
|
|
|
|
newNode.getTransactions(transactionHashes, transactions, [&status] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_NE(std::error_code(), status.getStatus());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, isSynchronized) {
|
2015-07-15 12:23:00 +00:00
|
|
|
bool syncStatus;
|
|
|
|
{
|
|
|
|
CallbackStatus status;
|
|
|
|
node.isSynchronized(syncStatus, [&status] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_EQ(std::error_code(), status.getStatus());
|
|
|
|
ASSERT_FALSE(syncStatus);
|
|
|
|
}
|
|
|
|
|
|
|
|
protocolQueryStub.setSynchronizedStatus(true);
|
|
|
|
|
|
|
|
{
|
|
|
|
CallbackStatus status;
|
|
|
|
node.isSynchronized(syncStatus, [&status] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_EQ(std::error_code(), status.getStatus());
|
|
|
|
ASSERT_TRUE(syncStatus);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, isSynchronizedNotInited) {
|
2015-07-15 12:23:00 +00:00
|
|
|
CryptoNote::InProcessNode newNode(coreStub, protocolQueryStub);
|
|
|
|
bool syncStatus;
|
|
|
|
|
|
|
|
CallbackStatus status;
|
|
|
|
newNode.isSynchronized(syncStatus, [&status] (std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_NE(std::error_code(), status.getStatus());
|
|
|
|
}
|
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
TEST_F(InProcessNodeTests, getLastLocalBlockTimestamp) {
|
|
|
|
class GetBlockTimestampCore : public ICoreStub {
|
|
|
|
public:
|
|
|
|
GetBlockTimestampCore(uint64_t timestamp) : timestamp(timestamp) {}
|
|
|
|
virtual void get_blockchain_top(uint32_t& height, Crypto::Hash& top_id) override {
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool getBlockByHash(const Crypto::Hash &h, CryptoNote::Block &blk) override {
|
|
|
|
blk.timestamp = timestamp;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t timestamp;
|
|
|
|
};
|
|
|
|
|
|
|
|
uint64_t expectedTimestamp = 1234567890;
|
|
|
|
GetBlockTimestampCore core(expectedTimestamp);
|
|
|
|
CryptoNote::InProcessNode newNode(core, protocolQueryStub);
|
|
|
|
|
|
|
|
CallbackStatus initStatus;
|
|
|
|
newNode.init([&initStatus] (std::error_code ec) { initStatus.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(initStatus.wait());
|
|
|
|
|
|
|
|
uint64_t timestamp = newNode.getLastLocalBlockTimestamp();
|
|
|
|
|
|
|
|
ASSERT_EQ(expectedTimestamp, timestamp);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(InProcessNodeTests, getLastLocalBlockTimestampError) {
|
|
|
|
class GetBlockTimestampErrorCore : public ICoreStub {
|
|
|
|
public:
|
|
|
|
virtual void get_blockchain_top(uint32_t& height, Crypto::Hash& top_id) override {
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual bool getBlockByHash(const Crypto::Hash &h, CryptoNote::Block &blk) override {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
GetBlockTimestampErrorCore core;
|
|
|
|
CryptoNote::InProcessNode newNode(core, protocolQueryStub);
|
|
|
|
|
|
|
|
CallbackStatus initStatus;
|
|
|
|
newNode.init([&initStatus] (std::error_code ec) { initStatus.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(initStatus.wait());
|
|
|
|
|
|
|
|
ASSERT_THROW(newNode.getLastLocalBlockTimestamp(), std::exception);
|
|
|
|
}
|
|
|
|
|
2015-08-27 18:55:14 +00:00
|
|
|
TEST_F(InProcessNodeTests, getPoolDiffereceNotInited) {
|
|
|
|
CryptoNote::InProcessNode newNode(coreStub, protocolQueryStub);
|
|
|
|
|
|
|
|
std::vector<Crypto::Hash> knownPoolTxIds;
|
|
|
|
Crypto::Hash knownBlockId = boost::value_initialized<Crypto::Hash>();
|
|
|
|
bool isBcActual = false;
|
|
|
|
std::vector<std::unique_ptr<ITransactionReader>> newTxs;
|
|
|
|
std::vector<Crypto::Hash> deletedTxIds;
|
|
|
|
|
|
|
|
CallbackStatus status;
|
|
|
|
newNode.getPoolSymmetricDifference(std::move(knownPoolTxIds), knownBlockId, isBcActual, newTxs, deletedTxIds, [&status](std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_NE(std::error_code(), status.getStatus());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(InProcessNodeTests, getPoolDiffereceActualBC) {
|
|
|
|
size_t POOL_TX_NUMBER = 10;
|
|
|
|
|
|
|
|
std::unordered_set<Crypto::Hash> transactionHashes;
|
|
|
|
|
|
|
|
coreStub.setPoolChangesResult(true);
|
|
|
|
|
|
|
|
for (size_t i = 0; i < POOL_TX_NUMBER; ++i) {
|
|
|
|
auto txptr = CryptoNote::createTransaction();
|
|
|
|
auto tx = ::createTx(*txptr.get());
|
|
|
|
transactionHashes.insert(CryptoNote::getObjectHash(tx));
|
|
|
|
CryptoNote::tx_verification_context tvc = boost::value_initialized<tx_verification_context>();
|
|
|
|
bool keptByBlock = false;
|
|
|
|
coreStub.handleIncomingTransaction(tx, CryptoNote::getObjectHash(tx), CryptoNote::getObjectBinarySize(tx), tvc, keptByBlock);
|
|
|
|
ASSERT_TRUE(tvc.m_added_to_pool);
|
|
|
|
ASSERT_FALSE(tvc.m_verifivation_failed);
|
|
|
|
}
|
|
|
|
|
|
|
|
ASSERT_EQ(transactionHashes.size(), POOL_TX_NUMBER);
|
|
|
|
|
|
|
|
std::vector<Crypto::Hash> knownPoolTxIds;
|
|
|
|
Crypto::Hash knownBlockId = CryptoNote::getObjectHash(generator.getBlockchain().back());
|
|
|
|
bool isBcActual = false;
|
|
|
|
std::vector<std::unique_ptr<ITransactionReader>> newTxs;
|
|
|
|
std::vector<Crypto::Hash> deletedTxIds;
|
|
|
|
|
|
|
|
CallbackStatus status;
|
|
|
|
node.getPoolSymmetricDifference(std::move(knownPoolTxIds), knownBlockId, isBcActual, newTxs, deletedTxIds, [&status](std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_EQ(std::error_code(), status.getStatus());
|
|
|
|
ASSERT_TRUE(isBcActual);
|
|
|
|
ASSERT_EQ(newTxs.size(), transactionHashes.size());
|
|
|
|
ASSERT_TRUE(deletedTxIds.empty());
|
|
|
|
|
|
|
|
for (const auto& tx : newTxs) {
|
|
|
|
ASSERT_NE(transactionHashes.find(tx->getTransactionHash()), transactionHashes.end());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(InProcessNodeTests, getPoolDiffereceNotActualBC) {
|
|
|
|
size_t POOL_TX_NUMBER = 10;
|
|
|
|
|
|
|
|
std::unordered_set<Crypto::Hash> transactionHashes;
|
|
|
|
|
|
|
|
coreStub.setPoolChangesResult(false);
|
|
|
|
|
|
|
|
for (size_t i = 0; i < POOL_TX_NUMBER; ++i) {
|
|
|
|
auto txptr = CryptoNote::createTransaction();
|
|
|
|
auto tx = ::createTx(*txptr.get());
|
|
|
|
transactionHashes.insert(CryptoNote::getObjectHash(tx));
|
|
|
|
CryptoNote::tx_verification_context tvc = boost::value_initialized<tx_verification_context>();
|
|
|
|
bool keptByBlock = false;
|
|
|
|
coreStub.handleIncomingTransaction(tx, CryptoNote::getObjectHash(tx), CryptoNote::getObjectBinarySize(tx), tvc, keptByBlock);
|
|
|
|
ASSERT_TRUE(tvc.m_added_to_pool);
|
|
|
|
ASSERT_FALSE(tvc.m_verifivation_failed);
|
|
|
|
}
|
|
|
|
|
|
|
|
ASSERT_EQ(transactionHashes.size(), POOL_TX_NUMBER);
|
|
|
|
|
|
|
|
std::vector<Crypto::Hash> knownPoolTxIds;
|
|
|
|
Crypto::Hash knownBlockId = CryptoNote::getObjectHash(generator.getBlockchain().back());
|
|
|
|
bool isBcActual = false;
|
|
|
|
std::vector<std::unique_ptr<ITransactionReader>> newTxs;
|
|
|
|
std::vector<Crypto::Hash> deletedTxIds;
|
|
|
|
|
|
|
|
CallbackStatus status;
|
|
|
|
node.getPoolSymmetricDifference(std::move(knownPoolTxIds), knownBlockId, isBcActual, newTxs, deletedTxIds, [&status](std::error_code ec) { status.setStatus(ec); });
|
|
|
|
ASSERT_TRUE(status.wait());
|
|
|
|
ASSERT_EQ(std::error_code(), status.getStatus());
|
|
|
|
ASSERT_FALSE(isBcActual);
|
|
|
|
ASSERT_EQ(newTxs.size(), transactionHashes.size());
|
|
|
|
ASSERT_TRUE(deletedTxIds.empty());
|
|
|
|
|
|
|
|
for (const auto& tx : newTxs) {
|
|
|
|
ASSERT_NE(transactionHashes.find(tx->getTransactionHash()), transactionHashes.end());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-06 16:13:07 +00:00
|
|
|
//TODO: make relayTransaction unit test
|
|
|
|
//TODO: make getNewBlocks unit test
|
|
|
|
//TODO: make queryBlocks unit test
|