Skip to content

Commit

Permalink
Simplewallet improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
Antonio Juarez committed Jul 9, 2015
1 parent ad291f5 commit 6d45be9
Show file tree
Hide file tree
Showing 14 changed files with 439 additions and 58 deletions.
6 changes: 5 additions & 1 deletion src/Common/SignalHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ namespace {

void handleSignal() {
static std::mutex m_mutex;
std::unique_lock<std::mutex> lock(m_mutex);
std::unique_lock<std::mutex> lock(m_mutex, std::try_to_lock);
if (!lock.owns_lock()) {
return;
}
m_handler();
}

Expand Down Expand Up @@ -75,6 +78,7 @@ namespace tools {
#else
signal(SIGINT, posixHandler);
signal(SIGTERM, posixHandler);
signal(SIGPIPE, SIG_IGN);
m_handler = t;
return true;
#endif
Expand Down
4 changes: 0 additions & 4 deletions src/Platform/OSX/System/TcpConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,6 @@ std::pair<Ipv4Address, uint16_t> TcpConnection::getPeerAddressAndPort() {
}

TcpConnection::TcpConnection(Dispatcher& dispatcher, int socket) : dispatcher(&dispatcher), connection(socket), stopped(false), readContext(nullptr), writeContext(nullptr) {
int val = 1;
if (setsockopt(connection, SOL_SOCKET, SO_NOSIGPIPE, (void*)&val, sizeof val) == -1) {
throw std::runtime_error("TcpConnection::TcpConnection, setsockopt failed, result=" + std::to_string(errno));
}
}

}
3 changes: 2 additions & 1 deletion src/cryptonote_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ const CheckpointData CHECKPOINTS[] = {
{667000, "a020c8fcaa567845d04b520bb7ebe721e097a9bed2bdb8971081f933b5b42995"},
{689000, "212ec2698c5ebd15d6242d59f36c2d186d11bb47c58054f476dd8e6b1c7f0008"},
{713000, "a03f836c4a19f907cd6cac095eb6f56f5279ca2d1303fb7f826750dcb9025495"},
{750300, "5117631dbeb5c14748a91127a515ecbf13f6849e14fda7ee03cd55da41f1710c"}
{750300, "5117631dbeb5c14748a91127a515ecbf13f6849e14fda7ee03cd55da41f1710c"},
{780000, "8dd55a9bae429e3685b90317281e633917023d3512eb7f37372209d1a5fc1070"}
};
} // CryptoNote

Expand Down
47 changes: 32 additions & 15 deletions src/p2p/net_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,11 @@ namespace CryptoNote
m_idleTimer.stop();
m_timedSyncTimer.stop();

logger(INFO) << "Stopping " << m_connections.size() << " connections";
logger(INFO) << "Stopping " << m_connections.size() + m_raw_connections.size() << " connections";

for (auto& conn : m_raw_connections) {
conn.second.connection.stop();
}

for (auto& conn : m_connections) {
conn.second.connection.stop();
Expand Down Expand Up @@ -671,32 +675,44 @@ namespace CryptoNote
ctx.m_is_income = false;
ctx.m_started = time(nullptr);

CryptoNote::LevinProtocol proto(ctx.connection);
auto raw = m_raw_connections.emplace(ctx.m_connection_id, std::move(ctx)).first;
try {
CryptoNote::LevinProtocol proto(raw->second.connection);

if (!handshake(proto, ctx, just_take_peerlist)) {
logger(WARNING) << "Failed to HANDSHAKE with peer " << na;
return false;
if (!handshake(proto, raw->second, just_take_peerlist)) {
logger(WARNING) << "Failed to HANDSHAKE with peer " << na;
m_raw_connections.erase(raw);
return false;
}
} catch (...) {
m_raw_connections.erase(raw);
throw;
}

if (just_take_peerlist) {
logger(Logging::DEBUGGING, Logging::BRIGHT_GREEN) << ctx << "CONNECTION HANDSHAKED OK AND CLOSED.";
logger(Logging::DEBUGGING, Logging::BRIGHT_GREEN) << raw->second << "CONNECTION HANDSHAKED OK AND CLOSED.";
m_raw_connections.erase(raw);
return true;
}

peerlist_entry pe_local = AUTO_VAL_INIT(pe_local);
pe_local.adr = na;
pe_local.id = ctx.peer_id;
pe_local.id = raw->second.peer_id;
time(&pe_local.last_seen);
m_peerlist.append_with_peer_white(pe_local);

if (m_stop) {
m_raw_connections.erase(raw);
throw System::InterruptedException();
}

auto iter = m_connections.emplace(ctx.m_connection_id, std::move(ctx)).first;
auto iter = m_connections.emplace(raw->first, std::move(raw->second)).first;
m_raw_connections.erase(raw);
const boost::uuids::uuid& connectionId = iter->first;
p2p_connection_context& connectionContext = iter->second;

++m_spawnCount;
m_dispatcher.spawn(std::bind(&node_server::connectionHandler, this, iter));
m_dispatcher.spawn(std::bind(&node_server::connectionHandler, this, std::cref(connectionId), std::ref(connectionContext)));

return true;
} catch (System::InterruptedException&) {
Expand Down Expand Up @@ -1219,9 +1235,11 @@ namespace CryptoNote
ctx.m_remote_port = addressAndPort.second;

auto iter = m_connections.emplace(ctx.m_connection_id, std::move(ctx)).first;
const boost::uuids::uuid& connectionId = iter->first;
p2p_connection_context& connection = iter->second;

++m_spawnCount;
m_dispatcher.spawn(std::bind(&node_server::connectionHandler, this, iter));
m_dispatcher.spawn(std::bind(&node_server::connectionHandler, this, std::cref(connectionId), std::ref(connection)));
}
} catch (System::InterruptedException&) {
} catch (const std::exception& e) {
Expand Down Expand Up @@ -1274,10 +1292,9 @@ namespace CryptoNote
}
}

void node_server::connectionHandler(ConnectionIterator connIter) {
void node_server::connectionHandler(const boost::uuids::uuid& connectionId, p2p_connection_context& ctx) {

try {
auto& ctx = connIter->second;
on_connection_new(ctx);

LevinProtocol proto(ctx.connection);
Expand Down Expand Up @@ -1320,10 +1337,10 @@ namespace CryptoNote
logger(WARNING) << "Exception in connectionHandler: " << e.what();
}

connIter->second.writeLatch.wait();
ctx.writeLatch.wait();

on_connection_close(connIter->second);
m_connections.erase(connIter);
on_connection_close(ctx);
m_connections.erase(connectionId);

if (--m_spawnCount == 0) {
m_shutdownCompleteEvent.set();
Expand Down
3 changes: 2 additions & 1 deletion src/p2p/net_node.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,11 @@ namespace CryptoNote

typedef std::unordered_map<boost::uuids::uuid, p2p_connection_context, boost::hash<boost::uuids::uuid>> ConnectionContainer;
typedef ConnectionContainer::iterator ConnectionIterator;
ConnectionContainer m_raw_connections;
ConnectionContainer m_connections;

void acceptLoop();
void connectionHandler(ConnectionIterator connIter);
void connectionHandler(const boost::uuids::uuid& connectionId, p2p_connection_context& connection);
void onIdle();
void timedSyncLoop();

Expand Down
2 changes: 1 addition & 1 deletion src/simplewallet/simplewallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ bool simple_wallet::listTransfers(const std::vector<std::string>& args) {
for (size_t trantransactionNumber = 0; trantransactionNumber < transactionsCount; ++trantransactionNumber) {
TransactionInfo txInfo;
m_wallet->getTransaction(trantransactionNumber, txInfo);
if (txInfo.state != TransactionState::Active) {
if (txInfo.state != TransactionState::Active || txInfo.blockHeight == UNCONFIRMED_TRANSACTION_HEIGHT) {
continue;
}

Expand Down
1 change: 0 additions & 1 deletion src/transfers/BlockchainSynchronizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ class BlockchainSynchronizer :
INode& m_node;
const crypto::hash m_genesisBlockHash;

std::vector<crypto::hash> knownTxIds;
crypto::hash lastBlockId;

State m_currentState;
Expand Down
4 changes: 2 additions & 2 deletions src/version.h.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#define BUILD_COMMIT_ID "@VERSION@"
#define PROJECT_VERSION "1.0.4"
#define PROJECT_VERSION_BUILD_NO "461"
#define PROJECT_VERSION "1.0.4.1"
#define PROJECT_VERSION_BUILD_NO "466"
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO "(" BUILD_COMMIT_ID ")"
71 changes: 40 additions & 31 deletions src/wallet/Wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@
// along with Bytecoin. If not, see <http:https://www.gnu.org/licenses/>.

#include "Wallet.h"
#include "serialization/binary_utils.h"
#include "WalletUtils.h"
#include "WalletSerializer.h"

#include <time.h>
#include <string.h>
#include <time.h>

#include "serialization/binary_utils.h"
#include "WalletHelper.h"
#include "WalletSerialization.h"
#include "WalletSerializer.h"
#include "WalletUtils.h"

namespace {

Expand Down Expand Up @@ -93,6 +94,7 @@ class SaveWaiter : public CryptoNote::IWalletObserver {
std::promise<std::error_code> promise;
std::future<std::error_code> future;
};

} //namespace

namespace CryptoNote {
Expand Down Expand Up @@ -125,7 +127,6 @@ Wallet::Wallet(const CryptoNote::Currency& currency, INode& node) :
m_onInitSyncStarter(new SyncStarter(m_blockchainSync))
{
addObserver(m_onInitSyncStarter.get());
m_blockchainSync.addObserver(this);
}

Wallet::~Wallet() {
Expand All @@ -139,10 +140,10 @@ Wallet::~Wallet() {
}
}

m_blockchainSync.removeObserver(this);
m_blockchainSync.stop();
m_asyncContextCounter.waitAsyncContextsFinish();
m_sender.release();
m_blockchainSync.removeObserver(this);
m_blockchainSync.stop();
m_asyncContextCounter.waitAsyncContextsFinish();
m_sender.release();
}

void Wallet::addObserver(IWalletObserver* observer) {
Expand Down Expand Up @@ -215,7 +216,7 @@ void Wallet::initAndLoad(std::istream& source, const std::string& password) {

m_password = password;
m_state = LOADING;

m_asyncContextCounter.addAsyncContext();
std::thread loader(&Wallet::doLoad, this, std::ref(source));
loader.detach();
Expand All @@ -234,6 +235,8 @@ void Wallet::initSync() {

m_sender.reset(new WalletTransactionSender(m_currency, m_transactionsCache, m_account.get_keys(), *m_transferDetails));
m_state = INITIALIZED;

m_blockchainSync.addObserver(this);
}

void Wallet::doLoad(std::istream& source) {
Expand All @@ -248,20 +251,18 @@ void Wallet::doLoad(std::istream& source) {
initSync();

try {
if (!cache.empty()) {
std::stringstream stream(cache);
m_transfersSync.load(stream);
}
if (!cache.empty()) {
std::stringstream stream(cache);
m_transfersSync.load(stream);
}
} catch (const std::exception&) {
// ignore cache loading errors
}
}
catch (std::system_error& e) {
}
} catch (std::system_error& e) {
runAtomic(m_cacheMutex, [this] () {this->m_state = Wallet::NOT_INITIALIZED;} );
m_observerManager.notify(&IWalletObserver::initCompleted, e.code());
return;
}
catch (std::exception&) {
} catch (std::exception&) {
runAtomic(m_cacheMutex, [this] () {this->m_state = Wallet::NOT_INITIALIZED;} );
m_observerManager.notify(&IWalletObserver::initCompleted, make_error_code(CryptoNote::error::INTERNAL_WALLET_ERROR));
return;
Expand Down Expand Up @@ -295,31 +296,39 @@ void Wallet::shutdown() {
std::unique_lock<std::mutex> lock(m_cacheMutex);
m_isStopping = false;
m_state = NOT_INITIALIZED;

const AccountAddress& accountAddress = reinterpret_cast<const AccountAddress&>(m_account.get_keys().m_account_address);
auto subObject = m_transfersSync.getSubscription(accountAddress);
assert(subObject != nullptr);
subObject->removeObserver(this);
m_transfersSync.removeSubscription(accountAddress);
m_transferDetails = nullptr;

m_transactionsCache.reset();
m_lastNotifiedActualBalance = 0;
m_lastNotifiedPendingBalance = 0;
}
}

void Wallet::reset() {
InitWaiter initWaiter;
SaveWaiter saveWaiter;

addObserver(&initWaiter);
addObserver(&saveWaiter);
WalletHelper::IWalletRemoveObserverGuard initGuarantee(*this, initWaiter);
WalletHelper::IWalletRemoveObserverGuard saveGuarantee(*this, saveWaiter);

std::stringstream ss;
try {
save(ss, false, false);
save(ss, false, false);

auto saveError = saveWaiter.waitSave();
if (!saveError) {
shutdown();
initAndLoad(ss, m_password);
if (!saveError) {
shutdown();
initAndLoad(ss, m_password);
initWaiter.waitInit();
}
} catch (std::exception& e) {
std::cout << "exception in reset: " << e.what() << std::endl;
}
} catch (std::exception&) {
}

removeObserver(&saveWaiter);
removeObserver(&initWaiter);
}

void Wallet::save(std::ostream& destination, bool saveDetailed, bool saveCache) {
Expand Down
4 changes: 4 additions & 0 deletions src/wallet/WalletUnconfirmedTransactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,5 +123,9 @@ void WalletUnconfirmedTransactions::collectUsedOutputs() {
m_usedOutputs = std::move(used);
}

void WalletUnconfirmedTransactions::reset() {
m_unconfirmedTxs.clear();
m_usedOutputs.clear();
}

} /* namespace CryptoNote */
1 change: 1 addition & 0 deletions src/wallet/WalletUnconfirmedTransactions.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class WalletUnconfirmedTransactions
uint64_t countUnconfirmedOutsAmount() const;
uint64_t countUnconfirmedTransactionsAmount() const;
bool isUsed(const TransactionOutputInformation& out) const;
void reset();

private:

Expand Down
6 changes: 6 additions & 0 deletions src/wallet/WalletUserTransactionsCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,5 +293,11 @@ void WalletUserTransactionsCache::updateUnconfirmedTransactions() {
Transfer& WalletUserTransactionsCache::getTransfer(TransferId transferId) {
return m_transfers.at(transferId);
}

void WalletUserTransactionsCache::reset() {
m_transactions.clear();
m_transfers.clear();
m_unconfirmedTransactions.reset();
}

} //namespace CryptoNote
1 change: 1 addition & 0 deletions src/wallet/WalletUserTransactionsCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class WalletUserTransactionsCache
Transfer& getTransfer(TransferId transferId);

bool isUsed(const TransactionOutputInformation& out) const;
void reset();

private:

Expand Down
Loading

0 comments on commit 6d45be9

Please sign in to comment.