Skip to content

Commit

Permalink
High level API from BCN
Browse files Browse the repository at this point in the history
  • Loading branch information
ducknote committed Aug 12, 2014
1 parent b4a27b9 commit 5ba1c9f
Show file tree
Hide file tree
Showing 44 changed files with 4,619 additions and 23 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_CONFIGURATION_TYPES "Debug;Release")
enable_testing()

include_directories(src contrib/epee/include external "${CMAKE_BINARY_DIR}/version")
include_directories(include src contrib/epee/include external "${CMAKE_BINARY_DIR}/version")
if(APPLE)
include_directories(SYSTEM /usr/include/malloc)
endif()
Expand Down
45 changes: 33 additions & 12 deletions include/INode.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,54 @@
#pragma once

#include <cstdint>
#include <functional>
#include <system_error>
#include <vector>

#include "crypto/crypto.h"
#include "cryptonote_core/cryptonote_basic.h"
#include "cryptonote_protocol/cryptonote_protocol_defs.h"
#include "rpc/core_rpc_server_commands_defs.h"

namespace CryptoNote {

class INodeObserver {
public:
virtual void initCompleted(std::error_code result) {}

virtual ~INodeObserver() {}
virtual void peerCountUpdated(size_t count) {}
virtual void lastLocalBlockHeightUpdated(uint64_t height) {}
virtual void localBlockchainUpdated(uint64_t height) {}
virtual void lastKnownBlockHeightUpdated(uint64_t height) {}
};

virtual void blockchainReorganized(uint64_t height) {}
struct OutEntry {
uint64_t outGlobalIndex;
crypto::public_key outKey;
};

struct OutsForAmount {
uint64_t amount;
std::vector<OutEntry> outs;
};

class INode {
public:
virtual ~INode() = 0;
virtual void addObserver(INodeObserver* observer) = 0;
virtual void removeObserver(INodeObserver* observer) = 0;
typedef std::function<void(std::error_code)> Callback;

virtual ~INode() {}
virtual bool addObserver(INodeObserver* observer) = 0;
virtual bool removeObserver(INodeObserver* observer) = 0;

virtual void init(const Callback& callback) = 0;
virtual bool shutdown() = 0;

virtual void init() = 0;
virtual void shutdown() = 0;
virtual size_t getPeerCount() const = 0;
virtual uint64_t getLastLocalBlockHeight() const = 0;
virtual uint64_t getLastKnownBlockHeight() const = 0;

virtual size_t getPeerCount() = 0;
virtual uint64_t getLastLocalBlockHeight() = 0;
virtual uint64_t getLastKnownBlockHeight() = 0;
virtual void relayTransaction(const cryptonote::transaction& transaction, const Callback& callback) = 0;
virtual void getRandomOutsByAmounts(std::vector<uint64_t>&& amounts, uint64_t outsCount, std::vector<cryptonote::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount>& result, const Callback& callback) = 0;
virtual void getNewBlocks(std::list<crypto::hash>&& knownBlockIds, std::list<cryptonote::block_complete_entry>& newBlocks, uint64_t& startHeight, const Callback& callback) = 0;
virtual void getTransactionOutsGlobalIndices(const crypto::hash& transactionHash, std::vector<uint64_t>& outsGlobalIndices, const Callback& callback) = 0;
};

}
8 changes: 4 additions & 4 deletions include/IWallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace CryptoNote {

typedef size_t TransactionId;
typedef size_t TransferId;
typedef std::array<uint8_t, 32> TransacitonHash;
typedef std::array<uint8_t, 32> TransactionHash;

struct Transfer {
std::string address;
Expand All @@ -33,7 +33,7 @@ struct Transaction {
size_t transferCount;
int64_t totalAmount;
uint64_t fee;
TransacitonHash hash;
TransactionHash hash;
bool isCoinbase;
uint64_t blockHeight;
uint64_t timestamp;
Expand All @@ -44,7 +44,7 @@ class IWalletObserver {
public:
virtual void initCompleted(std::error_code result) {}
virtual void saveCompleted(std::error_code result) {}
virtual void synchronizationProgressUpdated(uint64_t current, uint64_t total) {}
virtual void synchronizationProgressUpdated(uint64_t current, uint64_t total, std::error_code result) {}
virtual void actualBalanceUpdated(uint64_t actualBalance) {}
virtual void pendingBalanceUpdated(uint64_t pendingBalance) {}
virtual void externalTransactionCreated(TransactionId transactionId) {}
Expand All @@ -54,7 +54,7 @@ class IWalletObserver {

class IWallet {
public:
virtual ~IWallet() = 0;
virtual ~IWallet() {} ;
virtual void addObserver(IWalletObserver* observer) = 0;
virtual void removeObserver(IWalletObserver* observer) = 0;

Expand Down
6 changes: 5 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ file(GLOB_RECURSE SIMPLEWALLET simplewallet/*)
file(GLOB_RECURSE CONN_TOOL connectivity_tool/*)
file(GLOB_RECURSE WALLET wallet/*)
file(GLOB_RECURSE MINER miner/*)
file(GLOB_RECURSE NODE_RPC_PROXY node_rpc_proxy/*)

source_group(common FILES ${COMMON})
source_group(crypto FILES ${CRYPTO})
Expand All @@ -23,6 +24,7 @@ source_group(simplewallet FILES ${SIMPLEWALLET})
source_group(connectivity-tool FILES ${CONN_TOOL})
source_group(wallet FILES ${WALLET})
source_group(simpleminer FILES ${MINER})
source_group(node_rpc_proxy FILES ${NODE_RPC_PROXY})

add_library(common ${COMMON})
add_library(crypto ${CRYPTO})
Expand All @@ -37,10 +39,12 @@ add_library(rpc ${RPC})
add_library(wallet ${WALLET})
add_executable(simplewallet ${SIMPLEWALLET} )
target_link_libraries(simplewallet wallet rpc cryptonote_core crypto common upnpc-static ${Boost_LIBRARIES})
add_library(node_rpc_proxy ${NODE_RPC_PROXY})

add_dependencies(daemon version)
add_dependencies(rpc version)
add_dependencies(simplewallet version)

set_property(TARGET common crypto cryptonote_core rpc wallet PROPERTY FOLDER "libs")
set_property(TARGET common crypto cryptonote_core rpc wallet node_rpc_proxy PROPERTY FOLDER "libs")
set_property(TARGET daemon simplewallet connectivity_tool simpleminer PROPERTY FOLDER "prog")
set_property(TARGET daemon PROPERTY OUTPUT_NAME "ducknoted")
117 changes: 117 additions & 0 deletions src/common/ObserverManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#pragma once

#include <mutex>
#include <vector>
#include <algorithm>

namespace tools {

template<typename T>
class ObserverManager {
public:
bool add(T* observer) {
std::unique_lock<std::mutex> lock(m_observersMutex);
auto it = std::find(m_observers.begin(), m_observers.end(), observer);
if (m_observers.end() == it) {
m_observers.push_back(observer);
return true;
} else {
return false;
}
}

bool remove(T* observer) {
std::unique_lock<std::mutex> lock(m_observersMutex);
auto it = std::find(m_observers.begin(), m_observers.end(), observer);
if (m_observers.end() == it) {
return false;
} else {
m_observers.erase(it);
return true;
}
}

void clear() {
std::unique_lock<std::mutex> lock(m_observersMutex);
m_observers.clear();
}

#if defined(_MSC_VER)
template<typename F>
void notify(F notification) {
std::vector<T*> observersCopy;
{
std::unique_lock<std::mutex> lock(m_observersMutex);
observersCopy = m_observers;
}

for (T* observer : observersCopy) {
(observer->*notification)();
}
}

template<typename F, typename Arg0>
void notify(F notification, const Arg0& arg0) {
std::vector<T*> observersCopy;
{
std::unique_lock<std::mutex> lock(m_observersMutex);
observersCopy = m_observers;
}

for (T* observer : observersCopy) {
(observer->*notification)(arg0);
}
}

template<typename F, typename Arg0, typename Arg1>
void notify(F notification, const Arg0& arg0, const Arg1& arg1) {
std::vector<T*> observersCopy;
{
std::unique_lock<std::mutex> lock(m_observersMutex);
observersCopy = m_observers;
}

for (T* observer : observersCopy) {
(observer->*notification)(arg0, arg1);
}
}

template<typename F, typename Arg0, typename Arg1, typename Arg2>
void notify(F notification, const Arg0& arg0, const Arg1& arg1, const Arg2& arg2) {
std::vector<T*> observersCopy;
{
std::unique_lock<std::mutex> lock(m_observersMutex);
observersCopy = m_observers;
}

for (T* observer : observersCopy) {
(observer->*notification)(arg0, arg1, arg2);
}
}

#else

template<typename F, typename... Args>
void notify(F notification, Args... args) {
std::vector<T*> observersCopy;
{
std::unique_lock<std::mutex> lock(m_observersMutex);
observersCopy = m_observers;
}

for (T* observer : observersCopy) {
(observer->*notification)(args...);
}
}
#endif

private:
std::vector<T*> m_observers;
std::mutex m_observersMutex;
};

}
21 changes: 21 additions & 0 deletions src/cryptonote_core/cryptonote_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,27 @@ namespace cryptonote
update_miner_block_template();
return true;
}

void core::notify_new_block(const block& b) {
cryptonote_connection_context exclude_context = boost::value_initialized<cryptonote_connection_context>();
NOTIFY_NEW_BLOCK::request arg = AUTO_VAL_INIT(arg);
arg.hop = 0;
arg.current_blockchain_height = m_blockchain_storage.get_current_blockchain_height();
std::list<crypto::hash> missed_txs;
std::list<transaction> txs;
m_blockchain_storage.get_transactions(b.tx_hashes, txs, missed_txs);
if (missed_txs.size() > 0 && m_blockchain_storage.get_block_id_by_height(get_block_height(b)) != get_block_hash(b)) {
LOG_PRINT_L0("Block found but reorganize happened after that, block will not be relayed");
} else {
if (txs.size() != b.tx_hashes.size() || missed_txs.size()) {
LOG_ERROR("cant find some transactions in found block:" << get_block_hash(b) << " txs.size()=" << txs.size() << ", b.tx_hashes.size()=" << b.tx_hashes.size() << ", missed_txs.size()" << missed_txs.size());
return;
}
block_to_blob(b, arg.b.block);
BOOST_FOREACH(auto& tx, txs) arg.b.txs.push_back(t_serializable_object_to_blob(tx));
m_pprotocol->relay_block(arg, exclude_context);
}
}
//-----------------------------------------------------------------------------------------------
crypto::hash core::get_tail_id()
{
Expand Down
1 change: 1 addition & 0 deletions src/cryptonote_core/cryptonote_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ namespace cryptonote
std::string print_pool(bool short_format);
void print_blockchain_outs(const std::string& file);
void on_synchronized();
void notify_new_block(const block& b);

private:
bool add_new_tx(const transaction& tx, const crypto::hash& tx_hash, const crypto::hash& tx_prefix_hash, size_t blob_size, tx_verification_context& tvc, bool keeped_by_block);
Expand Down
83 changes: 83 additions & 0 deletions src/node_rpc_proxy/InitState.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#pragma once

#include <atomic>

#include "include_base_utils.h"

namespace tools {

class InitState {
public:
InitState() : m_state(STATE_NOT_INITIALIZED) {
}

bool initialized() const volatile {
return STATE_INITIALIZED == m_state.load(std::memory_order_acquire);
}

bool beginInit() volatile {
State state = STATE_NOT_INITIALIZED;
if (!m_state.compare_exchange_strong(state, STATE_INITIALIZING, std::memory_order_seq_cst)) {
LOG_ERROR("object has been already initialized");
return false;
}
return true;
}

bool endInit() volatile {
State expectedState = STATE_INITIALIZING;
if (!m_state.compare_exchange_strong(expectedState, STATE_INITIALIZED, std::memory_order_seq_cst)) {
LOG_ERROR("Unexpected state: " << expectedState);
return false;
}
return true;
}

bool beginShutdown() volatile {
while (true) {
State state = m_state.load(std::memory_order_relaxed);
if (STATE_NOT_INITIALIZED == state) {
return true;
} else if (STATE_INITIALIZING == state) {
LOG_ERROR("Object is being initialized");
return false;
} else if (STATE_INITIALIZED == state) {
if (m_state.compare_exchange_strong(state, STATE_SHUTTING_DOWN, std::memory_order_seq_cst)) {
return true;
}
} else if (STATE_SHUTTING_DOWN == state) {
LOG_ERROR("Object is being shutting down");
return false;
} else {
LOG_ERROR("Unknown state " << state);
return false;
}
}
}

bool endShutdown() volatile {
State expectedState = STATE_SHUTTING_DOWN;
if (!m_state.compare_exchange_strong(expectedState, STATE_NOT_INITIALIZED, std::memory_order_seq_cst)) {
LOG_ERROR("Unexpected state: " << expectedState);
return false;
}
return true;
}

private:
enum State {
STATE_NOT_INITIALIZED,
STATE_INITIALIZING,
STATE_INITIALIZED,
STATE_SHUTTING_DOWN
};

private:
std::atomic<State> m_state;
};

}
13 changes: 13 additions & 0 deletions src/node_rpc_proxy/NodeErrors.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "NodeErrors.h"

namespace cryptonote {
namespace error {

NodeErrorCategory NodeErrorCategory::INSTANCE;

}
}
Loading

0 comments on commit 5ba1c9f

Please sign in to comment.