Skip to content

Commit

Permalink
Feature/fusion (cryptonotefoundation#9)
Browse files Browse the repository at this point in the history
* Update core and bring back zero mixin to send

* Added fusion to WalletAdapter

* Added background wallet optimization (fusion transactions)

* Fixed mixin for fusion transactions

* Minor changes in optimization settings dialog

* Added translation of fusion related strings (incomplete)
  • Loading branch information
aivve authored Nov 25, 2018
1 parent ab6652e commit d201d73
Show file tree
Hide file tree
Showing 46 changed files with 4,353 additions and 794 deletions.
3 changes: 3 additions & 0 deletions src/Languages.pro
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ gui/VerifyMnemonicSeedDialog.cpp \
gui/NoWalletFrame.cpp \
gui/SendGlassFrame.cpp \
gui/SignMessageDialog.cpp \
gui/OptimizationSettings.cpp \


HEADERS = CommandLineParser.h \
Expand Down Expand Up @@ -129,6 +130,7 @@ gui/VerifyMnemonicSeedDialog.h \
gui/NoWalletFrame.h \
gui/SendGlassFrame.h \
gui/SignMessageDialog.h \
gui/OptimizationSettings.h \

FORMS = gui/ui/aboutdialog.ui \
Expand Down Expand Up @@ -166,6 +168,7 @@ gui/ui/restorefrommnemonicseeddialog.ui \
gui/ui/verifymnemonicseeddialog.ui \
gui/ui/nowalletframe.ui \
gui/ui/signmessagedialog.ui \
gui/ui/optimizationsettingsdialog.ui \

TRANSLATIONS = languages/uk.ts \
Expand Down
157 changes: 157 additions & 0 deletions src/OptimizationManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// Copyright (c) 2015-2017, The Bytecoin developers
// Copyright (c) 2018, The Karbo developers
//
// This file is part of Karbovanets.
//
// Karbovanets is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Karbovanets is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Karbovanets. If not, see <http://www.gnu.org/licenses/>.

#include <QTime>
#include <QTimerEvent>

#include "OptimizationManager.h"
#include "WalletAdapter.h"
#include "gui/WalletEvents.h"
#include "NodeAdapter.h"
#include "Settings.h"

namespace WalletGui {

namespace {

const int CHECK_TIMER_INTERVAL = 1000;

}

OptimizationManager::OptimizationManager(QObject* _parent) : QObject(_parent),
m_checkTimerId(-1), m_optimizationTimerId(-1), m_currentOptimizationInterval(0), m_isSynchronized(false) {
connect(&WalletAdapter::instance(), &WalletAdapter::walletInitCompletedSignal, this, &OptimizationManager::walletOpened);
connect(&WalletAdapter::instance(), &WalletAdapter::walletCloseCompletedSignal, this, &OptimizationManager::walletClosed);
connect(&WalletAdapter::instance(), &WalletAdapter::walletSynchronizationProgressUpdatedSignal, this, &OptimizationManager::synchronizationProgressUpdated, Qt::QueuedConnection);
connect(&WalletAdapter::instance(), &WalletAdapter::walletSynchronizationCompletedSignal, this, &OptimizationManager::synchronizationCompleted, Qt::QueuedConnection);
}

OptimizationManager::~OptimizationManager() {
}

void OptimizationManager::walletOpened() {
Q_ASSERT(m_checkTimerId == -1);
m_checkTimerId = startTimer(CHECK_TIMER_INTERVAL);
}

void OptimizationManager::walletClosed() {
if (m_checkTimerId != -1) {
killTimer(m_checkTimerId);
m_checkTimerId = -1;
}

if (m_optimizationTimerId != -1) {
killTimer(m_optimizationTimerId);
m_optimizationTimerId = -1;
}
}

void OptimizationManager::synchronizationProgressUpdated() {
m_isSynchronized = false;
}

void OptimizationManager::synchronizationCompleted() {
m_isSynchronized = true;
}

void OptimizationManager::timerEvent(QTimerEvent* _event) {
if (_event->timerId() == m_checkTimerId) {
checkOptimization();
} else if (_event->timerId() == m_optimizationTimerId) {
optimize();
}

QObject::timerEvent(_event);
}

void OptimizationManager::checkOptimization() {
if (Settings::instance().isOptimizationEnabled()) {
bool customTimeEnabled = Settings::instance().isOptimizationTimeSetManually();
QTime startTime = Settings::instance().getOptimizationStartTime();
QTime stopTime = Settings::instance().getOptimizationStopTime();
QTime currentTime = QTime::currentTime();
if (!customTimeEnabled || startTime == stopTime) {
ensureStarted();
} else if (stopTime > startTime) {
if (currentTime >= startTime && currentTime < stopTime) {
ensureStarted();
} else {
ensureStopped();
}
} else {
if ((currentTime >= startTime && currentTime < QTime(0, 0)) || (currentTime >= QTime(0, 0) && currentTime < stopTime)) {
ensureStarted();
} else {
ensureStopped();
}
}
} else {
ensureStopped();
}
}

void OptimizationManager::optimize() {
if (!m_isSynchronized) {
return;
}

Q_ASSERT(WalletAdapter::instance().isOpen());
if (Settings::instance().isTrackingMode()) {
return;
}

size_t fusionReadyCount = WalletAdapter::instance().estimateFusion(CurrencyAdapter::instance().getMinimumFee());
const size_t MAX_FUSION_OUTPUT_COUNT = 4;
const quint64 mixin = Settings::instance().getOptimizationMixin();
size_t estimatedFusionInputsCount = CurrencyAdapter::instance().getCurrency().getApproximateMaximumInputCount(CurrencyAdapter::instance().getCurrency().fusionTxMaxSize(), MAX_FUSION_OUTPUT_COUNT, mixin);
if (estimatedFusionInputsCount < CurrencyAdapter::instance().getCurrency().fusionTxMinInputCount()) {
// Mixin is too big
return;
}
std::list<CryptoNote::TransactionOutputInformation> fusionInputs = WalletAdapter::instance().getFusionTransfersToSend(Settings::instance().getOptimizationThreshold(), CurrencyAdapter::instance().getCurrency().fusionTxMinInputCount(), estimatedFusionInputsCount);
if (fusionInputs.size() < CurrencyAdapter::instance().getCurrency().fusionTxMinInputCount()) {
//nothing to optimize
return;
}
quint64 amount = 0;
WalletAdapter::instance().sendFusionTransaction(fusionInputs, 0, "", mixin);
}

void OptimizationManager::ensureStarted() {
if (m_optimizationTimerId != -1) {
if (m_currentOptimizationInterval == Settings::instance().getOptimizationInterval()) {
return;
}
}

optimize();
m_currentOptimizationInterval = Settings::instance().getOptimizationInterval();
m_optimizationTimerId = startTimer(m_currentOptimizationInterval);
}

void OptimizationManager::ensureStopped() {
if (m_optimizationTimerId == -1) {
return;
}

killTimer(m_optimizationTimerId);
m_currentOptimizationInterval = 0;
m_optimizationTimerId = -1;
}

}
59 changes: 59 additions & 0 deletions src/OptimizationManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright (c) 2015-2017, The Bytecoin developers
// Copyright (c) 2018, The Karbo developers
//
// This file is part of Karbovanets.
//
// Karbovanets is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Karbovanets is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Karbovanets. If not, see <http://www.gnu.org/licenses/>.

#pragma once

#include <QObject>

#include "CryptoNoteWrapper.h"
#include "CurrencyAdapter.h"
#include "WalletAdapter.h"

namespace WalletGui {

class OptimizationManager : public QObject {
Q_OBJECT
Q_DISABLE_COPY(OptimizationManager)

public:
OptimizationManager(QObject *_parent);
~OptimizationManager();

void checkOptimization();

Q_SLOT void walletOpened();
Q_SLOT void walletClosed();
Q_SLOT void synchronizationProgressUpdated();
Q_SLOT void synchronizationCompleted();

protected:
virtual void timerEvent(QTimerEvent* _event);

private:
int m_checkTimerId;
int m_optimizationTimerId;
quint64 m_currentOptimizationInterval;
bool m_isSynchronized;

void optimize();
void ensureStarted();
void ensureStopped();

};

}
Loading

0 comments on commit d201d73

Please sign in to comment.