diff --git a/README.md b/README.md index 77bdfa408c..3c75282194 100644 --- a/README.md +++ b/README.md @@ -14,18 +14,11 @@ What is [Dynamic](https://duality.solutions/dynamic)? * PoW Mining Algorithm: Argon2d * PoW Difficulty Algorithm: Digishield V3 * PoW Period: Unlimited -* PoW Target Spacing: 128 Seconds +* PoW Target Spacing: 75 Seconds * PoW Reward per Block: Controlled via Fluid Protocol * PoW Reward Start Height: Block 5,137 -* PoS Mining Algorithm: Blake2b -* PoS Period: Unlimited -* PoS Target Spacing: 128 Seconds -* PoS Reward per Block: Controlled via Fluid Protocol -* PoS Reward Start Height: Controlled via SPORK activation * Maturity: 10 Blocks -* PoW Blocks: ~675 per day -* PoS Blocks: ~675 per day -* Total Blocks Per Day: ~1350 +* PoW Blocks: ~1152 per day * Dynode Collateral Amount: 1000 DYN * Dynode Min Confirmation: 17 Blocks * Dynode Reward: Controlled via Fluid Protocol diff --git a/configure.ac b/configure.ac index 890f69d2d4..45ae2b4374 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 2) define(_CLIENT_VERSION_MINOR, 5) define(_CLIENT_VERSION_REVISION, 0) -define(_CLIENT_VERSION_BUILD, 0) +define(_CLIENT_VERSION_BUILD, 1) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2021) AC_INIT([Dynamic],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://github.com/duality-solutions/dynamic/issues],[dynamic]) diff --git a/contrib/gitian-descriptors/gitian-arm.yml b/contrib/gitian-descriptors/gitian-arm.yml index 48188e5bdc..5607b5cb55 100644 --- a/contrib/gitian-descriptors/gitian-arm.yml +++ b/contrib/gitian-descriptors/gitian-arm.yml @@ -1,5 +1,5 @@ --- -name: "dynamic-arm-2.5.0.0" +name: "dynamic-arm-2.5.0.1" enable_cache: true suites: - "trusty" diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index c72aa8c2c9..443a32bb8b 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -1,5 +1,5 @@ --- -name: "dynamic-linux-2.5.0.0" +name: "dynamic-linux-2.5.0.1" enable_cache: true suites: - "trusty" diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index d2dbee03a2..3fd0a0dc57 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -1,5 +1,5 @@ --- -name: "dynamic-osx-2.5.0.0" +name: "dynamic-osx-2.5.0.1" enable_cache: true suites: - "trusty" diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index 1af7019a8a..2f65bb5199 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -1,5 +1,5 @@ --- -name: "dynamic-2.5.0.0" +name: "dynamic-2.5.0.1" enable_cache: true suites: - "trusty" diff --git a/dynamic-qt.pro b/dynamic-qt.pro index 2b2097d67c..6757333880 100644 --- a/dynamic-qt.pro +++ b/dynamic-qt.pro @@ -1,6 +1,6 @@ TEMPLATE = app TARGET = dynamic -VERSION = 2.5.0.0 +VERSION = 2.5.0.1 INCLUDEPATH += src \ src/crypto \ src/crypto/heavyhash \ @@ -309,6 +309,7 @@ HEADERS += \ src/qt/askpassphrasedialog.h \ src/qt/addresstablemodel.h \ src/qt/addressbookpage.h \ + src/qt/swapdialog.h \ src/compat/byteswap.h \ src/compat/sanity.h \ src/consensus/consensus.h \ @@ -485,6 +486,7 @@ SOURCES += \ src/qt/sendcoinsentry.cpp \ src/qt/signverifymessagedialog.cpp \ src/qt/splashscreen.cpp \ + src/qt/swapdialog.cpp \ src/qt/dynodelist.cpp \ src/qt/trafficgraphwidget.cpp \ src/qt/transactiondesc.cpp \ @@ -652,4 +654,5 @@ FORMS += \ src/qt/forms/sendcoinsdialog.ui \ src/qt/forms/sendcoinsentry.ui \ src/qt/forms/signverifymessagedialog.ui \ + src/qt/forms/swapdialog.ui \ src/qt/forms/transactiondescdialog.ui diff --git a/src/Makefile.am b/src/Makefile.am index 1e99260b2e..f70ba92a88 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -208,6 +208,9 @@ DYNAMIC_CORE_H = \ support/cleanse.h \ support/lockedpool.h \ support/events.h \ + swap/ss58.h \ + swap/swapdata.h \ + swap/swapdb.h \ sync.h \ threadinterrupt.h \ threadsafety.h \ @@ -350,9 +353,13 @@ libdynamic_server_a_SOURCES = \ rpc/rawbdap.cpp \ rpc/rawtransaction.cpp \ rpc/server.cpp \ + rpc/swap.cpp \ script/sigcache.cpp \ sendalert.cpp \ spork.cpp \ + swap/ss58.cpp \ + swap/swapdata.cpp \ + swap/swapdb.cpp \ timedata.cpp \ torcontrol.cpp \ txdb.cpp \ diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 26552211d2..64ae7c330c 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -49,6 +49,7 @@ QT_FORMS_UI = \ qt/forms/sendcoinsdialog.ui \ qt/forms/sendcoinsentry.ui \ qt/forms/signverifymessagedialog.ui \ + qt/forms/swapdialog.ui \ qt/forms/transactiondescdialog.ui QT_MOC_CPP = \ @@ -100,6 +101,7 @@ QT_MOC_CPP = \ qt/moc_sendcoinsentry.cpp \ qt/moc_signverifymessagedialog.cpp \ qt/moc_splashscreen.cpp \ + qt/moc_swapdialog.cpp \ qt/moc_trafficgraphwidget.cpp \ qt/moc_transactiondesc.cpp \ qt/moc_transactiondescdialog.cpp \ @@ -179,6 +181,7 @@ DYNAMIC_QT_H = \ qt/sendcoinsentry.h \ qt/signverifymessagedialog.h \ qt/splashscreen.h \ + qt/swapdialog.h \ qt/trafficgraphdata.h \ qt/trafficgraphwidget.h \ qt/transactiondesc.h \ @@ -242,13 +245,10 @@ RES_ICONS = \ qt/res/icons/drk/lock_open.png \ qt/res/icons/drk/notsynced.png \ qt/res/icons/drk/overview.png \ - qt/res/icons/drk/pos.png \ qt/res/icons/drk/quit.png \ qt/res/icons/drk/receive.png \ qt/res/icons/drk/remove.png \ qt/res/icons/drk/send.png \ - qt/res/icons/drk/staking_active.png \ - qt/res/icons/drk/staking_inactive.png \ qt/res/icons/drk/synced.png \ qt/res/icons/drk/transaction_abandoned.png \ qt/res/icons/drk/transaction_conflicted.png \ @@ -332,6 +332,7 @@ DYNAMIC_QT_CPP += \ qt/transactionrecord.cpp \ qt/transactiontablemodel.cpp \ qt/transactionview.cpp \ + qt/swapdialog.cpp \ qt/walletframe.cpp \ qt/walletmodel.cpp \ qt/walletmodeltransaction.cpp \ diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 2499891dec..029c0e4a0a 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -94,6 +94,7 @@ DYNAMIC_TESTS =\ test/sighash_tests.cpp \ test/sigopcount_tests.cpp \ test/skiplist_tests.cpp \ + test/ss58_tests.cpp \ test/streams_tests.cpp \ test/test_dynamic.cpp \ test/test_dynamic.h \ diff --git a/src/bdap/audit.cpp b/src/bdap/audit.cpp index 916719258e..8f068c5c87 100644 --- a/src/bdap/audit.cpp +++ b/src/bdap/audit.cpp @@ -243,7 +243,7 @@ bool BuildAuditJson(const CAudit& audit, UniValue& oAudit) oAuditHashes.push_back(Pair("audit_hash" + std::to_string(counter), stringFromVch(vchAudit))); } oAudit.push_back(Pair("version", std::to_string(audit.Version()))); - oAudit.push_back(Pair("audit_count", auditData.vAuditData.size())); + oAudit.push_back(Pair("audit_count", (int)auditData.vAuditData.size())); oAudit.push_back(Pair("audit_hashes", oAuditHashes)); oAudit.push_back(Pair("timestamp", std::to_string(auditData.nTimeStamp))); oAudit.push_back(Pair("owner", stringFromVch(audit.vchOwnerFullObjectPath))); @@ -268,7 +268,7 @@ bool BuildVerifyAuditJson(const CAudit& audit, UniValue& oAudit) CAuditData auditData = audit.GetAuditData(); oAudit.push_back(Pair("version", std::to_string(audit.Version()))); - oAudit.push_back(Pair("audit_count", auditData.vAuditData.size())); + oAudit.push_back(Pair("audit_count", (int)auditData.vAuditData.size())); oAudit.push_back(Pair("timestamp", std::to_string(auditData.nTimeStamp))); oAudit.push_back(Pair("owner", stringFromVch(audit.vchOwnerFullObjectPath))); oAudit.push_back(Pair("signed", audit.IsSigned() ? "True" : "False")); diff --git a/src/bench/bench_dynamic.cpp b/src/bench/bench_dynamic.cpp index 10631105c4..7847230ba1 100644 --- a/src/bench/bench_dynamic.cpp +++ b/src/bench/bench_dynamic.cpp @@ -12,7 +12,6 @@ int main(int argc, char** argv) { - RandomInit(); ECC_Start(); SetupEnvironment(); fPrintToDebugLog = false; // don't want to write to debug.log file diff --git a/src/clientversion.h b/src/clientversion.h index 90719df719..31f56f0fb2 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -20,7 +20,7 @@ #define CLIENT_VERSION_MAJOR 2 #define CLIENT_VERSION_MINOR 5 #define CLIENT_VERSION_REVISION 0 -#define CLIENT_VERSION_BUILD 0 +#define CLIENT_VERSION_BUILD 1 //! Set to true for release, false for prerelease or test build #define CLIENT_VERSION_IS_RELEASE true diff --git a/src/crypto/sha512.h b/src/crypto/sha512.h index 9531a949b3..e5f40ac43d 100644 --- a/src/crypto/sha512.h +++ b/src/crypto/sha512.h @@ -17,7 +17,7 @@ class CSHA512 uint64_t bytes; public: - static const size_t OUTPUT_SIZE = 64; + static constexpr size_t OUTPUT_SIZE = 64; CSHA512(); CSHA512& Write(const unsigned char* data, size_t len); diff --git a/src/fluid/fluid.cpp b/src/fluid/fluid.cpp index f23b193e75..04a78f05ab 100644 --- a/src/fluid/fluid.cpp +++ b/src/fluid/fluid.cpp @@ -28,8 +28,7 @@ extern CWallet* pwalletMain; bool IsTransactionFluid(const CScript& txOut) { - return (txOut.IsProtocolInstruction(MINT_TX) || txOut.IsProtocolInstruction(DYNODE_MODFIY_TX) || txOut.IsProtocolInstruction(MINING_MODIFY_TX) || - txOut.IsProtocolInstruction(BDAP_REVOKE_TX)); + return txOut.IsFluid(); } bool IsTransactionFluid(const CTransaction& tx, CScript& fluidScript) diff --git a/src/hash.h b/src/hash.h index 4575b8b80a..f9c8374cc0 100644 --- a/src/hash.h +++ b/src/hash.h @@ -396,4 +396,27 @@ inline uint256 hash_Argon2d(const T1 pbegin, const T1 pend, const unsigned int& return hashResult; } +template +inline uint256 HashBlake2b_256(const T1 pbegin, const T1 pend) +{ + static unsigned char pblank[1]; + uint256 hash; + blake2b_state S[1]; + blake2b_init( S, OUTPUT_BYTES ); // 32 Bytes -> 256-bit hash + blake2b_update( S, (pbegin == pend ? pblank : (unsigned char*)&pbegin[0]), (pend - pbegin) * sizeof(pbegin[0]) ); + blake2b_final( S, (unsigned char*)&hash, OUTPUT_BYTES ); + return hash; +} + +template +inline uint512 HashBlake2b_512(const T1 pbegin, const T1 pend) +{ + static unsigned char pblank[1]; + uint512 hash; + blake2b_state S[1]; + blake2b_init( S, 64 ); // 64 Bytes -> 512-bit hash + blake2b_update( S, (pbegin == pend ? pblank : (unsigned char*)&pbegin[0]), (pend - pbegin) * sizeof(pbegin[0]) ); + blake2b_final( S, (unsigned char*)&hash, 64 ); + return hash; +} #endif // DYNAMIC_HASH_H diff --git a/src/init.cpp b/src/init.cpp index f92eb86fb4..76a2939fdf 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -61,6 +61,8 @@ #include "script/sigcache.h" #include "script/standard.h" #include "spork.h" +#include "swap/swapdata.h" +#include "swap/swapdb.h" #include "timedata.h" #include "torcontrol.h" #include "txdb.h" @@ -377,6 +379,8 @@ void PrepareShutdown() // LibTorrent DHT Netowrk Services //delete pMutableDataDB; //pMutableDataDB = NULL; + delete pSwapDB; + pSwapDB = NULL; } #ifdef ENABLE_WALLET if (pwalletMain) @@ -1739,6 +1743,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) delete pLinkManager; // LibTorrent DHT Netowrk Services //delete pMutableDataDB; + delete pSwapDB; pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex); pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex || fReindexChainState); @@ -1760,6 +1765,8 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) pLinkManager = new CLinkManager(); // Init DHT Services DB //pMutableDataDB = new CMutableDataDB(nTotalCache * 35, false, fReindex, obfuscate); + // Init SwapDB + pSwapDB = new CSwapDB(nTotalCache * 35, false, fReindex, obfuscate); if (fReindex) { pblocktree->WriteReindexing(true); diff --git a/src/net.h b/src/net.h index bca521dc60..5c01884cbd 100644 --- a/src/net.h +++ b/src/net.h @@ -61,8 +61,8 @@ static const int FEELER_INTERVAL = 120; static const unsigned int MAX_INV_SZ = 50000; /** The maximum number of new addresses to accumulate before announcing. */ static const unsigned int MAX_ADDR_TO_SEND = 1000; -/** Maximum length of incoming protocol messages (no message over 2 MiB is currently acceptable). */ -static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 2 * 1024 * 1024; +/** Maximum length of incoming protocol messages (no message over 4 MB is currently acceptable). */ +static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = (4 * 1024 * 1024) + 100; /** Maximum length of strSubVer in `version` message */ static const unsigned int MAX_SUBVERSION_LENGTH = 256; /** Maximum number of outgoing nodes */ diff --git a/src/ntp.cpp b/src/ntp.cpp index 133714340c..22c7f91c7a 100644 --- a/src/ntp.cpp +++ b/src/ntp.cpp @@ -15,7 +15,7 @@ #include "utiltime.h" #include "warnings.h" -extern int GetRandInt(int nMax); +extern int GetRandInt(int nMax) noexcept; /* * NTP uses two fixed point formats. The first (l_fp) is the "long" diff --git a/src/policy/policy.h b/src/policy/policy.h index 321825f187..3abe59bdea 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -62,6 +62,9 @@ static const unsigned int STANDARD_LOCKTIME_VERIFY_FLAGS = LOCKTIME_VERIFY_SEQUE /** Used for BDAP transactions. */ static const int BDAP_TX_VERSION = 0x3500; +/** Used for BDAP transactions. */ +static const int SWAP_TX_VERSION = 0x3600; + bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType); /** * Check for standard transaction types diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 34374b0402..5fa17941d0 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -88,6 +88,11 @@ bool CTxOut::GetBDAPOpCodes(int& opCode1, int& opCode2, std::vector& vchData) const +{ + if (!IsData()) + return false; + + if (GetOpReturnData(scriptPubKey, vchData)) + return true; + + return false; +} + std::string CTxOut::ToString() const { return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s, IsBDAP=%s, IsData=%s)", nValue / COIN, nValue % COIN diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index f2c9b1565e..216125e5ac 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -220,8 +220,10 @@ class CTxOut bool IsBDAP() const; bool IsData() const; + bool GetData(std::vector& vchData) const; bool GetBDAPOpCodes(int& opCode1, int& opCode2) const; bool GetBDAPOpCodes(int& opCode1, int& opCode2, std::vector>& vvch) const; + bool IsFluid() const; std::string ToString() const; }; diff --git a/src/qt/dynamic.qrc b/src/qt/dynamic.qrc index 684f37fcc4..ff63379d6b 100644 --- a/src/qt/dynamic.qrc +++ b/src/qt/dynamic.qrc @@ -35,8 +35,6 @@ res/icons/drk/key.png res/icons/drk/lock_closed.png res/icons/drk/lock_open.png - res/icons/drk/staking_active.png - res/icons/drk/staking_inactive.png res/icons/drk/configure.png res/icons/drk/history.png res/icons/drk/overview.png @@ -55,7 +53,6 @@ res/icons/drk/clock4.png res/icons/drk/clock5.png res/icons/drk/tx_mined.png - res/icons/drk/pos.png res/icons/drk/bdap.png res/icons/drk/tx_input.png res/icons/drk/tx_output.png diff --git a/src/qt/dynamicgui.cpp b/src/qt/dynamicgui.cpp index f348e06410..9e74c1c014 100644 --- a/src/qt/dynamicgui.cpp +++ b/src/qt/dynamicgui.cpp @@ -24,6 +24,7 @@ #include "optionsmodel.h" #include "platformstyle.h" #include "rpcconsole.h" +#include "swapdialog.h" #include "utilitydialog.h" #ifdef ENABLE_WALLET #include "walletframe.h" @@ -121,6 +122,7 @@ DynamicGUI::DynamicGUI(const PlatformStyle* _platformStyle, const NetworkStyle* openRPCConsoleAction(0), openAction(0), mnemonicAction(0), + swapAction(0), showHelpMessageAction(0), showPrivateSendHelpAction(0), trayIcon(0), @@ -468,7 +470,7 @@ void DynamicGUI::createActions() openAction = new QAction(QApplication::style()->standardIcon(QStyle::SP_DirOpenIcon), tr("Open &URI..."), this); openAction->setStatusTip(tr("Open a dynamic: URI")); - mnemonicAction = new QAction(platformStyle->TextColorIcon(":/icons/open"), tr("&Import mnemonic/private key..."), this); + mnemonicAction = new QAction(QIcon(":/icons/" + theme + "/receiving_addresses"), tr("&Import mnemonic/private key..."), this); mnemonicAction->setStatusTip(tr("Import Mnemonic Phrase or Private Key")); showHelpMessageAction = new QAction(QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation), tr("&Command-line options"), this); @@ -478,6 +480,9 @@ void DynamicGUI::createActions() showPrivateSendHelpAction = new QAction(QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation), tr("&PrivateSend information"), this); showPrivateSendHelpAction->setMenuRole(QAction::NoRole); showPrivateSendHelpAction->setStatusTip(tr("Show the PrivateSend basic information")); + + swapAction = new QAction(QIcon(":/icons/" + theme + "/send"), tr("&Swap Dynamic"), this); + swapAction->setStatusTip(tr("Swap current chain Dynamic for new Substrate chain")); connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked())); @@ -517,6 +522,7 @@ void DynamicGUI::createActions() connect(usedSendingAddressesAction, SIGNAL(triggered()), walletFrame, SLOT(usedSendingAddresses())); connect(usedReceivingAddressesAction, SIGNAL(triggered()), walletFrame, SLOT(usedReceivingAddresses())); connect(openAction, SIGNAL(triggered()), this, SLOT(openClicked())); + connect(swapAction, SIGNAL(triggered()), this, SLOT(swapClicked())); connect(mnemonicAction, SIGNAL(triggered()), this, SLOT(mnemonicClicked())); } #endif // ENABLE_WALLET @@ -542,11 +548,14 @@ void DynamicGUI::createMenuBar() QMenu* file = appMenuBar->addMenu(tr("&File")); if (walletFrame) { file->addAction(openAction); - file->addAction(backupWalletAction); file->addAction(signMessageAction); file->addAction(verifyMessageAction); file->addSeparator(); +#ifdef ENABLE_WALLET + file->addAction(backupWalletAction); + file->addAction(swapAction); file->addAction(mnemonicAction); +#endif // ENABLE_WALLET file->addAction(usedSendingAddressesAction); file->addAction(usedReceivingAddressesAction); file->addSeparator(); @@ -705,12 +714,13 @@ void DynamicGUI::setClientModel(ClientModel* _clientModel) } #ifdef ENABLE_WALLET -bool DynamicGUI::addWallet(const QString& name, WalletModel* walletModel) +bool DynamicGUI::addWallet(const QString& name, WalletModel* _walletModel) { if (!walletFrame) return false; setWalletActionsEnabled(true); - return walletFrame->addWallet(name, walletModel); + walletModel = _walletModel; + return walletFrame->addWallet(name, _walletModel); } bool DynamicGUI::setCurrentWallet(const QString& name) @@ -749,6 +759,7 @@ void DynamicGUI::setWalletActionsEnabled(bool enabled) usedReceivingAddressesAction->setEnabled(enabled); openAction->setEnabled(enabled); mnemonicAction->setEnabled(enabled); + swapAction->setEnabled(enabled); } void DynamicGUI::createTrayIcon(const NetworkStyle* networkStyle) @@ -908,6 +919,13 @@ void DynamicGUI::openClicked() } } +void DynamicGUI::swapClicked() +{ + SwapDialog dlg(this); + dlg.setWalletModel(walletModel); + dlg.exec(); +} + void DynamicGUI::gotoOverviewPage() { overviewAction->setChecked(true); diff --git a/src/qt/dynamicgui.h b/src/qt/dynamicgui.h index 06f0d65e91..125bc9acb1 100644 --- a/src/qt/dynamicgui.h +++ b/src/qt/dynamicgui.h @@ -108,6 +108,9 @@ class DynamicGUI : public QMainWindow private: ClientModel* clientModel; WalletFrame* walletFrame; +#ifdef ENABLE_WALLET + WalletModel* walletModel; +#endif // ENABLE_WALLET UnitDisplayStatusBarControl* unitDisplayControl; QLabel* labelWalletHDStatusIcon; @@ -151,6 +154,7 @@ class DynamicGUI : public QMainWindow QAction* showBackupsAction; QAction* openAction; QAction *mnemonicAction; + QAction* swapAction; QAction* showHelpMessageAction; QAction* showPrivateSendHelpAction; @@ -257,6 +261,7 @@ private Q_SLOTS: /** Show open dialog */ void openClicked(); void mnemonicClicked(); + void swapClicked(); #endif // ENABLE_WALLET /** Show configuration dialog */ diff --git a/src/qt/forms/swapdialog.ui b/src/qt/forms/swapdialog.ui new file mode 100644 index 0000000000..1fc53d201c --- /dev/null +++ b/src/qt/forms/swapdialog.ui @@ -0,0 +1,96 @@ + + + SwapDialog + + + + 0 + 0 + 708 + 357 + + + + Swap Dynamic + + + background-color: rgb(0, 0, 0); color: rgb(255, 255, 255); + + + + + + Get new Substrate chain address instructions here.... + + + Qt::RichText + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + + + Qt::RichText + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + + Swap Address + + + + + + + + + + + + Qt::Horizontal + + + + 10 + 20 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + QValidatedLineEdit + QLineEdit +
qvalidatedlineedit.h
+
+
+ + + + +
diff --git a/src/qt/res/icons/drk/pos.png b/src/qt/res/icons/drk/pos.png deleted file mode 100644 index 12900d67e9..0000000000 Binary files a/src/qt/res/icons/drk/pos.png and /dev/null differ diff --git a/src/qt/res/icons/drk/staking_active.png b/src/qt/res/icons/drk/staking_active.png deleted file mode 100644 index 3c7551eb25..0000000000 Binary files a/src/qt/res/icons/drk/staking_active.png and /dev/null differ diff --git a/src/qt/res/icons/drk/staking_inactive.png b/src/qt/res/icons/drk/staking_inactive.png deleted file mode 100644 index d6a4b02caf..0000000000 Binary files a/src/qt/res/icons/drk/staking_inactive.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-0.png b/src/qt/res/icons/drk/warning-0.png deleted file mode 100644 index 46123903b9..0000000000 Binary files a/src/qt/res/icons/drk/warning-0.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-1.png b/src/qt/res/icons/drk/warning-1.png deleted file mode 100644 index 23218567d5..0000000000 Binary files a/src/qt/res/icons/drk/warning-1.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-10.png b/src/qt/res/icons/drk/warning-10.png deleted file mode 100644 index a78d36d691..0000000000 Binary files a/src/qt/res/icons/drk/warning-10.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-100.png b/src/qt/res/icons/drk/warning-100.png deleted file mode 100644 index 5b90d5098b..0000000000 Binary files a/src/qt/res/icons/drk/warning-100.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-101.png b/src/qt/res/icons/drk/warning-101.png deleted file mode 100644 index ba53a0d63c..0000000000 Binary files a/src/qt/res/icons/drk/warning-101.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-102.png b/src/qt/res/icons/drk/warning-102.png deleted file mode 100644 index a0cf25cf14..0000000000 Binary files a/src/qt/res/icons/drk/warning-102.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-103.png b/src/qt/res/icons/drk/warning-103.png deleted file mode 100644 index eeb19ab9fa..0000000000 Binary files a/src/qt/res/icons/drk/warning-103.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-104.png b/src/qt/res/icons/drk/warning-104.png deleted file mode 100644 index 176ecfd6d7..0000000000 Binary files a/src/qt/res/icons/drk/warning-104.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-105.png b/src/qt/res/icons/drk/warning-105.png deleted file mode 100644 index 066e0432a0..0000000000 Binary files a/src/qt/res/icons/drk/warning-105.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-106.png b/src/qt/res/icons/drk/warning-106.png deleted file mode 100644 index 4a43c136d0..0000000000 Binary files a/src/qt/res/icons/drk/warning-106.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-107.png b/src/qt/res/icons/drk/warning-107.png deleted file mode 100644 index f33a58ad5a..0000000000 Binary files a/src/qt/res/icons/drk/warning-107.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-108.png b/src/qt/res/icons/drk/warning-108.png deleted file mode 100644 index 2147798106..0000000000 Binary files a/src/qt/res/icons/drk/warning-108.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-109.png b/src/qt/res/icons/drk/warning-109.png deleted file mode 100644 index 554858db96..0000000000 Binary files a/src/qt/res/icons/drk/warning-109.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-11.png b/src/qt/res/icons/drk/warning-11.png deleted file mode 100644 index 4fbf5652db..0000000000 Binary files a/src/qt/res/icons/drk/warning-11.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-110.png b/src/qt/res/icons/drk/warning-110.png deleted file mode 100644 index 38cfceba37..0000000000 Binary files a/src/qt/res/icons/drk/warning-110.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-111.png b/src/qt/res/icons/drk/warning-111.png deleted file mode 100644 index 2cbd2e3228..0000000000 Binary files a/src/qt/res/icons/drk/warning-111.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-112.png b/src/qt/res/icons/drk/warning-112.png deleted file mode 100644 index 5eff469a8b..0000000000 Binary files a/src/qt/res/icons/drk/warning-112.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-113.png b/src/qt/res/icons/drk/warning-113.png deleted file mode 100644 index 20422f163b..0000000000 Binary files a/src/qt/res/icons/drk/warning-113.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-114.png b/src/qt/res/icons/drk/warning-114.png deleted file mode 100644 index 025d58c0f3..0000000000 Binary files a/src/qt/res/icons/drk/warning-114.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-115.png b/src/qt/res/icons/drk/warning-115.png deleted file mode 100644 index 123bcc3b28..0000000000 Binary files a/src/qt/res/icons/drk/warning-115.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-116.png b/src/qt/res/icons/drk/warning-116.png deleted file mode 100644 index 8395b51ff0..0000000000 Binary files a/src/qt/res/icons/drk/warning-116.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-117.png b/src/qt/res/icons/drk/warning-117.png deleted file mode 100644 index db257d6db2..0000000000 Binary files a/src/qt/res/icons/drk/warning-117.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-118.png b/src/qt/res/icons/drk/warning-118.png deleted file mode 100644 index 62778eeb0e..0000000000 Binary files a/src/qt/res/icons/drk/warning-118.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-119.png b/src/qt/res/icons/drk/warning-119.png deleted file mode 100644 index 010dbe7c70..0000000000 Binary files a/src/qt/res/icons/drk/warning-119.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-12.png b/src/qt/res/icons/drk/warning-12.png deleted file mode 100644 index f66eddc330..0000000000 Binary files a/src/qt/res/icons/drk/warning-12.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-120.png b/src/qt/res/icons/drk/warning-120.png deleted file mode 100644 index feff7bbcf1..0000000000 Binary files a/src/qt/res/icons/drk/warning-120.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-121.png b/src/qt/res/icons/drk/warning-121.png deleted file mode 100644 index 5c8e0d7038..0000000000 Binary files a/src/qt/res/icons/drk/warning-121.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-122.png b/src/qt/res/icons/drk/warning-122.png deleted file mode 100644 index 8e629b6f9e..0000000000 Binary files a/src/qt/res/icons/drk/warning-122.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-123.png b/src/qt/res/icons/drk/warning-123.png deleted file mode 100644 index 7cb3a10a2d..0000000000 Binary files a/src/qt/res/icons/drk/warning-123.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-124.png b/src/qt/res/icons/drk/warning-124.png deleted file mode 100644 index 98167f7d9f..0000000000 Binary files a/src/qt/res/icons/drk/warning-124.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-125.png b/src/qt/res/icons/drk/warning-125.png deleted file mode 100644 index 4aa2719dbf..0000000000 Binary files a/src/qt/res/icons/drk/warning-125.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-126.png b/src/qt/res/icons/drk/warning-126.png deleted file mode 100644 index ddaea34466..0000000000 Binary files a/src/qt/res/icons/drk/warning-126.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-127.png b/src/qt/res/icons/drk/warning-127.png deleted file mode 100644 index ec846cd8b3..0000000000 Binary files a/src/qt/res/icons/drk/warning-127.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-128.png b/src/qt/res/icons/drk/warning-128.png deleted file mode 100644 index bcf666f808..0000000000 Binary files a/src/qt/res/icons/drk/warning-128.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-129.png b/src/qt/res/icons/drk/warning-129.png deleted file mode 100644 index 28037df700..0000000000 Binary files a/src/qt/res/icons/drk/warning-129.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-13.png b/src/qt/res/icons/drk/warning-13.png deleted file mode 100644 index 89c68e94c7..0000000000 Binary files a/src/qt/res/icons/drk/warning-13.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-130.png b/src/qt/res/icons/drk/warning-130.png deleted file mode 100644 index 402d2ebc3b..0000000000 Binary files a/src/qt/res/icons/drk/warning-130.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-131.png b/src/qt/res/icons/drk/warning-131.png deleted file mode 100644 index fece7afc3c..0000000000 Binary files a/src/qt/res/icons/drk/warning-131.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-132.png b/src/qt/res/icons/drk/warning-132.png deleted file mode 100644 index b85c3c7625..0000000000 Binary files a/src/qt/res/icons/drk/warning-132.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-133.png b/src/qt/res/icons/drk/warning-133.png deleted file mode 100644 index 5354756f1f..0000000000 Binary files a/src/qt/res/icons/drk/warning-133.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-134.png b/src/qt/res/icons/drk/warning-134.png deleted file mode 100644 index bab5b568a4..0000000000 Binary files a/src/qt/res/icons/drk/warning-134.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-135.png b/src/qt/res/icons/drk/warning-135.png deleted file mode 100644 index fb2dcf0e16..0000000000 Binary files a/src/qt/res/icons/drk/warning-135.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-136.png b/src/qt/res/icons/drk/warning-136.png deleted file mode 100644 index c3c28c63a2..0000000000 Binary files a/src/qt/res/icons/drk/warning-136.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-137.png b/src/qt/res/icons/drk/warning-137.png deleted file mode 100644 index c84ba94115..0000000000 Binary files a/src/qt/res/icons/drk/warning-137.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-138.png b/src/qt/res/icons/drk/warning-138.png deleted file mode 100644 index 3b63909587..0000000000 Binary files a/src/qt/res/icons/drk/warning-138.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-139.png b/src/qt/res/icons/drk/warning-139.png deleted file mode 100644 index 0553fb7b65..0000000000 Binary files a/src/qt/res/icons/drk/warning-139.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-14.png b/src/qt/res/icons/drk/warning-14.png deleted file mode 100644 index 5a8b2cd297..0000000000 Binary files a/src/qt/res/icons/drk/warning-14.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-140.png b/src/qt/res/icons/drk/warning-140.png deleted file mode 100644 index 9c0dc2d2ad..0000000000 Binary files a/src/qt/res/icons/drk/warning-140.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-141.png b/src/qt/res/icons/drk/warning-141.png deleted file mode 100644 index f0943010f8..0000000000 Binary files a/src/qt/res/icons/drk/warning-141.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-142.png b/src/qt/res/icons/drk/warning-142.png deleted file mode 100644 index 837e29c0c5..0000000000 Binary files a/src/qt/res/icons/drk/warning-142.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-143.png b/src/qt/res/icons/drk/warning-143.png deleted file mode 100644 index d472b5bc21..0000000000 Binary files a/src/qt/res/icons/drk/warning-143.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-144.png b/src/qt/res/icons/drk/warning-144.png deleted file mode 100644 index 9c0dc2d2ad..0000000000 Binary files a/src/qt/res/icons/drk/warning-144.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-145.png b/src/qt/res/icons/drk/warning-145.png deleted file mode 100644 index 9de3feca53..0000000000 Binary files a/src/qt/res/icons/drk/warning-145.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-146.png b/src/qt/res/icons/drk/warning-146.png deleted file mode 100644 index 94bbe8cd2b..0000000000 Binary files a/src/qt/res/icons/drk/warning-146.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-147.png b/src/qt/res/icons/drk/warning-147.png deleted file mode 100644 index 181a2e7c8c..0000000000 Binary files a/src/qt/res/icons/drk/warning-147.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-148.png b/src/qt/res/icons/drk/warning-148.png deleted file mode 100644 index a7c92553f4..0000000000 Binary files a/src/qt/res/icons/drk/warning-148.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-149.png b/src/qt/res/icons/drk/warning-149.png deleted file mode 100644 index 1a4f30111e..0000000000 Binary files a/src/qt/res/icons/drk/warning-149.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-15.png b/src/qt/res/icons/drk/warning-15.png deleted file mode 100644 index 84590c4340..0000000000 Binary files a/src/qt/res/icons/drk/warning-15.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-150.png b/src/qt/res/icons/drk/warning-150.png deleted file mode 100644 index 8fa9c4ee0c..0000000000 Binary files a/src/qt/res/icons/drk/warning-150.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-151.png b/src/qt/res/icons/drk/warning-151.png deleted file mode 100644 index abccff0ceb..0000000000 Binary files a/src/qt/res/icons/drk/warning-151.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-152.png b/src/qt/res/icons/drk/warning-152.png deleted file mode 100644 index 8d57715c87..0000000000 Binary files a/src/qt/res/icons/drk/warning-152.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-153.png b/src/qt/res/icons/drk/warning-153.png deleted file mode 100644 index 79211a849e..0000000000 Binary files a/src/qt/res/icons/drk/warning-153.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-154.png b/src/qt/res/icons/drk/warning-154.png deleted file mode 100644 index 497631b7b5..0000000000 Binary files a/src/qt/res/icons/drk/warning-154.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-155.png b/src/qt/res/icons/drk/warning-155.png deleted file mode 100644 index ebc5331bb3..0000000000 Binary files a/src/qt/res/icons/drk/warning-155.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-156.png b/src/qt/res/icons/drk/warning-156.png deleted file mode 100644 index b736c30acf..0000000000 Binary files a/src/qt/res/icons/drk/warning-156.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-157.png b/src/qt/res/icons/drk/warning-157.png deleted file mode 100644 index d32a9b6b2f..0000000000 Binary files a/src/qt/res/icons/drk/warning-157.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-158.png b/src/qt/res/icons/drk/warning-158.png deleted file mode 100644 index 9781a763a0..0000000000 Binary files a/src/qt/res/icons/drk/warning-158.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-159.png b/src/qt/res/icons/drk/warning-159.png deleted file mode 100644 index e6246b8934..0000000000 Binary files a/src/qt/res/icons/drk/warning-159.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-16.png b/src/qt/res/icons/drk/warning-16.png deleted file mode 100644 index d716f9f7f4..0000000000 Binary files a/src/qt/res/icons/drk/warning-16.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-160.png b/src/qt/res/icons/drk/warning-160.png deleted file mode 100644 index aea6d4fb6e..0000000000 Binary files a/src/qt/res/icons/drk/warning-160.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-161.png b/src/qt/res/icons/drk/warning-161.png deleted file mode 100644 index 0935b900ac..0000000000 Binary files a/src/qt/res/icons/drk/warning-161.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-162.png b/src/qt/res/icons/drk/warning-162.png deleted file mode 100644 index 502489f406..0000000000 Binary files a/src/qt/res/icons/drk/warning-162.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-163.png b/src/qt/res/icons/drk/warning-163.png deleted file mode 100644 index 60277a7076..0000000000 Binary files a/src/qt/res/icons/drk/warning-163.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-164.png b/src/qt/res/icons/drk/warning-164.png deleted file mode 100644 index a919f5ead7..0000000000 Binary files a/src/qt/res/icons/drk/warning-164.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-165.png b/src/qt/res/icons/drk/warning-165.png deleted file mode 100644 index 9e63f14ba5..0000000000 Binary files a/src/qt/res/icons/drk/warning-165.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-166.png b/src/qt/res/icons/drk/warning-166.png deleted file mode 100644 index 75bca432bd..0000000000 Binary files a/src/qt/res/icons/drk/warning-166.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-167.png b/src/qt/res/icons/drk/warning-167.png deleted file mode 100644 index cd6f9657b7..0000000000 Binary files a/src/qt/res/icons/drk/warning-167.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-168.png b/src/qt/res/icons/drk/warning-168.png deleted file mode 100644 index 88be777ac2..0000000000 Binary files a/src/qt/res/icons/drk/warning-168.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-169.png b/src/qt/res/icons/drk/warning-169.png deleted file mode 100644 index 5dd6d22cd7..0000000000 Binary files a/src/qt/res/icons/drk/warning-169.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-17.png b/src/qt/res/icons/drk/warning-17.png deleted file mode 100644 index 7aaa3e6711..0000000000 Binary files a/src/qt/res/icons/drk/warning-17.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-170.png b/src/qt/res/icons/drk/warning-170.png deleted file mode 100644 index f20ea88231..0000000000 Binary files a/src/qt/res/icons/drk/warning-170.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-171.png b/src/qt/res/icons/drk/warning-171.png deleted file mode 100644 index a244bd98d2..0000000000 Binary files a/src/qt/res/icons/drk/warning-171.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-172.png b/src/qt/res/icons/drk/warning-172.png deleted file mode 100644 index 18831e91b4..0000000000 Binary files a/src/qt/res/icons/drk/warning-172.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-173.png b/src/qt/res/icons/drk/warning-173.png deleted file mode 100644 index c869ae63b0..0000000000 Binary files a/src/qt/res/icons/drk/warning-173.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-174.png b/src/qt/res/icons/drk/warning-174.png deleted file mode 100644 index 7f76259f72..0000000000 Binary files a/src/qt/res/icons/drk/warning-174.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-175.png b/src/qt/res/icons/drk/warning-175.png deleted file mode 100644 index 88f02ccd69..0000000000 Binary files a/src/qt/res/icons/drk/warning-175.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-176.png b/src/qt/res/icons/drk/warning-176.png deleted file mode 100644 index 078bb27bbb..0000000000 Binary files a/src/qt/res/icons/drk/warning-176.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-177.png b/src/qt/res/icons/drk/warning-177.png deleted file mode 100644 index 1a7ae8fa88..0000000000 Binary files a/src/qt/res/icons/drk/warning-177.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-178.png b/src/qt/res/icons/drk/warning-178.png deleted file mode 100644 index 16fa7ca260..0000000000 Binary files a/src/qt/res/icons/drk/warning-178.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-179.png b/src/qt/res/icons/drk/warning-179.png deleted file mode 100644 index 7475f1cfd4..0000000000 Binary files a/src/qt/res/icons/drk/warning-179.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-18.png b/src/qt/res/icons/drk/warning-18.png deleted file mode 100644 index 54948380f1..0000000000 Binary files a/src/qt/res/icons/drk/warning-18.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-180.png b/src/qt/res/icons/drk/warning-180.png deleted file mode 100644 index 0686bdc9dd..0000000000 Binary files a/src/qt/res/icons/drk/warning-180.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-181.png b/src/qt/res/icons/drk/warning-181.png deleted file mode 100644 index a03ce448c7..0000000000 Binary files a/src/qt/res/icons/drk/warning-181.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-182.png b/src/qt/res/icons/drk/warning-182.png deleted file mode 100644 index e56c3726b1..0000000000 Binary files a/src/qt/res/icons/drk/warning-182.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-183.png b/src/qt/res/icons/drk/warning-183.png deleted file mode 100644 index 82a5a98ac4..0000000000 Binary files a/src/qt/res/icons/drk/warning-183.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-184.png b/src/qt/res/icons/drk/warning-184.png deleted file mode 100644 index 17eead3689..0000000000 Binary files a/src/qt/res/icons/drk/warning-184.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-185.png b/src/qt/res/icons/drk/warning-185.png deleted file mode 100644 index ed8f251829..0000000000 Binary files a/src/qt/res/icons/drk/warning-185.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-186.png b/src/qt/res/icons/drk/warning-186.png deleted file mode 100644 index 7a40e9fd1e..0000000000 Binary files a/src/qt/res/icons/drk/warning-186.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-187.png b/src/qt/res/icons/drk/warning-187.png deleted file mode 100644 index 184ba747c7..0000000000 Binary files a/src/qt/res/icons/drk/warning-187.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-188.png b/src/qt/res/icons/drk/warning-188.png deleted file mode 100644 index dc70dbadd7..0000000000 Binary files a/src/qt/res/icons/drk/warning-188.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-189.png b/src/qt/res/icons/drk/warning-189.png deleted file mode 100644 index 07819036c3..0000000000 Binary files a/src/qt/res/icons/drk/warning-189.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-19.png b/src/qt/res/icons/drk/warning-19.png deleted file mode 100644 index 9731a56605..0000000000 Binary files a/src/qt/res/icons/drk/warning-19.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-190.png b/src/qt/res/icons/drk/warning-190.png deleted file mode 100644 index 245b19bf7c..0000000000 Binary files a/src/qt/res/icons/drk/warning-190.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-191.png b/src/qt/res/icons/drk/warning-191.png deleted file mode 100644 index ca18a228ec..0000000000 Binary files a/src/qt/res/icons/drk/warning-191.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-192.png b/src/qt/res/icons/drk/warning-192.png deleted file mode 100644 index 895fbf8b88..0000000000 Binary files a/src/qt/res/icons/drk/warning-192.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-193.png b/src/qt/res/icons/drk/warning-193.png deleted file mode 100644 index 7be9108431..0000000000 Binary files a/src/qt/res/icons/drk/warning-193.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-194.png b/src/qt/res/icons/drk/warning-194.png deleted file mode 100644 index 321c59a521..0000000000 Binary files a/src/qt/res/icons/drk/warning-194.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-195.png b/src/qt/res/icons/drk/warning-195.png deleted file mode 100644 index c22ceba240..0000000000 Binary files a/src/qt/res/icons/drk/warning-195.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-196.png b/src/qt/res/icons/drk/warning-196.png deleted file mode 100644 index 4403ba1851..0000000000 Binary files a/src/qt/res/icons/drk/warning-196.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-197.png b/src/qt/res/icons/drk/warning-197.png deleted file mode 100644 index 6926aa7db9..0000000000 Binary files a/src/qt/res/icons/drk/warning-197.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-198.png b/src/qt/res/icons/drk/warning-198.png deleted file mode 100644 index 6bdedcd11a..0000000000 Binary files a/src/qt/res/icons/drk/warning-198.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-199.png b/src/qt/res/icons/drk/warning-199.png deleted file mode 100644 index 405f1d1dbb..0000000000 Binary files a/src/qt/res/icons/drk/warning-199.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-2.png b/src/qt/res/icons/drk/warning-2.png deleted file mode 100644 index 75673fbb80..0000000000 Binary files a/src/qt/res/icons/drk/warning-2.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-20.png b/src/qt/res/icons/drk/warning-20.png deleted file mode 100644 index 5514702697..0000000000 Binary files a/src/qt/res/icons/drk/warning-20.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-200.png b/src/qt/res/icons/drk/warning-200.png deleted file mode 100644 index bb3083ac37..0000000000 Binary files a/src/qt/res/icons/drk/warning-200.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-201.png b/src/qt/res/icons/drk/warning-201.png deleted file mode 100644 index b5b6ee76ab..0000000000 Binary files a/src/qt/res/icons/drk/warning-201.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-202.png b/src/qt/res/icons/drk/warning-202.png deleted file mode 100644 index 893d934796..0000000000 Binary files a/src/qt/res/icons/drk/warning-202.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-203.png b/src/qt/res/icons/drk/warning-203.png deleted file mode 100644 index 2556946bc2..0000000000 Binary files a/src/qt/res/icons/drk/warning-203.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-204.png b/src/qt/res/icons/drk/warning-204.png deleted file mode 100644 index 76220a0db6..0000000000 Binary files a/src/qt/res/icons/drk/warning-204.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-205.png b/src/qt/res/icons/drk/warning-205.png deleted file mode 100644 index c79c783f79..0000000000 Binary files a/src/qt/res/icons/drk/warning-205.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-206.png b/src/qt/res/icons/drk/warning-206.png deleted file mode 100644 index 0236a322e0..0000000000 Binary files a/src/qt/res/icons/drk/warning-206.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-207.png b/src/qt/res/icons/drk/warning-207.png deleted file mode 100644 index c19ff95f6d..0000000000 Binary files a/src/qt/res/icons/drk/warning-207.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-208.png b/src/qt/res/icons/drk/warning-208.png deleted file mode 100644 index 839915c783..0000000000 Binary files a/src/qt/res/icons/drk/warning-208.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-209.png b/src/qt/res/icons/drk/warning-209.png deleted file mode 100644 index a9511b1295..0000000000 Binary files a/src/qt/res/icons/drk/warning-209.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-21.png b/src/qt/res/icons/drk/warning-21.png deleted file mode 100644 index 18169ce019..0000000000 Binary files a/src/qt/res/icons/drk/warning-21.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-210.png b/src/qt/res/icons/drk/warning-210.png deleted file mode 100644 index 2ed1ab2c16..0000000000 Binary files a/src/qt/res/icons/drk/warning-210.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-211.png b/src/qt/res/icons/drk/warning-211.png deleted file mode 100644 index aa54f59207..0000000000 Binary files a/src/qt/res/icons/drk/warning-211.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-212.png b/src/qt/res/icons/drk/warning-212.png deleted file mode 100644 index 77bd858f0d..0000000000 Binary files a/src/qt/res/icons/drk/warning-212.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-213.png b/src/qt/res/icons/drk/warning-213.png deleted file mode 100644 index 767df71c17..0000000000 Binary files a/src/qt/res/icons/drk/warning-213.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-214.png b/src/qt/res/icons/drk/warning-214.png deleted file mode 100644 index ab395a9eec..0000000000 Binary files a/src/qt/res/icons/drk/warning-214.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-215.png b/src/qt/res/icons/drk/warning-215.png deleted file mode 100644 index 92198d3cff..0000000000 Binary files a/src/qt/res/icons/drk/warning-215.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-216.png b/src/qt/res/icons/drk/warning-216.png deleted file mode 100644 index 19fb4d3bbb..0000000000 Binary files a/src/qt/res/icons/drk/warning-216.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-217.png b/src/qt/res/icons/drk/warning-217.png deleted file mode 100644 index fe855bc3a3..0000000000 Binary files a/src/qt/res/icons/drk/warning-217.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-218.png b/src/qt/res/icons/drk/warning-218.png deleted file mode 100644 index 15a664b37d..0000000000 Binary files a/src/qt/res/icons/drk/warning-218.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-219.png b/src/qt/res/icons/drk/warning-219.png deleted file mode 100644 index 3272a40602..0000000000 Binary files a/src/qt/res/icons/drk/warning-219.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-22.png b/src/qt/res/icons/drk/warning-22.png deleted file mode 100644 index f1c25d7523..0000000000 Binary files a/src/qt/res/icons/drk/warning-22.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-220.png b/src/qt/res/icons/drk/warning-220.png deleted file mode 100644 index 1fd3bca46e..0000000000 Binary files a/src/qt/res/icons/drk/warning-220.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-221.png b/src/qt/res/icons/drk/warning-221.png deleted file mode 100644 index 0a7c92c8af..0000000000 Binary files a/src/qt/res/icons/drk/warning-221.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-222.png b/src/qt/res/icons/drk/warning-222.png deleted file mode 100644 index 10f9dba448..0000000000 Binary files a/src/qt/res/icons/drk/warning-222.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-223.png b/src/qt/res/icons/drk/warning-223.png deleted file mode 100644 index 57f95c1b76..0000000000 Binary files a/src/qt/res/icons/drk/warning-223.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-224.png b/src/qt/res/icons/drk/warning-224.png deleted file mode 100644 index b24bcd4663..0000000000 Binary files a/src/qt/res/icons/drk/warning-224.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-225.png b/src/qt/res/icons/drk/warning-225.png deleted file mode 100644 index 5f74f91a77..0000000000 Binary files a/src/qt/res/icons/drk/warning-225.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-226.png b/src/qt/res/icons/drk/warning-226.png deleted file mode 100644 index fe26396516..0000000000 Binary files a/src/qt/res/icons/drk/warning-226.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-227.png b/src/qt/res/icons/drk/warning-227.png deleted file mode 100644 index 52f8b3b2f7..0000000000 Binary files a/src/qt/res/icons/drk/warning-227.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-228.png b/src/qt/res/icons/drk/warning-228.png deleted file mode 100644 index c40f65da03..0000000000 Binary files a/src/qt/res/icons/drk/warning-228.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-229.png b/src/qt/res/icons/drk/warning-229.png deleted file mode 100644 index 0bfefd11f9..0000000000 Binary files a/src/qt/res/icons/drk/warning-229.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-23.png b/src/qt/res/icons/drk/warning-23.png deleted file mode 100644 index a282f70bc4..0000000000 Binary files a/src/qt/res/icons/drk/warning-23.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-230.png b/src/qt/res/icons/drk/warning-230.png deleted file mode 100644 index d80d1ed2e7..0000000000 Binary files a/src/qt/res/icons/drk/warning-230.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-231.png b/src/qt/res/icons/drk/warning-231.png deleted file mode 100644 index 77bd858f0d..0000000000 Binary files a/src/qt/res/icons/drk/warning-231.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-232.png b/src/qt/res/icons/drk/warning-232.png deleted file mode 100644 index 767df71c17..0000000000 Binary files a/src/qt/res/icons/drk/warning-232.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-233.png b/src/qt/res/icons/drk/warning-233.png deleted file mode 100644 index 39d77f8fb2..0000000000 Binary files a/src/qt/res/icons/drk/warning-233.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-234.png b/src/qt/res/icons/drk/warning-234.png deleted file mode 100644 index 59c33ae9ae..0000000000 Binary files a/src/qt/res/icons/drk/warning-234.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-235.png b/src/qt/res/icons/drk/warning-235.png deleted file mode 100644 index 64e5524d8e..0000000000 Binary files a/src/qt/res/icons/drk/warning-235.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-236.png b/src/qt/res/icons/drk/warning-236.png deleted file mode 100644 index 85ea5eba01..0000000000 Binary files a/src/qt/res/icons/drk/warning-236.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-237.png b/src/qt/res/icons/drk/warning-237.png deleted file mode 100644 index ebcd604674..0000000000 Binary files a/src/qt/res/icons/drk/warning-237.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-238.png b/src/qt/res/icons/drk/warning-238.png deleted file mode 100644 index b019d65d9c..0000000000 Binary files a/src/qt/res/icons/drk/warning-238.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-239.png b/src/qt/res/icons/drk/warning-239.png deleted file mode 100644 index 1ef0e7307e..0000000000 Binary files a/src/qt/res/icons/drk/warning-239.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-24.png b/src/qt/res/icons/drk/warning-24.png deleted file mode 100644 index 29ccca9348..0000000000 Binary files a/src/qt/res/icons/drk/warning-24.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-240.png b/src/qt/res/icons/drk/warning-240.png deleted file mode 100644 index e466f0df69..0000000000 Binary files a/src/qt/res/icons/drk/warning-240.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-241.png b/src/qt/res/icons/drk/warning-241.png deleted file mode 100644 index d476d45ec4..0000000000 Binary files a/src/qt/res/icons/drk/warning-241.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-242.png b/src/qt/res/icons/drk/warning-242.png deleted file mode 100644 index 540770bdfe..0000000000 Binary files a/src/qt/res/icons/drk/warning-242.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-243.png b/src/qt/res/icons/drk/warning-243.png deleted file mode 100644 index 64c3664414..0000000000 Binary files a/src/qt/res/icons/drk/warning-243.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-244.png b/src/qt/res/icons/drk/warning-244.png deleted file mode 100644 index df1997dbf6..0000000000 Binary files a/src/qt/res/icons/drk/warning-244.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-245.png b/src/qt/res/icons/drk/warning-245.png deleted file mode 100644 index 8eac94f54f..0000000000 Binary files a/src/qt/res/icons/drk/warning-245.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-246.png b/src/qt/res/icons/drk/warning-246.png deleted file mode 100644 index 84b36a35ae..0000000000 Binary files a/src/qt/res/icons/drk/warning-246.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-247.png b/src/qt/res/icons/drk/warning-247.png deleted file mode 100644 index b43cd93de7..0000000000 Binary files a/src/qt/res/icons/drk/warning-247.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-248.png b/src/qt/res/icons/drk/warning-248.png deleted file mode 100644 index aaecb14a68..0000000000 Binary files a/src/qt/res/icons/drk/warning-248.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-249.png b/src/qt/res/icons/drk/warning-249.png deleted file mode 100644 index 7bedf73f0e..0000000000 Binary files a/src/qt/res/icons/drk/warning-249.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-25.png b/src/qt/res/icons/drk/warning-25.png deleted file mode 100644 index a9be8e0721..0000000000 Binary files a/src/qt/res/icons/drk/warning-25.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-250.png b/src/qt/res/icons/drk/warning-250.png deleted file mode 100644 index 761de7a4bc..0000000000 Binary files a/src/qt/res/icons/drk/warning-250.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-251.png b/src/qt/res/icons/drk/warning-251.png deleted file mode 100644 index 067be5b2b4..0000000000 Binary files a/src/qt/res/icons/drk/warning-251.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-252.png b/src/qt/res/icons/drk/warning-252.png deleted file mode 100644 index 98e94a6684..0000000000 Binary files a/src/qt/res/icons/drk/warning-252.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-253.png b/src/qt/res/icons/drk/warning-253.png deleted file mode 100644 index 71106fd1a7..0000000000 Binary files a/src/qt/res/icons/drk/warning-253.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-254.png b/src/qt/res/icons/drk/warning-254.png deleted file mode 100644 index 19fb4d3bbb..0000000000 Binary files a/src/qt/res/icons/drk/warning-254.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-255.png b/src/qt/res/icons/drk/warning-255.png deleted file mode 100644 index 7704d46511..0000000000 Binary files a/src/qt/res/icons/drk/warning-255.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-256.png b/src/qt/res/icons/drk/warning-256.png deleted file mode 100644 index 39d77f8fb2..0000000000 Binary files a/src/qt/res/icons/drk/warning-256.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-257.png b/src/qt/res/icons/drk/warning-257.png deleted file mode 100644 index c047cca88e..0000000000 Binary files a/src/qt/res/icons/drk/warning-257.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-258.png b/src/qt/res/icons/drk/warning-258.png deleted file mode 100644 index bd9e61f243..0000000000 Binary files a/src/qt/res/icons/drk/warning-258.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-259.png b/src/qt/res/icons/drk/warning-259.png deleted file mode 100644 index c782dfeacd..0000000000 Binary files a/src/qt/res/icons/drk/warning-259.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-26.png b/src/qt/res/icons/drk/warning-26.png deleted file mode 100644 index 6b02d46edd..0000000000 Binary files a/src/qt/res/icons/drk/warning-26.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-260.png b/src/qt/res/icons/drk/warning-260.png deleted file mode 100644 index 6e44eef918..0000000000 Binary files a/src/qt/res/icons/drk/warning-260.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-261.png b/src/qt/res/icons/drk/warning-261.png deleted file mode 100644 index 2fb2d508b0..0000000000 Binary files a/src/qt/res/icons/drk/warning-261.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-262.png b/src/qt/res/icons/drk/warning-262.png deleted file mode 100644 index 24489d04b5..0000000000 Binary files a/src/qt/res/icons/drk/warning-262.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-263.png b/src/qt/res/icons/drk/warning-263.png deleted file mode 100644 index 9235fe6e46..0000000000 Binary files a/src/qt/res/icons/drk/warning-263.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-264.png b/src/qt/res/icons/drk/warning-264.png deleted file mode 100644 index b159f7fa91..0000000000 Binary files a/src/qt/res/icons/drk/warning-264.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-265.png b/src/qt/res/icons/drk/warning-265.png deleted file mode 100644 index c946a287a3..0000000000 Binary files a/src/qt/res/icons/drk/warning-265.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-266.png b/src/qt/res/icons/drk/warning-266.png deleted file mode 100644 index f2820d2399..0000000000 Binary files a/src/qt/res/icons/drk/warning-266.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-267.png b/src/qt/res/icons/drk/warning-267.png deleted file mode 100644 index 4bc9f1f434..0000000000 Binary files a/src/qt/res/icons/drk/warning-267.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-268.png b/src/qt/res/icons/drk/warning-268.png deleted file mode 100644 index 28c3eb024c..0000000000 Binary files a/src/qt/res/icons/drk/warning-268.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-269.png b/src/qt/res/icons/drk/warning-269.png deleted file mode 100644 index d8d16ba447..0000000000 Binary files a/src/qt/res/icons/drk/warning-269.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-27.png b/src/qt/res/icons/drk/warning-27.png deleted file mode 100644 index 6065d5429e..0000000000 Binary files a/src/qt/res/icons/drk/warning-27.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-270.png b/src/qt/res/icons/drk/warning-270.png deleted file mode 100644 index f06188654a..0000000000 Binary files a/src/qt/res/icons/drk/warning-270.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-271.png b/src/qt/res/icons/drk/warning-271.png deleted file mode 100644 index cc84b78ff3..0000000000 Binary files a/src/qt/res/icons/drk/warning-271.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-272.png b/src/qt/res/icons/drk/warning-272.png deleted file mode 100644 index 370fb626d3..0000000000 Binary files a/src/qt/res/icons/drk/warning-272.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-273.png b/src/qt/res/icons/drk/warning-273.png deleted file mode 100644 index 4f2dad79b1..0000000000 Binary files a/src/qt/res/icons/drk/warning-273.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-274.png b/src/qt/res/icons/drk/warning-274.png deleted file mode 100644 index bc1b7fecde..0000000000 Binary files a/src/qt/res/icons/drk/warning-274.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-275.png b/src/qt/res/icons/drk/warning-275.png deleted file mode 100644 index 7b02ad91e3..0000000000 Binary files a/src/qt/res/icons/drk/warning-275.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-276.png b/src/qt/res/icons/drk/warning-276.png deleted file mode 100644 index de848ddd99..0000000000 Binary files a/src/qt/res/icons/drk/warning-276.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-277.png b/src/qt/res/icons/drk/warning-277.png deleted file mode 100644 index 08192f9430..0000000000 Binary files a/src/qt/res/icons/drk/warning-277.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-278.png b/src/qt/res/icons/drk/warning-278.png deleted file mode 100644 index afa6d55a7c..0000000000 Binary files a/src/qt/res/icons/drk/warning-278.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-279.png b/src/qt/res/icons/drk/warning-279.png deleted file mode 100644 index 40041b2e5d..0000000000 Binary files a/src/qt/res/icons/drk/warning-279.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-28.png b/src/qt/res/icons/drk/warning-28.png deleted file mode 100644 index 062688e99b..0000000000 Binary files a/src/qt/res/icons/drk/warning-28.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-280.png b/src/qt/res/icons/drk/warning-280.png deleted file mode 100644 index b4986853a0..0000000000 Binary files a/src/qt/res/icons/drk/warning-280.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-281.png b/src/qt/res/icons/drk/warning-281.png deleted file mode 100644 index e365b6f4e1..0000000000 Binary files a/src/qt/res/icons/drk/warning-281.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-282.png b/src/qt/res/icons/drk/warning-282.png deleted file mode 100644 index fc38cbdcb9..0000000000 Binary files a/src/qt/res/icons/drk/warning-282.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-283.png b/src/qt/res/icons/drk/warning-283.png deleted file mode 100644 index f99aeb7149..0000000000 Binary files a/src/qt/res/icons/drk/warning-283.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-284.png b/src/qt/res/icons/drk/warning-284.png deleted file mode 100644 index c7797af2e6..0000000000 Binary files a/src/qt/res/icons/drk/warning-284.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-285.png b/src/qt/res/icons/drk/warning-285.png deleted file mode 100644 index 94e89f7315..0000000000 Binary files a/src/qt/res/icons/drk/warning-285.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-286.png b/src/qt/res/icons/drk/warning-286.png deleted file mode 100644 index 1c865cf059..0000000000 Binary files a/src/qt/res/icons/drk/warning-286.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-287.png b/src/qt/res/icons/drk/warning-287.png deleted file mode 100644 index ea4d842918..0000000000 Binary files a/src/qt/res/icons/drk/warning-287.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-288.png b/src/qt/res/icons/drk/warning-288.png deleted file mode 100644 index 1e599c7ecd..0000000000 Binary files a/src/qt/res/icons/drk/warning-288.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-289.png b/src/qt/res/icons/drk/warning-289.png deleted file mode 100644 index 2492e9372a..0000000000 Binary files a/src/qt/res/icons/drk/warning-289.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-29.png b/src/qt/res/icons/drk/warning-29.png deleted file mode 100644 index 2e3541a1f7..0000000000 Binary files a/src/qt/res/icons/drk/warning-29.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-290.png b/src/qt/res/icons/drk/warning-290.png deleted file mode 100644 index 2c3db76852..0000000000 Binary files a/src/qt/res/icons/drk/warning-290.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-291.png b/src/qt/res/icons/drk/warning-291.png deleted file mode 100644 index 5dbb80ac95..0000000000 Binary files a/src/qt/res/icons/drk/warning-291.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-292.png b/src/qt/res/icons/drk/warning-292.png deleted file mode 100644 index 1e8742c31a..0000000000 Binary files a/src/qt/res/icons/drk/warning-292.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-293.png b/src/qt/res/icons/drk/warning-293.png deleted file mode 100644 index 8d6de57d8f..0000000000 Binary files a/src/qt/res/icons/drk/warning-293.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-294.png b/src/qt/res/icons/drk/warning-294.png deleted file mode 100644 index 098254bdcd..0000000000 Binary files a/src/qt/res/icons/drk/warning-294.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-295.png b/src/qt/res/icons/drk/warning-295.png deleted file mode 100644 index a29d5405fa..0000000000 Binary files a/src/qt/res/icons/drk/warning-295.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-296.png b/src/qt/res/icons/drk/warning-296.png deleted file mode 100644 index 43953e32a5..0000000000 Binary files a/src/qt/res/icons/drk/warning-296.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-297.png b/src/qt/res/icons/drk/warning-297.png deleted file mode 100644 index d341c8bcb7..0000000000 Binary files a/src/qt/res/icons/drk/warning-297.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-298.png b/src/qt/res/icons/drk/warning-298.png deleted file mode 100644 index 067be5b2b4..0000000000 Binary files a/src/qt/res/icons/drk/warning-298.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-299.png b/src/qt/res/icons/drk/warning-299.png deleted file mode 100644 index 450f750b1c..0000000000 Binary files a/src/qt/res/icons/drk/warning-299.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-3.png b/src/qt/res/icons/drk/warning-3.png deleted file mode 100644 index 2462c7347f..0000000000 Binary files a/src/qt/res/icons/drk/warning-3.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-30.png b/src/qt/res/icons/drk/warning-30.png deleted file mode 100644 index 901c26f82f..0000000000 Binary files a/src/qt/res/icons/drk/warning-30.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-300.png b/src/qt/res/icons/drk/warning-300.png deleted file mode 100644 index 43953e32a5..0000000000 Binary files a/src/qt/res/icons/drk/warning-300.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-301.png b/src/qt/res/icons/drk/warning-301.png deleted file mode 100644 index f31ae76bd1..0000000000 Binary files a/src/qt/res/icons/drk/warning-301.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-302.png b/src/qt/res/icons/drk/warning-302.png deleted file mode 100644 index f04ca22419..0000000000 Binary files a/src/qt/res/icons/drk/warning-302.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-303.png b/src/qt/res/icons/drk/warning-303.png deleted file mode 100644 index 114345eeff..0000000000 Binary files a/src/qt/res/icons/drk/warning-303.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-304.png b/src/qt/res/icons/drk/warning-304.png deleted file mode 100644 index bf87575fb3..0000000000 Binary files a/src/qt/res/icons/drk/warning-304.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-305.png b/src/qt/res/icons/drk/warning-305.png deleted file mode 100644 index 9c475c182a..0000000000 Binary files a/src/qt/res/icons/drk/warning-305.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-306.png b/src/qt/res/icons/drk/warning-306.png deleted file mode 100644 index 7bbbb1a201..0000000000 Binary files a/src/qt/res/icons/drk/warning-306.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-307.png b/src/qt/res/icons/drk/warning-307.png deleted file mode 100644 index 4dfa656940..0000000000 Binary files a/src/qt/res/icons/drk/warning-307.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-308.png b/src/qt/res/icons/drk/warning-308.png deleted file mode 100644 index 900145702f..0000000000 Binary files a/src/qt/res/icons/drk/warning-308.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-309.png b/src/qt/res/icons/drk/warning-309.png deleted file mode 100644 index a1aacd2d27..0000000000 Binary files a/src/qt/res/icons/drk/warning-309.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-31.png b/src/qt/res/icons/drk/warning-31.png deleted file mode 100644 index 2bf5d343d0..0000000000 Binary files a/src/qt/res/icons/drk/warning-31.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-310.png b/src/qt/res/icons/drk/warning-310.png deleted file mode 100644 index d050b8138b..0000000000 Binary files a/src/qt/res/icons/drk/warning-310.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-32.png b/src/qt/res/icons/drk/warning-32.png deleted file mode 100644 index d443c30e67..0000000000 Binary files a/src/qt/res/icons/drk/warning-32.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-33.png b/src/qt/res/icons/drk/warning-33.png deleted file mode 100644 index 3e30299a45..0000000000 Binary files a/src/qt/res/icons/drk/warning-33.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-34.png b/src/qt/res/icons/drk/warning-34.png deleted file mode 100644 index 2ba6a1f19b..0000000000 Binary files a/src/qt/res/icons/drk/warning-34.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-35.png b/src/qt/res/icons/drk/warning-35.png deleted file mode 100644 index 5857324be6..0000000000 Binary files a/src/qt/res/icons/drk/warning-35.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-36.png b/src/qt/res/icons/drk/warning-36.png deleted file mode 100644 index f9306cc1eb..0000000000 Binary files a/src/qt/res/icons/drk/warning-36.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-37.png b/src/qt/res/icons/drk/warning-37.png deleted file mode 100644 index 00022418b3..0000000000 Binary files a/src/qt/res/icons/drk/warning-37.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-38.png b/src/qt/res/icons/drk/warning-38.png deleted file mode 100644 index 03e11b0c58..0000000000 Binary files a/src/qt/res/icons/drk/warning-38.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-39.png b/src/qt/res/icons/drk/warning-39.png deleted file mode 100644 index 20627eba2f..0000000000 Binary files a/src/qt/res/icons/drk/warning-39.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-4.png b/src/qt/res/icons/drk/warning-4.png deleted file mode 100644 index 8c3b0f3cc2..0000000000 Binary files a/src/qt/res/icons/drk/warning-4.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-40.png b/src/qt/res/icons/drk/warning-40.png deleted file mode 100644 index fbc99edfb5..0000000000 Binary files a/src/qt/res/icons/drk/warning-40.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-41.png b/src/qt/res/icons/drk/warning-41.png deleted file mode 100644 index d608e4f459..0000000000 Binary files a/src/qt/res/icons/drk/warning-41.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-42.png b/src/qt/res/icons/drk/warning-42.png deleted file mode 100644 index 7e812352be..0000000000 Binary files a/src/qt/res/icons/drk/warning-42.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-43.png b/src/qt/res/icons/drk/warning-43.png deleted file mode 100644 index 38bbf47dca..0000000000 Binary files a/src/qt/res/icons/drk/warning-43.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-44.png b/src/qt/res/icons/drk/warning-44.png deleted file mode 100644 index 7d30ddbc47..0000000000 Binary files a/src/qt/res/icons/drk/warning-44.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-45.png b/src/qt/res/icons/drk/warning-45.png deleted file mode 100644 index 3ec2f12ace..0000000000 Binary files a/src/qt/res/icons/drk/warning-45.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-46.png b/src/qt/res/icons/drk/warning-46.png deleted file mode 100644 index b4571a354c..0000000000 Binary files a/src/qt/res/icons/drk/warning-46.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-47.png b/src/qt/res/icons/drk/warning-47.png deleted file mode 100644 index 67456cde4e..0000000000 Binary files a/src/qt/res/icons/drk/warning-47.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-48.png b/src/qt/res/icons/drk/warning-48.png deleted file mode 100644 index f78dc294cf..0000000000 Binary files a/src/qt/res/icons/drk/warning-48.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-49.png b/src/qt/res/icons/drk/warning-49.png deleted file mode 100644 index 7a29cb890d..0000000000 Binary files a/src/qt/res/icons/drk/warning-49.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-5.png b/src/qt/res/icons/drk/warning-5.png deleted file mode 100644 index 9d4227ab6f..0000000000 Binary files a/src/qt/res/icons/drk/warning-5.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-50.png b/src/qt/res/icons/drk/warning-50.png deleted file mode 100644 index ef153f17ff..0000000000 Binary files a/src/qt/res/icons/drk/warning-50.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-51.png b/src/qt/res/icons/drk/warning-51.png deleted file mode 100644 index 96b604ff54..0000000000 Binary files a/src/qt/res/icons/drk/warning-51.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-52.png b/src/qt/res/icons/drk/warning-52.png deleted file mode 100644 index 5dd1fcc4fb..0000000000 Binary files a/src/qt/res/icons/drk/warning-52.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-53.png b/src/qt/res/icons/drk/warning-53.png deleted file mode 100644 index ac95611a4a..0000000000 Binary files a/src/qt/res/icons/drk/warning-53.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-54.png b/src/qt/res/icons/drk/warning-54.png deleted file mode 100644 index 32e43916c7..0000000000 Binary files a/src/qt/res/icons/drk/warning-54.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-55.png b/src/qt/res/icons/drk/warning-55.png deleted file mode 100644 index c09429de78..0000000000 Binary files a/src/qt/res/icons/drk/warning-55.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-56.png b/src/qt/res/icons/drk/warning-56.png deleted file mode 100644 index 7022636d82..0000000000 Binary files a/src/qt/res/icons/drk/warning-56.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-57.png b/src/qt/res/icons/drk/warning-57.png deleted file mode 100644 index 7fe344e6fa..0000000000 Binary files a/src/qt/res/icons/drk/warning-57.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-58.png b/src/qt/res/icons/drk/warning-58.png deleted file mode 100644 index 2217e1f3a4..0000000000 Binary files a/src/qt/res/icons/drk/warning-58.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-59.png b/src/qt/res/icons/drk/warning-59.png deleted file mode 100644 index 79e0be9fce..0000000000 Binary files a/src/qt/res/icons/drk/warning-59.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-6.png b/src/qt/res/icons/drk/warning-6.png deleted file mode 100644 index 25fe6e1998..0000000000 Binary files a/src/qt/res/icons/drk/warning-6.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-60.png b/src/qt/res/icons/drk/warning-60.png deleted file mode 100644 index 7ee669fc59..0000000000 Binary files a/src/qt/res/icons/drk/warning-60.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-61.png b/src/qt/res/icons/drk/warning-61.png deleted file mode 100644 index d555fe7948..0000000000 Binary files a/src/qt/res/icons/drk/warning-61.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-62.png b/src/qt/res/icons/drk/warning-62.png deleted file mode 100644 index aab8d0ca9e..0000000000 Binary files a/src/qt/res/icons/drk/warning-62.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-63.png b/src/qt/res/icons/drk/warning-63.png deleted file mode 100644 index 52ffd78fa1..0000000000 Binary files a/src/qt/res/icons/drk/warning-63.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-64.png b/src/qt/res/icons/drk/warning-64.png deleted file mode 100644 index d0132dea71..0000000000 Binary files a/src/qt/res/icons/drk/warning-64.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-65.png b/src/qt/res/icons/drk/warning-65.png deleted file mode 100644 index dc8aab70e2..0000000000 Binary files a/src/qt/res/icons/drk/warning-65.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-66.png b/src/qt/res/icons/drk/warning-66.png deleted file mode 100644 index 7c793bfaac..0000000000 Binary files a/src/qt/res/icons/drk/warning-66.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-67.png b/src/qt/res/icons/drk/warning-67.png deleted file mode 100644 index 48ba4ccb33..0000000000 Binary files a/src/qt/res/icons/drk/warning-67.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-68.png b/src/qt/res/icons/drk/warning-68.png deleted file mode 100644 index 87af8f8fe2..0000000000 Binary files a/src/qt/res/icons/drk/warning-68.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-69.png b/src/qt/res/icons/drk/warning-69.png deleted file mode 100644 index 4ee39ac305..0000000000 Binary files a/src/qt/res/icons/drk/warning-69.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-7.png b/src/qt/res/icons/drk/warning-7.png deleted file mode 100644 index 1e134ff929..0000000000 Binary files a/src/qt/res/icons/drk/warning-7.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-70.png b/src/qt/res/icons/drk/warning-70.png deleted file mode 100644 index 8699c56341..0000000000 Binary files a/src/qt/res/icons/drk/warning-70.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-71.png b/src/qt/res/icons/drk/warning-71.png deleted file mode 100644 index 65f77c4400..0000000000 Binary files a/src/qt/res/icons/drk/warning-71.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-72.png b/src/qt/res/icons/drk/warning-72.png deleted file mode 100644 index 7c5b01bb14..0000000000 Binary files a/src/qt/res/icons/drk/warning-72.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-73.png b/src/qt/res/icons/drk/warning-73.png deleted file mode 100644 index d11e218e0c..0000000000 Binary files a/src/qt/res/icons/drk/warning-73.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-74.png b/src/qt/res/icons/drk/warning-74.png deleted file mode 100644 index 7db6a7a672..0000000000 Binary files a/src/qt/res/icons/drk/warning-74.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-75.png b/src/qt/res/icons/drk/warning-75.png deleted file mode 100644 index 7022636d82..0000000000 Binary files a/src/qt/res/icons/drk/warning-75.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-76.png b/src/qt/res/icons/drk/warning-76.png deleted file mode 100644 index 7fe344e6fa..0000000000 Binary files a/src/qt/res/icons/drk/warning-76.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-77.png b/src/qt/res/icons/drk/warning-77.png deleted file mode 100644 index 5b90d5098b..0000000000 Binary files a/src/qt/res/icons/drk/warning-77.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-78.png b/src/qt/res/icons/drk/warning-78.png deleted file mode 100644 index 0bf82eeabf..0000000000 Binary files a/src/qt/res/icons/drk/warning-78.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-79.png b/src/qt/res/icons/drk/warning-79.png deleted file mode 100644 index a33e2f1e47..0000000000 Binary files a/src/qt/res/icons/drk/warning-79.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-8.png b/src/qt/res/icons/drk/warning-8.png deleted file mode 100644 index 5518d94c90..0000000000 Binary files a/src/qt/res/icons/drk/warning-8.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-80.png b/src/qt/res/icons/drk/warning-80.png deleted file mode 100644 index 48c23ba95c..0000000000 Binary files a/src/qt/res/icons/drk/warning-80.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-81.png b/src/qt/res/icons/drk/warning-81.png deleted file mode 100644 index 70b9c3d1a1..0000000000 Binary files a/src/qt/res/icons/drk/warning-81.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-82.png b/src/qt/res/icons/drk/warning-82.png deleted file mode 100644 index 17bee991b5..0000000000 Binary files a/src/qt/res/icons/drk/warning-82.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-83.png b/src/qt/res/icons/drk/warning-83.png deleted file mode 100644 index b5a5db9927..0000000000 Binary files a/src/qt/res/icons/drk/warning-83.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-84.png b/src/qt/res/icons/drk/warning-84.png deleted file mode 100644 index afcbac59f5..0000000000 Binary files a/src/qt/res/icons/drk/warning-84.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-85.png b/src/qt/res/icons/drk/warning-85.png deleted file mode 100644 index 850d73d70b..0000000000 Binary files a/src/qt/res/icons/drk/warning-85.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-86.png b/src/qt/res/icons/drk/warning-86.png deleted file mode 100644 index 2ecf7a27f0..0000000000 Binary files a/src/qt/res/icons/drk/warning-86.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-87.png b/src/qt/res/icons/drk/warning-87.png deleted file mode 100644 index 7b8625776d..0000000000 Binary files a/src/qt/res/icons/drk/warning-87.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-88.png b/src/qt/res/icons/drk/warning-88.png deleted file mode 100644 index 79ae1de5d3..0000000000 Binary files a/src/qt/res/icons/drk/warning-88.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-89.png b/src/qt/res/icons/drk/warning-89.png deleted file mode 100644 index 9943b74d87..0000000000 Binary files a/src/qt/res/icons/drk/warning-89.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-9.png b/src/qt/res/icons/drk/warning-9.png deleted file mode 100644 index 441bae305b..0000000000 Binary files a/src/qt/res/icons/drk/warning-9.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-90.png b/src/qt/res/icons/drk/warning-90.png deleted file mode 100644 index e0613382fd..0000000000 Binary files a/src/qt/res/icons/drk/warning-90.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-91.png b/src/qt/res/icons/drk/warning-91.png deleted file mode 100644 index 67bdd30055..0000000000 Binary files a/src/qt/res/icons/drk/warning-91.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-92.png b/src/qt/res/icons/drk/warning-92.png deleted file mode 100644 index 84c116ce35..0000000000 Binary files a/src/qt/res/icons/drk/warning-92.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-93.png b/src/qt/res/icons/drk/warning-93.png deleted file mode 100644 index 39de1a60ff..0000000000 Binary files a/src/qt/res/icons/drk/warning-93.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-94.png b/src/qt/res/icons/drk/warning-94.png deleted file mode 100644 index 6840739416..0000000000 Binary files a/src/qt/res/icons/drk/warning-94.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-95.png b/src/qt/res/icons/drk/warning-95.png deleted file mode 100644 index 2d5b3d1128..0000000000 Binary files a/src/qt/res/icons/drk/warning-95.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-96.png b/src/qt/res/icons/drk/warning-96.png deleted file mode 100644 index b7b244bcaf..0000000000 Binary files a/src/qt/res/icons/drk/warning-96.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-97.png b/src/qt/res/icons/drk/warning-97.png deleted file mode 100644 index 10b3b831b3..0000000000 Binary files a/src/qt/res/icons/drk/warning-97.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-98.png b/src/qt/res/icons/drk/warning-98.png deleted file mode 100644 index 7ee669fc59..0000000000 Binary files a/src/qt/res/icons/drk/warning-98.png and /dev/null differ diff --git a/src/qt/res/icons/drk/warning-99.png b/src/qt/res/icons/drk/warning-99.png deleted file mode 100644 index 2d670ee606..0000000000 Binary files a/src/qt/res/icons/drk/warning-99.png and /dev/null differ diff --git a/src/qt/swapdialog.cpp b/src/qt/swapdialog.cpp new file mode 100644 index 0000000000..d669993c93 --- /dev/null +++ b/src/qt/swapdialog.cpp @@ -0,0 +1,149 @@ +// Copyright (c) 2021-present Duality Blockchain Solutions Developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "swapdialog.h" +#include "ui_swapdialog.h" + +#include "askpassphrasedialog.h" +#include "guiutil.h" +#include "rpc/server.h" +#include "swap/ss58.h" +#include "utilmoneystr.h" +#include "wallet/wallet.h" +#include "walletmodel.h" + +#include + +#include +#include + +SwapDialog::SwapDialog(QWidget* parent) : QDialog(parent), ui(new Ui::SwapDialog) +{ + ui->setupUi(this); +#if QT_VERSION >= 0x040700 + ui->swapAddress->setPlaceholderText("Enter your swap address here"); +#endif + // ok button + connect(ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(buttonBoxClicked(QAbstractButton*))); +#ifdef ENABLE_WALLET + if (pwalletMain) { + walletLocked = pwalletMain->IsLocked(); + totalBalance = pwalletMain->GetBalance(); + lockedBalance = pwalletMain->LockedCoinsTotal(); + swapBalance = pwalletMain->SwapBalance(); + immatureBalance = totalBalance - swapBalance - lockedBalance; + std::string label = ""; + QString questionString = tr(label.c_str()); + questionString.append("
"); + label = ""; + questionString.append(tr(label.c_str())); + questionString.append("
"); + label = ""; + questionString.append(tr(label.c_str())); + questionString.append("

"); + label = ""; + questionString.append(tr(label.c_str())); + ui->label_swapInfo->setText(QObject::tr(questionString.toStdString().c_str())); + } else { + walletLocked = true; + totalBalance = 0; + immatureBalance = 0; + lockedBalance = 0; + ui->label_swapInfo->setText(QObject::tr("Unable to access wallet. Please close this swap window.")); + } +#endif // ENABLE_WALLET +} + +SwapDialog::~SwapDialog() +{ + delete ui; +} + +#ifdef ENABLE_WALLET + +void SwapDialog::setWalletModel(WalletModel* _walletModel) +{ + this->walletModel = _walletModel; +} + +bool SwapDialog::swapDynamic() +{ + std::string errorMessage = ""; + UniValue result = SwapDynamic(ui->swapAddress->text().toStdString(), true, errorMessage); + if (errorMessage != "") { + QMessageBox::critical(0, "Swap Dynamic Error", QObject::tr(errorMessage.c_str())); + return false; + } + return true; +} + +#endif // ENABLE_WALLET + +QString SwapDialog::getSwapAddress() +{ + return ui->swapAddress->text(); +} + +void SwapDialog::buttonBoxClicked(QAbstractButton* button) +{ +#ifdef ENABLE_WALLET + if (ui->buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole) { + if (swapBalance <= 0) { + QMessageBox::critical(this, QObject::tr("Invalid Amount"), QObject::tr("Swap amount must be greater than 0")); + done(QDialog::Rejected); // closes the dialog + return; + } + CSS58 swapAddress(getSwapAddress().toStdString()); + if (swapAddress.strError == "") { + // show fee, amount of coins swapping and swap address + QString questionString = tr("Are you sure you want to swap?"); + questionString.append("
"); + questionString.append("
"); + questionString.append(" "); + std::string label = ""; + questionString.append(label.c_str()); + questionString.append("
"); + label = ""; + questionString.append(tr(label.c_str())); + QMessageBox::StandardButton retval = + QMessageBox::question(this, tr("Confirm swap coins"), questionString, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel); + + if (retval != QMessageBox::Yes) { + done(QDialog::Rejected); // closes the dialog + } else { + if (walletLocked) { + AskPassphraseDialog dlg(AskPassphraseDialog::Unlock, this); + dlg.setModel(walletModel); + dlg.exec(); + walletLocked = pwalletMain->IsLocked(); + if (walletLocked) { + done(QDialog::Rejected); // closes the dialog + } else { + if (swapDynamic()) { + pwalletMain->Lock(); + done(QDialog::Accepted); // closes the dialog + } else { + done(QDialog::Rejected); // closes the dialog + } + } + } + else { + if (swapDynamic()) { + done(QDialog::Accepted); // closes the dialog + } else { + done(QDialog::Rejected); // closes the dialog + } + } + } + } else { // SS58 error + QMessageBox::critical(this, QObject::tr("Address validation failed"), QObject::tr(swapAddress.strError.c_str())); + } + } + else { + done(QDialog::Accepted); // closes the dialog + } +#elif + done(QDialog::Rejected); // closes the dialog +#endif // ENABLE_WALLET +} \ No newline at end of file diff --git a/src/qt/swapdialog.h b/src/qt/swapdialog.h new file mode 100644 index 0000000000..c163e6137d --- /dev/null +++ b/src/qt/swapdialog.h @@ -0,0 +1,48 @@ +// Copyright (c) 2021-present Duality Blockchain Solutions Developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef DYNAMIC_QT_SWAPDIALOG_H +#define DYNAMIC_QT_SWAPDIALOG_H + +#include "amount.h" + +#include +#include + +namespace Ui +{ +class SwapDialog; +} + +class WalletModel; + +class SwapDialog : public QDialog +{ + Q_OBJECT + +public: + explicit SwapDialog(QWidget* parent); + ~SwapDialog(); + + void setWalletModel(WalletModel* _walletModel); + +protected Q_SLOTS: + +private Q_SLOTS: + void buttonBoxClicked(QAbstractButton*); + +private: + Ui::SwapDialog* ui; + WalletModel* walletModel; + CAmount totalBalance; + CAmount immatureBalance; + CAmount lockedBalance; + CAmount swapBalance; + bool walletLocked; + + QString getSwapAddress(); + bool swapDynamic(); +}; + +#endif // DYNAMIC_QT_SWAPDIALOG_H diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 17c6ba325d..51fffbfcc1 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -262,6 +262,15 @@ QList TransactionRecord::decomposeTransaction(const CWallet* } } } + } else if (txout.scriptPubKey.IsUnspendable()) { + // ToDo: Parse Swap address to show in UI + sub.type = TransactionRecord::Swap; + std::vector vchData; + if (txout.GetData(vchData)) { + sub.address = EncodeBase58(vchData); + } else { + sub.address = "OP_RETURN Data Burn"; + } } if (IsTransactionFluid(txout.scriptPubKey)) { sub.type = TransactionRecord::Fluid; diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h index 2fd9045615..5399ea302a 100644 --- a/src/qt/transactionrecord.h +++ b/src/qt/transactionrecord.h @@ -106,7 +106,8 @@ class TransactionRecord NewAudit, NewCertificate, ApproveCertificate, - ApproveRootCertificate + ApproveRootCertificate, + Swap }; /** Number of confirmation recommended for accepting a transaction */ diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 13c6fa9d64..8a581dc3d9 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -399,6 +399,8 @@ QString TransactionTableModel::formatTxType(const TransactionRecord* wtx) const return tr("PrivateSend Create Denominations"); case TransactionRecord::PrivateSend: return tr("PrivateSend"); + case TransactionRecord::Swap: + return tr("Swap"); default: return QString(); @@ -505,6 +507,8 @@ QString TransactionTableModel::formatTxToAddress(const TransactionRecord* wtx, b return tr("Certificate Approved Entry"); case TransactionRecord::ApproveRootCertificate: return tr("Certificate Root Entry"); + case TransactionRecord::Swap: + return QString::fromStdString(wtx->address); case TransactionRecord::SendToSelf: default: return tr("(n/a)") + watchAddress; diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 2644eed045..b1e33d7e20 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -121,6 +121,7 @@ TransactionView::TransactionView(const PlatformStyle* platformStyle, QWidget* pa TransactionFilterProxy::TYPE(TransactionRecord::RevokeDomainGroup) | TransactionFilterProxy::TYPE(TransactionRecord::LinkRequest) | TransactionFilterProxy::TYPE(TransactionRecord::LinkAccept)); + typeWidget->addItem(tr("Swap"), TransactionFilterProxy::TYPE(TransactionRecord::Swap)); typeWidget->addItem(tr("Other"), TransactionFilterProxy::TYPE(TransactionRecord::Other)); typeWidget->setCurrentIndex(settings.value("transactionType").toInt()); diff --git a/src/random.cpp b/src/random.cpp index 31767f561d..ba51d0b40a 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -20,6 +20,8 @@ #include #include +#include + #ifndef WIN32 #include #include @@ -48,6 +50,7 @@ #include #include +#include [[noreturn]] static void RandFailure() { @@ -55,7 +58,7 @@ std::abort(); } -static inline int64_t GetPerformanceCounter() +static inline int64_t GetPerformanceCounter() noexcept { // Read the hardware time stamp counter when available. // See https://en.wikipedia.org/wiki/Time_Stamp_Counter for more information. @@ -75,27 +78,38 @@ static inline int64_t GetPerformanceCounter() #endif } - #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__) -static std::atomic hwrand_initialized{false}; static bool rdrand_supported = false; static constexpr uint32_t CPUID_F1_ECX_RDRAND = 0x40000000; -static void RDRandInit() +static void InitHardwareRand() { uint32_t eax, ebx, ecx, edx; if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) && (ecx & CPUID_F1_ECX_RDRAND)) { - LogPrintf("Using RdRand as an additional entropy source\n"); rdrand_supported = true; } - hwrand_initialized.store(true); } + +static void ReportHardwareRand() +{ + if (rdrand_supported) { + // This must be done in a separate function, as HWRandInit() may be indirectly called + // from global constructors, before logging is initialized. + LogPrintf("Using RdRand as an additional entropy source\n"); + } +} + #else -static void RDRandInit() {} +/* Access to other hardware random number generators could be added here later, + * assuming it is sufficiently fast (in the order of a few hundred CPU cycles). + * Slower sources should probably be invoked separately, and/or only from + * RandAddSeedSleep (which is called during idle background operation). + */ +static void InitHardwareRand() {} +static void ReportHardwareRand() {} #endif -static bool GetHWRand(unsigned char* ent32) { +static bool GetHardwareRand(unsigned char* ent32) noexcept { #if defined(__x86_64__) || defined(__amd64__) || defined(__i386__) - assert(hwrand_initialized.load(std::memory_order_relaxed)); if (rdrand_supported) { uint8_t ok; // Not all assemblers support the rdrand instruction, write it in hex. @@ -130,18 +144,8 @@ static bool GetHWRand(unsigned char* ent32) { return false; } -void RandAddSeed() +static void RandAddSeedPerfmon(CSHA512& hasher) { - // Seed with CPU performance counter - int64_t nCounter = GetPerformanceCounter(); - RAND_add(&nCounter, sizeof(nCounter), 1.5); - memory_cleanse((void*)&nCounter, sizeof(nCounter)); -} - -static void RandAddSeedPerfmon() -{ - RandAddSeed(); - #ifdef WIN32 // Don't need this on Linux, OpenSSL automatically uses /dev/urandom // Seed with the entire set of perfmon data @@ -165,15 +169,15 @@ static void RandAddSeedPerfmon() } RegCloseKey(HKEY_PERFORMANCE_DATA); if (ret == ERROR_SUCCESS) { - RAND_add(vData.data(), nSize, nSize / 100.0); + hasher.Write(vData.data(), nSize); memory_cleanse(vData.data(), nSize); - LogPrint("rand", "%s: %lu bytes\n", __func__, nSize); } else { - static bool warned = false; // Warn only once - if (!warned) { - LogPrintf("%s: Warning: RegQueryValueExA(HKEY_PERFORMANCE_DATA) failed with code %i\n", __func__, ret); - warned = true; - } + // Performance data is only a best-effort attempt at improving the + // situation when the OS randomness (and other sources) aren't + // adequate. As a result, failure to read it is isn't considered critical, + // so we don't call RandFailure(). + // TODO: Add logging when the logger is made functional before global + // constructors have been invoked. } #endif } @@ -273,106 +277,255 @@ void GetOSRand(unsigned char *ent32) #endif } -void GetRandBytes(unsigned char* buf, int num) +void LockingCallbackOpenSSL(int mode, int i, const char* file, int line); + +namespace { + +class RNGState { + Mutex m_mutex; + /* The RNG state consists of 256 bits of entropy, taken from the output of + * one operation's SHA512 output, and fed as input to the next one. + * Carrying 256 bits of entropy should be sufficient to guarantee + * unpredictability as long as any entropy source was ever unpredictable + * to an attacker. To protect against situations where an attacker might + * observe the RNG's state, fresh entropy is always mixed when + * GetStrongRandBytes is called. + */ + unsigned char m_state[32] GUARDED_BY(m_mutex) = {0}; + uint64_t m_counter GUARDED_BY(m_mutex) = 0; + bool m_strongly_seeded GUARDED_BY(m_mutex) = false; + std::unique_ptr m_mutex_openssl; + +public: + RNGState() noexcept + { + InitHardwareRand(); + + // Init OpenSSL library multithreading support + m_mutex_openssl.reset(new Mutex[CRYPTO_num_locks()]); + CRYPTO_set_locking_callback(LockingCallbackOpenSSL); + + // OpenSSL can optionally load a config file which lists optional loadable modules and engines. + // We don't use them so we don't require the config. However some of our libs may call functions + // which attempt to load the config file, possibly resulting in an exit() or crash if it is missing + // or corrupt. Explicitly tell OpenSSL not to try to load the file. The result for our libs will be + // that the config appears to have been loaded and there are no modules/engines available. + OPENSSL_no_config(); + } + + ~RNGState() + { + // Securely erase the memory used by the OpenSSL PRNG + RAND_cleanup(); + // Shutdown OpenSSL library multithreading support + CRYPTO_set_locking_callback(nullptr); + } + + /** Extract up to 32 bytes of entropy from the RNG state, mixing in new entropy from hasher. + * + * If this function has never been called with strong_seed = true, false is returned. + */ + bool MixExtract(unsigned char* out, size_t num, CSHA512&& hasher, bool strong_seed) noexcept + { + assert(num <= 32); + unsigned char buf[64]; + static_assert(sizeof(buf) == CSHA512::OUTPUT_SIZE, "Buffer needs to have hasher's output size"); + bool ret; + { + LOCK(m_mutex); + ret = (m_strongly_seeded |= strong_seed); + // Write the current state of the RNG into the hasher + hasher.Write(m_state, 32); + // Write a new counter number into the state + hasher.Write((const unsigned char*)&m_counter, sizeof(m_counter)); + ++m_counter; + // Finalize the hasher + hasher.Finalize(buf); + // Store the last 32 bytes of the hash output as new RNG state. + memcpy(m_state, buf + 32, 32); + } + // If desired, copy (up to) the first 32 bytes of the hash output as output. + if (num) { + assert(out != nullptr); + memcpy(out, buf, num); + } + // Best effort cleanup of internal state + hasher.Reset(); + memory_cleanse(buf, 64); + return ret; + } + + Mutex& GetOpenSSLMutex(int i) { return m_mutex_openssl[i]; } +}; + +RNGState& GetRNGState() noexcept { - if (RAND_bytes(buf, num) != 1) { - RandFailure(); + // This C++11 idiom relies on the guarantee that static variable are initialized + // on first call, even when multiple parallel calls are permitted. + static std::vector> g_rng(1); + return g_rng[0]; +} +} + +void LockingCallbackOpenSSL(int mode, int i, const char* file, int line) NO_THREAD_SAFETY_ANALYSIS +{ + RNGState& rng = GetRNGState(); + + if (mode & CRYPTO_LOCK) { + rng.GetOpenSSLMutex(i).lock(); + } else { + rng.GetOpenSSLMutex(i).unlock(); } } -static void AddDataToRng(void* data, size_t len); +/* A note on the use of noexcept in the seeding functions below: + * + * None of the RNG code should ever throw any exception, with the sole exception + * of MilliSleep in SeedSleep, which can (and does) support interruptions which + * cause a boost::thread_interrupted to be thrown. + * + * This means that SeedSleep, and all functions that invoke it are throwing. + * However, we know that GetRandBytes() and GetStrongRandBytes() never trigger + * this sleeping logic, so they are noexcept. The same is true for all the + * GetRand*() functions that use GetRandBytes() indirectly. + * + * TODO: After moving away from interruptible boost-based thread management, + * everything can become noexcept here. + */ -void RandAddSeedSleep() +static void SeedTimestamp(CSHA512& hasher) noexcept { - int64_t nPerfCounter1 = GetPerformanceCounter(); - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - int64_t nPerfCounter2 = GetPerformanceCounter(); + int64_t perfcounter = GetPerformanceCounter(); + hasher.Write((const unsigned char*)&perfcounter, sizeof(perfcounter)); +} - // Combine with and update state - AddDataToRng(&nPerfCounter1, sizeof(nPerfCounter1)); - AddDataToRng(&nPerfCounter2, sizeof(nPerfCounter2)); +static void SeedFast(CSHA512& hasher) noexcept +{ + unsigned char buffer[32]; + + // Stack pointer to indirectly commit to thread/callstack + const unsigned char* ptr = buffer; + hasher.Write((const unsigned char*)&ptr, sizeof(ptr)); + + // Hardware randomness is very fast when available; use it always. + bool have_hw_rand = GetHardwareRand(buffer); + if (have_hw_rand) hasher.Write(buffer, sizeof(buffer)); - memory_cleanse(&nPerfCounter1, sizeof(nPerfCounter1)); - memory_cleanse(&nPerfCounter2, sizeof(nPerfCounter2)); + // High-precision timestamp + SeedTimestamp(hasher); } +static void SeedSlow(CSHA512& hasher) noexcept +{ + unsigned char buffer[32]; -static Mutex cs_rng_state; -static unsigned char rng_state[32] = {0}; -static uint64_t rng_counter = 0; + // Everything that the 'fast' seeder includes + SeedFast(hasher); -static void AddDataToRng(void* data, size_t len) { - CSHA512 hasher; - hasher.Write((const unsigned char*)&len, sizeof(len)); - hasher.Write((const unsigned char*)data, len); - unsigned char buf[64]; - { - WAIT_LOCK(cs_rng_state, lock); - hasher.Write(rng_state, sizeof(rng_state)); - hasher.Write((const unsigned char*)&rng_counter, sizeof(rng_counter)); - ++rng_counter; - hasher.Finalize(buf); - memcpy(rng_state, buf + 32, 32); - } - memory_cleanse(buf, 64); + // OS randomness + GetOSRand(buffer); + hasher.Write(buffer, sizeof(buffer)); + + // OpenSSL RNG (for now) + RAND_bytes(buffer, sizeof(buffer)); + hasher.Write(buffer, sizeof(buffer)); + + // High-precision timestamp. + // + // Note that we also commit to a timestamp in the Fast seeder, so we indirectly commit to a + // benchmark of all the entropy gathering sources in this function). + SeedTimestamp(hasher); } -void GetStrongRandBytes(unsigned char* out, int num) +static void SeedSleep(CSHA512& hasher) { - assert(num <= 32); - CSHA512 hasher; - unsigned char buf[64]; + // Everything that the 'fast' seeder includes + SeedFast(hasher); + + // High-precision timestamp + SeedTimestamp(hasher); + + // Sleep for 1ms + MilliSleep(1); + + // High-precision timestamp after sleeping (as we commit to both the time before and after, this measures the delay) + SeedTimestamp(hasher); - // First source: OpenSSL's RNG - RandAddSeedPerfmon(); - GetRandBytes(buf, 32); - hasher.Write(buf, 32); + // Windows performance monitor data (once every 10 minutes) + RandAddSeedPerfmon(hasher); +} + +static void SeedStartup(CSHA512& hasher) noexcept +{ +#ifdef WIN32 + RAND_screen(); +#endif - // Second source: OS RNG - GetOSRand(buf); - hasher.Write(buf, 32); + // Everything that the 'slow' seeder includes. + SeedSlow(hasher); + + // Windows performance monitor data. + RandAddSeedPerfmon(hasher); +} + +enum class RNGLevel { + FAST, //!< Automatically called by GetRandBytes + SLOW, //!< Automatically called by GetStrongRandBytes + SLEEP, //!< Called by RandAddSeedSleep() +}; + +static void ProcRand(unsigned char* out, int num, RNGLevel level) +{ + // Make sure the RNG is initialized first (as all Seed* function possibly need hwrand to be available). + RNGState& rng = GetRNGState(); - // Third source: HW RNG, if available. - if (GetHWRand(buf)) { - hasher.Write(buf, 32); + assert(num <= 32); + + CSHA512 hasher; + switch (level) { + case RNGLevel::FAST: + SeedFast(hasher); + break; + case RNGLevel::SLOW: + SeedSlow(hasher); + break; + case RNGLevel::SLEEP: + SeedSleep(hasher); + break; } // Combine with and update state - { - WAIT_LOCK(cs_rng_state, lock); - hasher.Write(rng_state, sizeof(rng_state)); - hasher.Write((const unsigned char*)&rng_counter, sizeof(rng_counter)); - ++rng_counter; - hasher.Finalize(buf); - memcpy(rng_state, buf + 32, 32); + if (!rng.MixExtract(out, num, std::move(hasher), false)) { + // On the first invocation, also seed with SeedStartup(). + CSHA512 startup_hasher; + SeedStartup(startup_hasher); + rng.MixExtract(out, num, std::move(startup_hasher), true); } - // Produce output - memcpy(out, buf, num); - memory_cleanse(buf, 64); + // For anything but the 'fast' level, feed the resulting RNG output (after an additional hashing step) back into OpenSSL. + if (level != RNGLevel::FAST) { + unsigned char buf[64]; + CSHA512().Write(out, num).Finalize(buf); + RAND_add(buf, sizeof(buf), num); + memory_cleanse(buf, 64); + } } -uint64_t GetRand(uint64_t nMax) -{ - if (nMax == 0) - return 0; +void GetRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNGLevel::FAST); } +void GetStrongRandBytes(unsigned char* buf, int num) noexcept { ProcRand(buf, num, RNGLevel::SLOW); } +void RandAddSeedSleep() { ProcRand(nullptr, 0, RNGLevel::SLEEP); } - // The range of the random source must be a multiple of the modulus - // to give every possible output value an equal possibility - uint64_t nRange = (std::numeric_limits::max() / nMax) * nMax; - uint64_t nRand = 0; - do { - GetRandBytes((unsigned char*)&nRand, sizeof(nRand)); - } while (nRand >= nRange); - return (nRand % nMax); +uint64_t GetRand(uint64_t nMax) noexcept +{ + return FastRandomContext().randrange(nMax); } -int GetRandInt(int nMax) +int GetRandInt(int nMax) noexcept { return GetRand(nMax); } -uint256 GetRandHash() +uint256 GetRandHash() noexcept { uint256 hash; GetRandBytes((unsigned char*)&hash, sizeof(hash)); @@ -386,7 +539,7 @@ void FastRandomContext::RandomSeed() requires_seed = false; } -uint256 FastRandomContext::rand256() +uint256 FastRandomContext::rand256() noexcept { if (bytebuf_size < 32) { FillByteBuffer(); @@ -406,7 +559,7 @@ std::vector FastRandomContext::randbytes(size_t len) return ret; } -FastRandomContext::FastRandomContext(const uint256& seed) : requires_seed(false), bytebuf_size(0), bitbuf_size(0) +FastRandomContext::FastRandomContext(const uint256& seed) noexcept : requires_seed(false), bytebuf_size(0), bitbuf_size(0) { rng.SetKey(seed.begin(), 32); } @@ -449,13 +602,15 @@ bool Random_SanityCheck() if (stop == start) return false; // We called GetPerformanceCounter. Use it as entropy. - RAND_add((const unsigned char*)&start, sizeof(start), 1); - RAND_add((const unsigned char*)&stop, sizeof(stop), 1); + CSHA512 to_add; + to_add.Write((const unsigned char*)&start, sizeof(start)); + to_add.Write((const unsigned char*)&stop, sizeof(stop)); + GetRNGState().MixExtract(nullptr, 0, std::move(to_add), false); return true; } -FastRandomContext::FastRandomContext(bool fDeterministic) : requires_seed(!fDeterministic), bytebuf_size(0), bitbuf_size(0) +FastRandomContext::FastRandomContext(bool fDeterministic) noexcept : requires_seed(!fDeterministic), bytebuf_size(0), bitbuf_size(0) { if (!fDeterministic) { return; @@ -466,5 +621,8 @@ FastRandomContext::FastRandomContext(bool fDeterministic) : requires_seed(!fDete void RandomInit() { - RDRandInit(); + // Invoke RNG code to trigger initialization (if not already performed) + ProcRand(nullptr, 0, RNGLevel::FAST); + + ReportHardwareRand(); } diff --git a/src/random.h b/src/random.h index 5a531d98c1..7dc686f160 100644 --- a/src/random.h +++ b/src/random.h @@ -14,33 +14,83 @@ #include #include -/* Seed OpenSSL PRNG with additional entropy data */ -void RandAddSeed(); +/** + * Overall design of the RNG and entropy sources. + * + * We maintain a single global 256-bit RNG state for all high-quality randomness. + * The following (classes of) functions interact with that state by mixing in new + * entropy, and optionally extracting random output from it: + * + * - The GetRand*() class of functions, as well as construction of FastRandomContext objects, + * perform 'fast' seeding, consisting of mixing in: + * - A stack pointer (indirectly committing to calling thread and call stack) + * - A high-precision timestamp (rdtsc when available, c++ high_resolution_clock otherwise) + * - Hardware RNG (rdrand) when available. + * These entropy sources are very fast, and only designed to protect against situations + * where a VM state restore/copy results in multiple systems with the same randomness. + * FastRandomContext on the other hand does not protect against this once created, but + * is even faster (and acceptable to use inside tight loops). + * + * - The GetStrongRand*() class of function perform 'slow' seeding, including everything + * that fast seeding includes, but additionally: + * - OS entropy (/dev/urandom, getrandom(), ...). The application will terminate if + * this entropy source fails. + * - Bytes from OpenSSL's RNG (which itself may be seeded from various sources) + * - Another high-precision timestamp (indirectly committing to a benchmark of all the + * previous sources). + * These entropy sources are slower, but designed to make sure the RNG state contains + * fresh data that is unpredictable to attackers. + * + * - RandAddSeedSleep() seeds everything that fast seeding includes, but additionally: + * - A high-precision timestamp before and after sleeping 1ms. + * - (On Windows) Once every 10 minutes, performance monitoring data from the OS. + * These just exploit the fact the system is idle to improve the quality of the RNG + * slightly. + * + * On first use of the RNG (regardless of what function is called first), all entropy + * sources used in the 'slow' seeder are included, but also: + * - (On Windows) Performance monitoring data from the OS. + * - (On Windows) Through OpenSSL, the screen contents. + * + * When mixing in new entropy, H = SHA512(entropy || old_rng_state) is computed, and + * (up to) the first 32 bytes of H are produced as output, while the last 32 bytes + * become the new RNG state. +*/ /** - * Functions to gather random data via the OpenSSL PRNG + * Generate random data via the internal PRNG. + * + * These functions are designed to be fast (sub microsecond), but do not necessarily + * meaningfully add entropy to the PRNG state. + * + * Thread-safe. */ -void GetRandBytes(unsigned char* buf, int num); -uint64_t GetRand(uint64_t nMax); -int GetRandInt(int nMax); -uint256 GetRandHash(); +void GetRandBytes(unsigned char* buf, int num) noexcept; +uint64_t GetRand(uint64_t nMax) noexcept; +int GetRandInt(int nMax) noexcept; +uint256 GetRandHash() noexcept; /** - * Add a little bit of randomness to the output of GetStrongRangBytes. - * This sleeps for a millisecond, so should only be called when there is - * no other work to be done. + * Gather entropy from various sources, feed it into the internal PRNG, and + * generate random data using it. + * + * This function will cause failure whenever the OS RNG fails. + * + * Thread-safe. */ -void RandAddSeedSleep(); +void GetStrongRandBytes(unsigned char* buf, int num) noexcept; /** - * Function to gather random data from multiple sources, failing whenever any - * of those sources fail to provide a result. + * Sleep for 1ms, gather entropy from various sources, and feed them to the PRNG state. + * + * Thread-safe. */ -void GetStrongRandBytes(unsigned char* buf, int num); +void RandAddSeedSleep(); /** * Fast randomness source. This is seeded once with secure random data, but - * is completely deterministic and insecure after that. + * is completely deterministic and does not gather more entropy after that. + * * This class is not thread-safe. */ class FastRandomContext { @@ -72,13 +122,13 @@ class FastRandomContext { } public: - explicit FastRandomContext(bool fDeterministic = false); + explicit FastRandomContext(bool fDeterministic = false) noexcept; /** Initialize with explicit seed (only for testing) */ - explicit FastRandomContext(const uint256& seed); + explicit FastRandomContext(const uint256& seed) noexcept; /** Generate a random 64-bit integer. */ - uint64_t rand64() + uint64_t rand64() noexcept { if (bytebuf_size < 8) FillByteBuffer(); uint64_t ret = ReadLE64(bytebuf + 64 - bytebuf_size); @@ -87,7 +137,7 @@ class FastRandomContext { } /** Generate a random (bits)-bit integer. */ - uint64_t randbits(int bits) { + uint64_t randbits(int bits) noexcept { if (bits == 0) { return 0; } else if (bits > 32) { @@ -102,7 +152,7 @@ class FastRandomContext { } /** Generate a random integer in the range [0..range). */ - uint64_t randrange(uint64_t range) + uint64_t randrange(uint64_t range) noexcept { --range; int bits = CountBits(range); @@ -116,27 +166,21 @@ class FastRandomContext { std::vector randbytes(size_t len); /** Generate a random 32-bit integer. */ - uint32_t rand32() { return randbits(32); } - uint32_t rand32(uint32_t nMax) - { - return rand32() % nMax; - } + uint32_t rand32() noexcept { return randbits(32); } + uint32_t rand32(uint32_t nMax) { return rand32() % nMax; } /** generate a random uint256. */ - uint256 rand256(); + uint256 rand256() noexcept; /** Generate a random boolean. */ - bool randbool() { return randbits(1); } + bool randbool() noexcept { return randbits(1); } // Compatibility with the C++11 UniformRandomBitGenerator concept typedef uint64_t result_type; static constexpr uint64_t min() { return 0; } static constexpr uint64_t max() { return std::numeric_limits::max(); } - inline uint64_t operator()() { return rand64(); } - uint32_t operator()(uint32_t nMax) - { - return rand32(nMax); - } + inline uint32_t operator()(uint32_t nMax) noexcept { return rand32(nMax); } + inline uint64_t operator()() noexcept { return rand64(); } }; /* Number of random bytes returned by GetOSRand. @@ -156,7 +200,12 @@ void GetOSRand(unsigned char *ent32); */ bool Random_SanityCheck(); -/** Initialize the RNG. */ +/** + * Initialize global RNG state and log any CPU features that are used. + * + * Calling this function is optional. RNG state will be initialized when first + * needed if it is not called. + */ void RandomInit(); #endif // DYNAMIC_RANDOM_H diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index a1a7129c5a..53b9486e7b 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -885,12 +885,14 @@ static bool GetUTXOStats(CCoinsView* view, CCoinsStats& stats) COutPoint key; Coin coin; if (pcursor->GetKey(key) && pcursor->GetValue(coin)) { - if (!outputs.empty() && key.hash != prevkey) { - ApplyStats(stats, ss, prevkey, outputs); - outputs.clear(); + if (!coin.out.IsFluid()) { + if (!outputs.empty() && key.hash != prevkey) { + ApplyStats(stats, ss, prevkey, outputs); + outputs.clear(); + } + prevkey = key.hash; + outputs[key.n] = std::move(coin); } - prevkey = key.hash; - outputs[key.n] = std::move(coin); } else { return error("%s: unable to read value", __func__); } diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index acb4f77653..5861ce9c34 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -152,6 +152,10 @@ static const CRPCConvertParam vRPCConvertParams[] = {"getaddressmempool", 0, "addresses"}, {"reservebalance", 0, "reserve"}, {"reservebalance", 1, "amount"}, + {"getswaps", 0, "start_height"}, + {"getswaps", 1, "end_height"}, + {"getswaperrors", 0, "start_height"}, + {"getswaperrors", 1, "end_height"}, // Echo with conversion (For testing only) {"echojson", 0, "arg0"}, {"echojson", 1, "arg1"}, diff --git a/src/rpc/fluid.cpp b/src/rpc/fluid.cpp index 7fe3d5f020..73e341721e 100644 --- a/src/rpc/fluid.cpp +++ b/src/rpc/fluid.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2017-2021 Duality Blockchain Solutions Developers - +#include "base58.h" #include "bdap/domainentrydb.h" #include "bdap/utils.h" #include "chain.h" @@ -13,6 +13,7 @@ #include "fluid/fluidmining.h" #include "fluid/fluidmint.h" #include "fluid/fluidsovereign.h" +#include "hash.h" #include "init.h" #include "keepass.h" #include "net.h" @@ -20,6 +21,7 @@ #include "rpc/server.h" #include "spork.h" #include "timedata.h" +#include "uint256.h" #include "util.h" #include "utilmoneystr.h" #include "utilstrencodings.h" diff --git a/src/rpc/register.h b/src/rpc/register.h index 18d54403e9..cb3415ba91 100644 --- a/src/rpc/register.h +++ b/src/rpc/register.h @@ -38,6 +38,8 @@ void RegisterRawBDAPAccountRPCCommands(CRPCTable &tableRPC); void RegisterAuditRPCCommands(CRPCTable &tableRPC); /** Register Raw BDAP Certificate RPC commands */ void RegisterCertificateRPCCommands(CRPCTable &tableRPC); +/** Register Swap RPC commands */ +void RegisterSwapRPCCommands(CRPCTable &tableRPC); static inline void RegisterAllCoreRPCCommands(CRPCTable& t) { @@ -55,6 +57,7 @@ static inline void RegisterAllCoreRPCCommands(CRPCTable& t) RegisterRawBDAPAccountRPCCommands(t); RegisterAuditRPCCommands(t); RegisterCertificateRPCCommands(t); + RegisterSwapRPCCommands(t); } #endif // DYNAMIC_RPCREGISTER_H \ No newline at end of file diff --git a/src/rpc/server.h b/src/rpc/server.h index cc0ee7482e..e761b1d759 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -208,6 +208,8 @@ extern std::string HelpExampleRpc(const std::string& methodname, const std::stri extern void EnsureWalletIsUnlocked(); extern void relockWalletAfterDuration(CWallet *wallet, int64_t nSeconds); +extern UniValue SwapDynamic(const std::string& address, const bool fSend, std::string& errorMessage); + bool StartRPC(); void InterruptRPC(); void StopRPC(); diff --git a/src/rpc/swap.cpp b/src/rpc/swap.cpp new file mode 100644 index 0000000000..d14b45d639 --- /dev/null +++ b/src/rpc/swap.cpp @@ -0,0 +1,310 @@ +// Copyright (c) 2021-present Duality Blockchain Solutions Developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "base58.h" +#include "bdap/utils.h" +#include "core_io.h" +#include "hash.h" +#include "init.h" +#include "keepass.h" +#include "net.h" +#include "netbase.h" +#include "rpc/server.h" +#include "swap/ss58.h" +#include "swap/swapdata.h" +#include "swap/swapdb.h" +#include "timedata.h" +#include "uint256.h" +#include "util.h" +#include "utilmoneystr.h" +#include "utilstrencodings.h" +#include "validation.h" +#include "wallet/wallet.h" +#include "wallet/walletdb.h" + +#include + +#include + +#ifdef ENABLE_WALLET + +extern bool EnsureWalletIsAvailable(bool avoidException); +extern bool SendSwapTransaction(const CScript& burnScript, CWalletTx& wtxNew, const CScript& sendAddress, std::string& strError); +extern CAmount GetSwapOutputsBalance(std::vector& vchTxOuts); + +struct SwapCompareHeight { + bool operator()(const CSwapData& a, const CSwapData& b) { + return (a.nHeight < b.nHeight); + } +}; + +UniValue SwapDynamic(const std::string& address, const bool fSend, std::string& errorMessage) +{ + if (!EnsureWalletIsAvailable(true)) { + errorMessage = "Wallet is not available"; + return NullUniValue; + } + if (pwalletMain->IsLocked()) { + errorMessage = "Wallet is locked"; + return NullUniValue; + } + + CSS58 ss58Address(address); + if (!ss58Address.fValid) { + errorMessage = "Invalid swap address. " + ss58Address.strError; + return NullUniValue; + } + + UniValue oResult(UniValue::VOBJ); + oResult.push_back(Pair("address_length", ss58Address.nLength)); + oResult.push_back(Pair("hex_address", ss58Address.AddressHex())); + oResult.push_back(Pair("address_type", (int64_t)ss58Address.AddressType())); + oResult.push_back(Pair("address_pubkey", ss58Address.PublicKeyHex())); + oResult.push_back(Pair("address_checksum", ss58Address.AddressChecksumHex())); + if (fSend) { + CWalletTx wtx; + CScript scriptSendFrom; + CScript swapScript = CScript() << OP_RETURN << ss58Address.AddressBytes(); + std::string strError = ""; + if (SendSwapTransaction(swapScript, wtx, scriptSendFrom, strError)) { + oResult.push_back(Pair("amount", FormatMoney(wtx.GetDebit(ISMINE_SPENDABLE)))); + oResult.push_back(Pair("txid", wtx.GetHash().ToString())); + } else { + errorMessage = strError; + return NullUniValue; + } + } + return oResult; +} + +UniValue swapdynamic(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() > 1 || request.params.size() == 0) + throw std::runtime_error( + "swapdynamic \"address\"\n" + "\nSend coins to be swapped for Substrate chain\n" + "\nArguments:\n" + "1. \"address\" (string, required) The Substrate address to swap funds.\n" + "\nExamples:\n" + + HelpExampleCli("swapdynamic", "\"1a1LcBX6hGPKg5aQ6DXZpAHCCzWjckhea4sz3P1PvL3oc4F\"") + + HelpExampleRpc("swapdynamic", "\"1a1LcBX6hGPKg5aQ6DXZpAHCCzWjckhea4sz3P1PvL3oc4F\"")); + + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + EnsureWalletIsUnlocked(); + + std::string strSubstrateAddress = request.params[0].get_str(); + + std::string errorMessage = ""; + UniValue oResult = SwapDynamic(strSubstrateAddress, true, errorMessage); + if (errorMessage != "") + throw JSONRPCError(RPC_TYPE_ERROR, errorMessage); + + return oResult; +} + +UniValue swapbalance(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 0) + throw std::runtime_error( + "swapbalance\n" + "\nGet total coins available for swap\n" + "\nExamples:\n" + + HelpExampleCli("swapbalance", "") + + HelpExampleRpc("swapbalance", "")); + + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + UniValue oResult(UniValue::VOBJ); + std::vector vchUtxos; + CAmount balance = GetSwapOutputsBalance(vchUtxos); + int count = 0; + for (const CSwapOutput& utxo : vchUtxos) { + UniValue oTxOut(UniValue::VOBJ); + oTxOut.push_back(Pair("amount", FormatMoney(utxo.TxOut.nValue))); + oTxOut.push_back(Pair("txid", utxo.Hash.GetHex())); + oTxOut.push_back(Pair("n", utxo.n)); + oTxOut.push_back(Pair("nValue", FormatMoney(utxo.nValue))); + oTxOut.push_back(Pair("confirmations", utxo.nDepth)); + std::string utxoName = utxo.Hash.GetHex() + ":" + std::to_string(utxo.n); + oResult.push_back(Pair(utxoName, oTxOut)); + count++; + } + oResult.push_back(Pair("swap_balance", FormatMoney(balance))); + oResult.push_back(Pair("count", count)); + return oResult; +} +#endif // ENABLE_WALLET + +UniValue GetAddress(const std::string& address, std::string& errorMessage) +{ + CSS58 ss58Address(address); + UniValue oResult(UniValue::VOBJ); + oResult.push_back(Pair("address_length", ss58Address.nLength)); + oResult.push_back(Pair("hex_address", ss58Address.AddressHex())); + oResult.push_back(Pair("address_type", (int64_t)ss58Address.AddressType())); + oResult.push_back(Pair("address_pubkey", ss58Address.PublicKeyHex())); + oResult.push_back(Pair("address_checksum", ss58Address.AddressChecksumHex())); + oResult.push_back(Pair("calculated_checksum", ss58Address.CalulatedChecksumHex())); + oResult.push_back(Pair("calculated_hash", ss58Address.CalculatedHashHex())); + oResult.push_back(Pair("valid_checksum", ss58Address.ValidChecksum() ? "true" : "false")); + oResult.push_back(Pair("valid", ss58Address.Valid() ? "true" : "false")); + if (ss58Address.strError != "") { + oResult.push_back(Pair("errorMessage", ss58Address.strError)); + } + return oResult; +} + +UniValue ss58valid(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() > 1 || request.params.size() == 0) + throw std::runtime_error( + "ss58valid \"address\"\n" + "\nArguments:\n" + "1. \"address\" (string, required) The Substrate address to swap funds.\n" + "\nExamples:\n" + + HelpExampleCli("ss58valid", "\"1a1LcBX6hGPKg5aQ6DXZpAHCCzWjckhea4sz3P1PvL3oc4F\"") + + HelpExampleRpc("ss58valid", "\"1a1LcBX6hGPKg5aQ6DXZpAHCCzWjckhea4sz3P1PvL3oc4F\"")); + + std::string strSubstrateAddress = request.params[0].get_str(); + + std::string errorMessage = ""; + UniValue oResult = GetAddress(strSubstrateAddress, errorMessage); + if (errorMessage != "") + throw JSONRPCError(RPC_TYPE_ERROR, errorMessage); + + return oResult; +} + +UniValue getswaps(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() > 2) + throw std::runtime_error( + "getswaps start_height end_height\n" + "\nSend coins to be swapped for Substrate chain\n" + "\nArguments:\n" + "1. \"start_height\" (int, optional) Swaps starting at this block height.\n" + "1. \"end_height\" (int, optional) Swaps ending at this block height.\n" + "\nExamples:\n" + + HelpExampleCli("getswap", "0 100000") + + HelpExampleRpc("getswap", "0 100000")); + + int nStartHeight = 0; + int nEndHeight = (std::numeric_limits::max()); + if (!request.params[0].isNull()) { + nStartHeight = request.params[0].get_int(); + if (!request.params[1].isNull()) { + nEndHeight = request.params[1].get_int(); + } + } + + std::vector vSwaps; + if (GetAllSwaps(vSwaps)) { + std::sort(vSwaps.begin(), vSwaps.end(), SwapCompareHeight()); //sort entries by nHeight + UniValue oResult(UniValue::VOBJ); + CAmount totalAmount = 0; + int count = 0; + for (const CSwapData& swap : vSwaps) { + if (swap.nHeight >= nStartHeight && swap.nHeight <= nEndHeight) { + UniValue oSwap(UniValue::VOBJ); + const CAmount fee = swap.GetFee(); + oSwap.push_back(Pair("address", swap.Address())); + oSwap.push_back(Pair("out_amount", FormatMoney(swap.Amount))); + oSwap.push_back(Pair("fee", FormatMoney(fee))); + oSwap.push_back(Pair("swap_amount", FormatMoney(swap.Amount + fee))); + oSwap.push_back(Pair("txid", swap.TxId.ToString())); + oSwap.push_back(Pair("nout", swap.nOut)); + oSwap.push_back(Pair("block_height", swap.nHeight)); + if (fee <= 0) { + oSwap.push_back(Pair("warning", "Zero fee.")); + } + oResult.push_back(Pair(swap.TxId.ToString(), oSwap)); + totalAmount += (swap.Amount + fee); + count += 1; + } + } + oResult.push_back(Pair("count", count)); + oResult.push_back(Pair("total_amount", FormatMoney(totalAmount))); + return oResult; + } else { + throw JSONRPCError(RPC_INTERNAL_ERROR, "Get all swaps from LevelDB failed."); + } +} + +UniValue getswaperrors(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() > 2) + throw std::runtime_error( + "getswaperrors start_height end_height\n" + "\nSend coins to be swapped for Substrate chain\n" + "\nArguments:\n" + "1. \"start_height\" (int, optional) Swaps starting at this block height.\n" + "1. \"end_height\" (int, optional) Swaps ending at this block height.\n" + "\nExamples:\n" + + HelpExampleCli("getswaperrors", "0 100000") + + HelpExampleRpc("getswaperrors", "0 100000")); + + int nStartHeight = 0; + int nEndHeight = (std::numeric_limits::max()); + if (!request.params[0].isNull()) { + nStartHeight = request.params[0].get_int(); + if (!request.params[1].isNull()) { + nEndHeight = request.params[1].get_int(); + } + } + + std::vector vSwaps; + if (GetAllSwaps(vSwaps)) { + std::sort(vSwaps.begin(), vSwaps.end(), SwapCompareHeight()); //sort entries by nHeight + UniValue oResult(UniValue::VOBJ); + CAmount totalAmount = 0; + int count = 0; + for (const CSwapData& swap : vSwaps) { + if (swap.nHeight >= nStartHeight && swap.nHeight <= nEndHeight) { + const CAmount fee = swap.GetFee(); + if (fee <= 0) { + UniValue oSwap(UniValue::VOBJ); + oSwap.push_back(Pair("address", swap.Address())); + oSwap.push_back(Pair("out_amount", FormatMoney(swap.Amount))); + oSwap.push_back(Pair("fee", FormatMoney(fee))); + oSwap.push_back(Pair("swap_amount", FormatMoney(swap.Amount + fee))); + oSwap.push_back(Pair("txid", swap.TxId.ToString())); + oSwap.push_back(Pair("nout", swap.nOut)); + oSwap.push_back(Pair("block_height", swap.nHeight)); + oSwap.push_back(Pair("warning", "Zero fee.")); + oResult.push_back(Pair(swap.TxId.ToString(), oSwap)); + totalAmount += (swap.Amount); + count += 1; + } + } + } + oResult.push_back(Pair("count", count)); + oResult.push_back(Pair("total_amount", FormatMoney(totalAmount))); + return oResult; + } else { + throw JSONRPCError(RPC_INTERNAL_ERROR, "Get all swaps from LevelDB failed."); + } +} + +static const CRPCCommand commands[] = + { + // category name actor (function) okSafe argNames + // --------------------- ------------------------ ----------------------- ------ -------------------- +#ifdef ENABLE_WALLET + /* Dynamic Swap To Substrate Chain */ + {"swap", "swapdynamic", &swapdynamic, true, {"address"}}, + {"swap", "swapbalance", &swapbalance, true, {}}, +#endif //ENABLE_WALLET + {"swap", "getswaps", &getswaps, true, {"start_height", "end_height"}}, + {"swap", "getswaperrors", &getswaperrors, true, {"start_height", "end_height"}}, + {"swap", "ss58valid", &ss58valid, true, {"address"}}, +}; + +void RegisterSwapRPCCommands(CRPCTable &t) +{ + for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) + t.appendCommand(commands[vcidx].name, &commands[vcidx]); +} diff --git a/src/rpc/wallet.cpp b/src/rpc/wallet.cpp index 8c6f7347e9..1630838d26 100644 --- a/src/rpc/wallet.cpp +++ b/src/rpc/wallet.cpp @@ -722,6 +722,52 @@ void SendBurnTransaction(const CScript& burnScript, CWalletTx& wtxNew, const CAm delete ccCoins; } +CAmount GetSwapOutputsBalance(std::vector& vchUtxos) +{ + return pwalletMain->GetSwapOutputs(vchUtxos); +} + +bool SendSwapTransaction(const CScript& swapScript, CWalletTx& wtxNew, const CScript& scriptSendFrom, std::string& strError) +{ + const CAmount curUnlockedMatureBalance = pwalletMain->SwapBalance(); + const CAmount nValue = curUnlockedMatureBalance; + // Check amount + if (nValue <= 0) { + strError = strprintf("Invalid amount"); + return false; + } + + LogPrint("swap", "%s - Script to the swap %s DYN transaction processing: %s\n", __func__, FormatMoney(nValue), ScriptToAsmStr(swapScript)); + + // Create and send the transaction + CReserveKey reservekey(pwalletMain); + CCoinControl* ccCoins = new CCoinControl; + if (!scriptSendFrom.empty()) { + if (!GetCoinControl(scriptSendFrom, ccCoins)) { + strError = strprintf("Error: GetCoinControl failed"); + delete ccCoins; + return false; + } + } + + std::vector vWtxNew; + if (pwalletMain->CreateSwapTransaction(swapScript, vWtxNew, reservekey, ccCoins, strError)) { + for(CWalletTx& wtx : vWtxNew) { + CValidationState state; + if (!pwalletMain->CommitTransaction(wtx, reservekey, g_connman.get(), state, NetMsgType::TX)) { + strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason()); + delete ccCoins; + return false; + } + } + } else { + delete ccCoins; + return false; + } + delete ccCoins; + return true; +} + UniValue sendtoaddress(const JSONRPCRequest& request) { if (!EnsureWalletIsAvailable(request.fHelp)) diff --git a/src/script/script.cpp b/src/script/script.cpp index 408cde2415..a7e6c8b4c0 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -377,6 +377,19 @@ bool RemoveBDAPScript(const CScript& scriptIn, CScript& scriptOut) scriptOut = CScript(pc, scriptIn.end()); return true; } + +bool GetOpReturnData(const CScript& script, std::vector& vchRet) +{ + opcodetype opcode; + CScript::const_iterator pc = script.begin(); + if (!script.GetOp(pc, opcode)) + return false; + + if (opcode == OP_RETURN) + script.GetOp2(pc, opcode, &vchRet); + + return true; +} // TODO (bdap): move the above functions to seperate code file unsigned int CScript::GetSigOpCount(bool fAccurate) const diff --git a/src/script/script.h b/src/script/script.h index 27ab08f547..adc97c0d00 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -751,6 +751,12 @@ class CScript : public CScriptBase return false; } + bool IsFluid() const + { + return (IsProtocolInstruction(MINT_TX) || IsProtocolInstruction(DYNODE_MODFIY_TX) || IsProtocolInstruction(MINING_MODIFY_TX) || + IsProtocolInstruction(BDAP_REVOKE_TX)); + } + void clear() { // The default std::vector::clear() does not release memory. @@ -771,5 +777,6 @@ class CReserveScript bool DecodeBDAPScript(const CScript& script, int& op, int& op2, std::vector >& vvch, CScript::const_iterator& pc); bool DecodeBDAPScript(const CScript& script, int& op1, int& op2, std::vector >& vvch); bool RemoveBDAPScript(const CScript& scriptIn, CScript& scriptOut); +bool GetOpReturnData(const CScript& script, std::vector& vchRet); #endif // DYNAMIC_SCRIPT_SCRIPT_H diff --git a/src/swap/ss58.cpp b/src/swap/ss58.cpp new file mode 100644 index 0000000000..b4e2b41a7e --- /dev/null +++ b/src/swap/ss58.cpp @@ -0,0 +1,130 @@ +// Copyright (c) 2021-present Duality Blockchain Solutions Developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "swap/ss58.h" + +#include "base58.h" +#include "bdap/utils.h" +#include "hash.h" +#include "util.h" + +CSS58::CSS58(std::string address) +{ + SetNull(); + strAddress = address; + vchPrefix = vchFromString("SS58PRE"); // SS58PRE + fValid = DecodeBase58(strAddress, vchAddress); + nLength = vchAddress.size(); + int prefixLen = 1; + if (fValid) { + if (nLength >= 35) { + if (nLength >= 36) + prefixLen = 2; + vchAddressType = std::vector(&vchAddress[0], &vchAddress[prefixLen]); + setAddressType(); + vchPublicKey = std::vector(&vchAddress[prefixLen], &vchAddress[prefixLen + 32]); + vchAddressCheckSum = std::vector(&vchAddress[prefixLen + 32], &vchAddress[nLength]); + } else { + strError = strprintf("BadLength: Invalid SS58 address size %d", vchAddress.size()); + fValid = false; + return; + } + } else { + strError = strprintf("BadBase58: Failed to decode base58 address"); + return; + } + fValid = calulatedChecksumHash(); + if (std::count(vAcceptedAddressTypes.begin(), vAcceptedAddressTypes.end(), type) == 0) + { + if (strError == "") { + strError = strprintf("AddressType: Invalid SS58 address type (%d).", type); + } else { + strError += ", " + strprintf("AddressType: Invalid SS58 address type (%d)", type); + } + fValid = false; + } +} + +std::string CSS58::AddressHex() const +{ + if (vchAddress.size() > 0) + return "0x" + CharVectorToHexString(vchAddress); + + return ""; +} + +uint32_t CSS58::AddressType() const +{ + return type; +} + +std::string CSS58::PublicKeyHex() const +{ + if (vchPublicKey.size() > 0) + return "0x" + CharVectorToHexString(vchPublicKey); + + return ""; +} + +std::string CSS58::AddressChecksumHex() const +{ + if (vchAddressCheckSum.size() > 0) + return "0x" + CharVectorToHexString(vchAddressCheckSum); + + return ""; +} + +std::string CSS58::CalulatedChecksumHex() const +{ + if (vchAddressCheckSum.size() > 0) + return "0x" + CharVectorToHexString(vchCalulatedCheckSum); + + return ""; +} + +void CSS58::setAddressType() +{ + if (vchAddressType.size() > 0 && vchAddressType[0] >= 64) { + // Full Format + // https://github.com/paritytech/substrate/blob/master/primitives/core/src/crypto.rs + // weird bit manipulation owing to the combination of LE encoding and missing two + // bits from the left. + // d[0] d[1] are: 01aaaaaa bbcccccc + // they make the LE-encoded 16-bit value: aaaaaabb 00cccccc + // so the lower byte is formed of aaaaaabb and the higher byte is 00cccccc + uint8_t lower = vchAddressType[0] << 2 | vchAddressType[1] >> 6; + uint8_t upper = vchAddressType[1] & 0b00111111; //63 0x3F 0b00111111 '?' + type = (uint32_t)(256 * upper + lower); + } else if (vchAddressType.size() > 0) { + // Simple Format + type = (uint32_t)vchAddressType[0]; + } +} + +bool CSS58::calulatedChecksumHash() +{ + std::vector vchImageData = vchPrefix; + vchImageData.insert(vchImageData.end(), vchAddress.begin(), vchAddress.end()); + vchImageData.resize(nLength + vchPrefix.size() - vchAddressCheckSum.size()); + calulatedhash = HashBlake2b_512(vchImageData.begin(), vchImageData.end()); + std::vector vchHash = ParseHex(calulatedhash.GetHex()); + size_t hashSize = vchHash.size(); + if (hashSize >= 32 && hashSize > vchAddressCheckSum.size() + 1) { + vchCalulatedCheckSum.clear(); + //reverse vector by starting from the last item + for (size_t i = 1; i < vchAddressCheckSum.size() + 1; i++) { + vchCalulatedCheckSum.push_back(vchHash[hashSize - i]); + } + if (vchCalulatedCheckSum.size() > 0 && vchCalulatedCheckSum == vchAddressCheckSum) { + return true; + } else { + if (strError == "") { + strError = "Checksum does not match."; + } else { + strError += ", Checksum does not match."; + } + } + } + return false; +} diff --git a/src/swap/ss58.h b/src/swap/ss58.h new file mode 100644 index 0000000000..604d3af6f0 --- /dev/null +++ b/src/swap/ss58.h @@ -0,0 +1,75 @@ +// Copyright (c) 2021-present Duality Blockchain Solutions Developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef DYNAMIC_SWAP_SS58_H +#define DYNAMIC_SWAP_SS58_H + +#include "uint256.h" + +#include +#include + +//See https://docs.substrate.io/v3/advanced/ss58 + +// Accept Substrate generic (42) and Clover address types for now. +const std::vector vAcceptedAddressTypes = {42, 128}; + +class CSS58 +{ +private: + std::string strAddress; + std::vector vchPrefix; + std::vector vchAddress; + std::vector vchAddressType; + std::vector vchPublicKey; + std::vector vchAddressCheckSum; + uint512 calulatedhash; + std::vector vchCalulatedCheckSum; + uint32_t type; + +public: + static const int CURRENT_VERSION = 1; + int nVersion; + int nLength; + bool fValid; + std::string strError = ""; + + inline void SetNull() + { + nVersion = CSS58::CURRENT_VERSION; + nLength = -1; + fValid = false; + strError = ""; + strAddress = ""; + vchAddress.clear(); + vchAddressType.clear(); + vchPublicKey.clear(); + vchAddressCheckSum.clear(); + calulatedhash = uint512(0); + vchCalulatedCheckSum.clear(); + type = 0; + } + + CSS58(std::string address); + + uint32_t AddressType() const; + std::string Address() const { return strAddress; } + std::vector AddressBytes() const { return vchAddress; } + std::string AddressHex() const; + std::string AddressTypeHex() const; + std::string PublicKeyHex() const; + std::string AddressChecksumHex() const; + std::string CalulatedChecksumHex() const; + + uint512 CalculatedHash() const { return calulatedhash; } + std::string CalculatedHashHex() const { return calulatedhash.GetHex(); } + bool ValidChecksum() const { return (vchCalulatedCheckSum == vchAddressCheckSum); } + bool Valid() const { return (fValid && ValidChecksum()); } + +private: + bool calulatedChecksumHash(); + void setAddressType(); +}; + +#endif // DYNAMIC_SWAP_SS58_H diff --git a/src/swap/swapdata.cpp b/src/swap/swapdata.cpp new file mode 100644 index 0000000000..a7ab6883bd --- /dev/null +++ b/src/swap/swapdata.cpp @@ -0,0 +1,170 @@ +// Copyright (c) 2021-present Duality Blockchain Solutions Developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "swap/swapdata.h" + +#include "base58.h" +#include "bdap/utils.h" +#include "chainparams.h" +#include "coins.h" +#include "core_io.h" +#include "policy/policy.h" +#include "serialize.h" +#include "streams.h" +#include "uint256.h" +#include "utilmoneystr.h" +#include "validation.h" + +#include + +std::string CSwapData::Address() const +{ + return EncodeBase58(vSwapData); +} + +void CSwapData::Serialize(std::vector& vchData) +{ + CDataStream dsSwapData(SER_NETWORK, PROTOCOL_VERSION); + dsSwapData << *this; + vchData = std::vector(dsSwapData.begin(), dsSwapData.end()); +} + +bool CSwapData::UnserializeFromData(const std::vector& vchData, const std::vector& vchHash) +{ + try { + CDataStream dsSwapData(vchData, SER_NETWORK, PROTOCOL_VERSION); + dsSwapData >> *this; + + std::vector vchSwapData; + Serialize(vchSwapData); + const uint256& calculatedHash = Hash(vchSwapData.begin(), vchSwapData.end()); + const std::vector& vchRandSwapData = vchFromValue(calculatedHash.GetHex()); + if(vchRandSwapData != vchHash) { + SetNull(); + return false; + } + } catch (std::exception& e) { + SetNull(); + return false; + } + return true; +} + +bool CSwapData::UnserializeFromData(const std::vector& vchData) +{ + try { + CDataStream dsSwapData(vchData, SER_NETWORK, PROTOCOL_VERSION); + dsSwapData >> *this; + + std::vector vchSwapData; + Serialize(vchSwapData); + } catch (std::exception& e) { + SetNull(); + return false; + } + return true; +} + +CSwapData::CSwapData(const CTransactionRef& tx, const int& height) +{ + SetNull(); + + if (tx->nVersion == SWAP_TX_VERSION) + { + CAmount nValueIn = 0; + CCoinsViewCache view(pcoinsTip); + for (const CTxIn& txin : tx->vin) { + const Coin& coin = view.AccessCoin(txin.prevout); + nValueIn += coin.out.nValue; + } + // This assumes there is only one swap output per transaction + int nCurrentIndex = 0; + CAmount nValueOut = 0; + for (const auto& txout : tx->vout) { + if (txout.IsData()) { + std::vector vchData; + if (txout.GetData(vchData)) { + if (vchData.size() >= 32) { + vSwapData = vchData; + Amount = txout.nValue; + TxId = tx->GetHash(); + nOut = nCurrentIndex; + nHeight = height; + } + } + } + nValueOut += txout.nValue; + nCurrentIndex++; + } + if (nValueIn > nValueOut) { + Fee = (nValueIn - nValueOut); + } else { + Fee = 0; + LogPrintf("%s Error getting Fee %s, nValueIn %s, nValueOut %s\n", __func__, FormatMoney((nValueIn - nValueOut)), FormatMoney(nValueIn), FormatMoney(nValueOut)); + } + } +} + +CAmount CSwapData::GetFee() const +{ + if (Fee <= 0) { + CTransactionRef tx; + uint256 hashBlock; + if (!GetTransaction(TxId, tx, Params().GetConsensus(), hashBlock, true)) { + LogPrint("swap", "%s Unable to get %s transaction\n", __func__, TxId.GetHex()); + return 0; + } + CAmount nValueIn = 0; + CCoinsViewCache view(pcoinsTip); + size_t index = 0; + for (const CTxIn& txin : tx->vin) { + const Coin& coin = view.AccessCoin(txin.prevout); + if (coin.out.nValue <= 0) { + LogPrint("swap", "%s Unable to get %s transaction value scriptPubKey %s\n", __func__, TxId.GetHex(), ScriptToAsmStr(coin.out.scriptPubKey)); + } + nValueIn += coin.out.nValue; + index ++; + } + CAmount nValueOut = 0; + for (const auto& txout : tx->vout) { + nValueOut += txout.nValue; + } + + if (nValueIn > nValueOut) { + return (nValueIn - nValueOut); + } else { + LogPrint("swap", "%s - Txid %s nValueIn (%s) is less than nValueOut (%s)\n", __func__, TxId.GetHex(), FormatMoney(nValueIn), FormatMoney(nValueOut)); + return 0; + } + } else { + return Fee; + } +} + +std::string CSwapData::ToString() const +{ + return strprintf( + "CSwapData(\n" + " nVersion = %d\n" + " vSwapData = %s\n" + " Amount = %s\n" + " Fee = %s\n" + " TxId = %s\n" + " nOut = %d\n" + " nHeight = %d\n" + ")\n", + nVersion, + Address(), + FormatMoney(Amount), + FormatMoney(GetFee()), + TxId.ToString(), + nOut, + nHeight + ); +} + +std::vector CSwapData::vchTxId() const +{ + return vchFromString(TxId.ToString()); +} \ No newline at end of file diff --git a/src/swap/swapdata.h b/src/swap/swapdata.h new file mode 100644 index 0000000000..f2fac8309f --- /dev/null +++ b/src/swap/swapdata.h @@ -0,0 +1,100 @@ +// Copyright (c) 2021-present Duality Blockchain Solutions Developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef DYNAMIC_SWAP_SWAPDATA_H +#define DYNAMIC_SWAP_SWAPDATA_H + +#include "amount.h" +#include "primitives/transaction.h" +#include "serialize.h" +#include "uint256.h" + +#include +#include + +class CSwapData { +public: + static const int CURRENT_VERSION = 1; + int nVersion; + std::vector vSwapData; // Swap address + CAmount Amount; // Swap amount + CAmount Fee; // Swap fee amount + uint256 TxId; + int nOut; + int nHeight; + + CSwapData() { + SetNull(); + } + + CSwapData(const std::vector& vchData) { + SetNull(); + UnserializeFromData(vchData); + } + + CSwapData(const CTransactionRef& tx, const int& height); + + inline void SetNull() + { + nVersion = CSwapData::CURRENT_VERSION; + vSwapData.clear(); + Amount = -1; + Fee = 0; + TxId = uint256(); + nOut = -1; + nHeight = -1; + } + + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { + READWRITE(this->nVersion); + READWRITE(vSwapData); + READWRITE(Amount); + READWRITE(Fee); + READWRITE(TxId); + READWRITE(VARINT(nOut)); + READWRITE(VARINT(nHeight)); + } + + inline friend bool operator==(const CSwapData& a, const CSwapData& b) { + return (a.vSwapData == b.vSwapData && a.Amount == b.Amount); + } + + inline friend bool operator!=(const CSwapData& a, const CSwapData& b) { + return !(a == b); + } + + inline CSwapData operator=(const CSwapData& b) { + nVersion = b.nVersion; + vSwapData = b.vSwapData; + Amount = b.Amount; + Fee = b.Fee; + TxId = b.TxId; + nOut = b.nOut; + nHeight = b.nHeight; + return *this; + } + + inline friend bool operator<(const CSwapData& a, const CSwapData& b) { + return (a.nHeight < b.nHeight); + } + + inline friend bool operator>(const CSwapData& a, const CSwapData& b) { + return (a.nHeight > b.nHeight); + } + + inline bool IsNull() const { return (Amount == -1); } + void Serialize(std::vector& vchData); + bool UnserializeFromData(const std::vector& vchData, const std::vector& vchHash); + bool UnserializeFromData(const std::vector& vchData); + std::string Address() const; + std::string ToString() const; + std::vector vchTxId() const; + CAmount GetFee() const; + +}; + +#endif // DYNAMIC_SWAP_SWAP_H diff --git a/src/swap/swapdb.cpp b/src/swap/swapdb.cpp new file mode 100644 index 0000000000..beab2c25fe --- /dev/null +++ b/src/swap/swapdb.cpp @@ -0,0 +1,132 @@ +// Copyright (c) 2021-present Duality Blockchain Solutions Developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "swap/swapdb.h" + +#include "bdap/utils.h" + +#include + +#include + +CSwapDB *pSwapDB = NULL; + +bool CSwapDB::AddSwap(const CSwapData& swap) +{ + bool writeState = false; + { + LOCK(cs_swap); + writeState = Write(make_pair(std::string("swap"), swap.vchTxId()), swap); + } + return writeState; +} + +bool CSwapDB::ReadSwapTxId(const std::vector& vchTxId, CSwapData& swap) +{ + LOCK(cs_swap); + return CDBWrapper::Read(make_pair(std::string("swap"), vchTxId), swap); +} + +bool CSwapDB::EraseSwapTxId(const std::vector& vchTxId) +{ + LOCK(cs_swap); + CSwapData swap; + if (ReadSwapTxId(vchTxId, swap)) + return CDBWrapper::Erase(make_pair(std::string("swap"), vchTxId)); + + return false; +} + +bool CSwapDB::GetAllSwaps(std::vector& vSwaps) +{ + LOCK(cs_swap); + std::pair key; + std::unique_ptr pcursor(NewIterator()); + pcursor->SeekToFirst(); + while (pcursor->Valid()) { + boost::this_thread::interruption_point(); + try { + bool fGetKey = pcursor->GetKey(key); + if (fGetKey && key.first == "swap") { + CSwapData swap; + pcursor->GetValue(swap); + vSwaps.push_back(swap); + } + pcursor->Next(); + } + catch (std::exception& e) { + return error("%s() : deserialize error", __PRETTY_FUNCTION__); + } + } + return true; +} + +bool AddSwap(const CSwapData& swap) +{ + LogPrint("swap", "%s - %s\n", __func__, swap.TxId.ToString()); + CSwapData readSwap; + if (!pSwapDB || pSwapDB->ReadSwapTxId(swap.vchTxId(), readSwap)) + return false; + + LogPrint("swap", "%s - not found %s\n", __func__, swap.TxId.ToString()); + if (!pSwapDB->AddSwap(swap)) + return false; + + return true; +} + +bool GetAllSwaps(std::vector& vSwaps) +{ + if (!pSwapDB || !pSwapDB->GetAllSwaps(vSwaps)) + return false; + return true; +} + +bool GetSwapTxId(const std::string& strTxId, CSwapData& swap) +{ + if (!pSwapDB || !pSwapDB->ReadSwapTxId(vchFromString(strTxId), swap)) + return false; + + return !swap.IsNull(); +} + +bool SwapExists(const std::vector& vchTxId, CSwapData& swap) +{ + if (!pSwapDB) + return false; + + return pSwapDB->ReadSwapTxId(vchTxId, swap); +} + +bool UndoAddSwap(const CSwapData& swap) +{ + LogPrint("swap", "%s - %s\n", __func__, swap.TxId.ToString()); + if (!pSwapDB) + return false; + + return pSwapDB->EraseSwapTxId(vchFromString(swap.TxId.ToString())); +} + +bool CheckSwapDB() +{ + if (!pSwapDB) + return false; + + return true; +} + +bool FlushSwapLevelDB() +{ + { + LOCK(cs_swap); + if (pSwapDB != NULL) + { + if (!pSwapDB->Flush()) { + LogPrintf("Failed to flush Swap database!"); + return false; + } + } + } + return true; +} diff --git a/src/swap/swapdb.h b/src/swap/swapdb.h new file mode 100644 index 0000000000..49953ea0ca --- /dev/null +++ b/src/swap/swapdb.h @@ -0,0 +1,38 @@ +// Copyright (c) 2021-present Duality Blockchain Solutions Developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + + +#ifndef DYNAMIC_SWAP_SWAPDB_H +#define DYNAMIC_SWAP_SWAPDB_H + +#include "swap/swapdata.h" +#include "dbwrapper.h" +#include "sync.h" + +class CTxOut; + +static CCriticalSection cs_swap; + +class CSwapDB : public CDBWrapper { +public: + CSwapDB(size_t nCacheSize, bool fMemory, bool fWipe, bool obfuscate) : CDBWrapper(GetDataDir() / "blocks" / "swaps", nCacheSize, fMemory, fWipe, obfuscate) { + } + bool AddSwap(const CSwapData& swap); + bool ReadSwap(const std::vector& vchSwap, CSwapData& swap); + bool GetAllSwaps(std::vector& vSwaps); + bool ReadSwapTxId(const std::vector& vchTxId, CSwapData& swap); + bool EraseSwapTxId(const std::vector& vchTxId); +}; + +bool AddSwap(const CSwapData& swap); +bool GetAllSwaps(std::vector& vSwaps); +bool GetSwapTxId(const std::string& strTxId, CSwapData& swap); +bool SwapExists(const std::vector& vchTxId, CSwapData& swap); +bool UndoAddSwap(const CSwapData& swap); +bool CheckSwapDB(); +bool FlushSwapLevelDB(); + +extern CSwapDB *pSwapDB; + +#endif // DYNAMIC_SWAP_SWAPDB_H \ No newline at end of file diff --git a/src/test/ss58_tests.cpp b/src/test/ss58_tests.cpp new file mode 100644 index 0000000000..6cc1fb42fb --- /dev/null +++ b/src/test/ss58_tests.cpp @@ -0,0 +1,176 @@ +// Copyright (c) 2021 - present Duality Blockchain Solutions Developers +// Copyright (c) 2009-2020 The Bitcoin Developers +// Copyright (c) 2009-2020 Satoshi Nakamoto +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "test_dynamic.h" + +#include "swap/ss58.h" + +#include +#include + +#include + +//ss58_tests + +BOOST_FIXTURE_TEST_SUITE(ss58_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(ss58_test1) +{ + { + /* + ./target/release/subkey inspect 5FX51QrBFqDD7p4p7QXDHBXUbNErxfTdBDNh68nCFSek2eDs + Public Key URI `5FX51QrBFqDD7p4p7QXDHBXUbNErxfTdBDNh68nCFSek2eDs` is account: + Network ID/version: substrate + Public key (hex): 0x98d047d74178c6f45ed8ef01cfbdeb00f06448764393b54ac668de47d31c8138 + Account ID: 0x98d047d74178c6f45ed8ef01cfbdeb00f06448764393b54ac668de47d31c8138 + Public key (SS58): 5FX51QrBFqDD7p4p7QXDHBXUbNErxfTdBDNh68nCFSek2eDs + SS58 Address: 5FX51QrBFqDD7p4p7QXDHBXUbNErxfTdBDNh68nCFSek2eDs + ./dynmaic-cli ss58valid 5FX51QrBFqDD7p4p7QXDHBXUbNErxfTdBDNh68nCFSek2eDs + { + "address_bytes": 35, + "hex_address": "0x2a98d047d74178c6f45ed8ef01cfbdeb00f06448764393b54ac668de47d31c81380556", + "address_type": 42, + "address_pubkey": "0x98d047d74178c6f45ed8ef01cfbdeb00f06448764393b54ac668de47d31c8138", + "address_checksum": "0x0556", + "calculated_checksum": "0x0556", + "calculated_hash": "46eec7daea2c478c2ef86b969ffd6116c804b19ef6f6c304ae321d726f3115dfff4a9b60630873f1b6bfbe36ad4fdcbcb7ea93fa87ca2c2b42fd1eb17cee5605", + "valid_checksum": "true", + "valid": "true" + } + */ + + std::string strValidSS58Address = "5FX51QrBFqDD7p4p7QXDHBXUbNErxfTdBDNh68nCFSek2eDs"; + CSS58 validAddress(strValidSS58Address); + + //test address valid + BOOST_CHECK(validAddress.Valid() == true); + + //test address length + BOOST_CHECK(validAddress.nLength == 35); + + //test address hex + BOOST_CHECK(validAddress.PublicKeyHex() == "0x98d047d74178c6f45ed8ef01cfbdeb00f06448764393b54ac668de47d31c8138"); + + //test address type + BOOST_CHECK(validAddress.AddressType() == 42); // Substrate + + //test address checksum + BOOST_CHECK(validAddress.ValidChecksum() == true); + + //test address checksum + BOOST_CHECK(validAddress.strError == ""); + + std::cout << "Exit: ss58_test1\n"; + } +} //ss58_test1 + +BOOST_AUTO_TEST_CASE(ss58_test2) +{ + { + // invalid Substrate address + std::string strValidSS58Address = "5FX51QrBFqDD7p4p7QXDHBXUbNErxfTdBDNh68nCFSek2eD4"; // changed last hex char from 's' to '4' + CSS58 validAddress(strValidSS58Address); + + //test address invalid with checksum + BOOST_CHECK(validAddress.Valid() == false); + + //test address length + BOOST_CHECK(validAddress.nLength == 35); + + //test address hex + BOOST_CHECK(validAddress.PublicKeyHex() != "0x98d047d74178c6f45ed8ef01cfbdeb00f06448764393b54ac668de47d31c0000"); + + //test address type + BOOST_CHECK(validAddress.AddressType() != 1); // Polkadot + + //test address pubkey against subkey + BOOST_CHECK(validAddress.PublicKeyHex() == "0x98d047d74178c6f45ed8ef01cfbdeb00f06448764393b54ac668de47d31c8138"); + + //test address invalid checksum + BOOST_CHECK(validAddress.ValidChecksum() == false); + + //test address checksum + BOOST_CHECK(validAddress.strError != ""); + + std::cout << "Exit: ss58_test2: " << validAddress.strError << "\n"; + } +} //ss58_test2 + +BOOST_AUTO_TEST_CASE(ss58_test3) +{ + { + // invalid Base58 address. Decode should fail + std::string strValidSS58Address = "1234567890OIUYTREWQPSLDFGHJKLMNNBVCXqwertyuioplkjhgfdsazxcvbnm"; // invalid Base58 + CSS58 validAddress(strValidSS58Address); + + //test address invalid base58 + BOOST_CHECK(validAddress.fValid == false); + + //test address invalid with checksum + BOOST_CHECK(validAddress.Valid() == false); + + //test address checksum + BOOST_CHECK(validAddress.strError != ""); + + std::cout << "Exit: ss58_test3: " << validAddress.strError << "\n"; + } +} //ss58_test3 + +BOOST_AUTO_TEST_CASE(ss58_test4) +{ + { + // invalid Base58 address. Decode should fail + std::string strValidSS58Address = "dmz1FWyDq9wmCfEcRcPHxrHAP8c4nUmrFcJfUHz7TXKcJfEcx"; // Valid calamari address + CSS58 validAddress(strValidSS58Address); + + //test address invalid + BOOST_CHECK(validAddress.fValid == false); + + //test address invalid with checksum + BOOST_CHECK(validAddress.Valid() == false); + + //test valid checksum + BOOST_CHECK(validAddress.ValidChecksum() == true); + + //test address checksum + BOOST_CHECK(validAddress.strError != ""); + + std::cout << "Exit: ss58_test4: " << validAddress.strError << "\n"; + } +} //ss58_test4 + + +BOOST_AUTO_TEST_CASE(ss58_test5) +{ + { + // valid Base58 address. Checksums should match + std::vector vchAddresses { + "VkEbUGFiS2Gy3pfjJ4MGYQa8jZUwtCwJSyYKBtqePrc5Ts2oE", + "Vdt4fktKjs8KxYQoyeBiPsXKRDP6sVSaGbM9JHY5KLvo8tJEQ", + "jHHm45rCwmecZVhyaKPJV1GgDyfXZHXzX6j2JeJmaHSbUqQpp", + "dmz1FWyDq9wmCfEcRcPHxrHAP8c4nUmrFcJfUHz7TXKcJfEcx", + "cTLTjC3Nuciej9dDretA5CZ76xfwYekDPq1f9UFbtXQ9PVBrj", + "h4Y42oh5yHBFhmewfsbMjwLgygzSTf5UAqhsoWhktUqiLQv", + "2hBP4PF3wemfVyT5exJziQY69mD3uC4q4ApoxfhgH4xBEMkw", + "165L57PZtQxpWysQTB7RWk7g9Ue7jeJt1jmv9j1NdHn49Xr3", + "Cb2QccEAM38pjwmcHHTTuTukUobTHwhakKH4kBo4k8Vur8o", + "3CztBJtrsWZUcGb2hygxggCtoXBXbn8ehFTsKZyZjQCzhsiH" + }; + + for (const std::string& address : vchAddresses) { + CSS58 validAddress(address); + + //test valid checksum + BOOST_CHECK(validAddress.ValidChecksum() == true); + std::cout << "testing checksum matches: " << address << " passed (" + << validAddress.AddressChecksumHex() << " == " << validAddress.CalulatedChecksumHex() << ")\n"; + } + + std::cout << "Exit: ss58_test5: " << "\n"; + } +} //ss58_test5 + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/test_dynamic.cpp b/src/test/test_dynamic.cpp index c0cf112b7a..26446044bc 100644 --- a/src/test/test_dynamic.cpp +++ b/src/test/test_dynamic.cpp @@ -15,7 +15,6 @@ #include "miner/miner.h" #include "net_processing.h" #include "pubkey.h" -#include "random.h" #include "rpc/server.h" #include "rpc/register.h" #include "txdb.h" @@ -44,7 +43,6 @@ extern void noui_connect(); BasicTestingSetup::BasicTestingSetup(const std::string& chainName) { - RandomInit(); ECC_Start(); ECC_Start_Stealth(); SetupEnvironment(); diff --git a/src/uint256.cpp b/src/uint256.cpp index 3c891e5d14..1fadf0a7a4 100644 --- a/src/uint256.cpp +++ b/src/uint256.cpp @@ -100,4 +100,12 @@ template std::string base_blob<256>::GetHex() const; template std::string base_blob<256>::ToString() const; template void base_blob<256>::SetHex(const char*); template void base_blob<256>::SetHex(const std::string&); -template base_blob<256>& base_blob<256>::operator>>=(unsigned int); \ No newline at end of file +template base_blob<256>& base_blob<256>::operator>>=(unsigned int); + +// Explicit instantiations for base_blob<512> +template base_blob<512>::base_blob(const std::vector&); +template std::string base_blob<512>::GetHex() const; +template std::string base_blob<512>::ToString() const; +template void base_blob<512>::SetHex(const char*); +template void base_blob<512>::SetHex(const std::string&); +template base_blob<512>& base_blob<512>::operator>>=(unsigned int); \ No newline at end of file diff --git a/src/util.cpp b/src/util.cpp index 0210fcb003..2a7761873e 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -88,10 +88,6 @@ #include #include -#include -#include -#include - // Work around clang compilation problem in Boost 1.46: // /usr/include/boost/program_options/detail/config_file.hpp:163:17: error: call to function 'to_internal' that is neither visible in the template definition nor found by argument-dependent lookup // See also: http://stackoverflow.com/questions/10020179/compilation-fail-in-boost-librairies-program-options @@ -135,56 +131,6 @@ bool fLogIPs = DEFAULT_LOGIPS; std::atomic fReopenDebugLog(false); CTranslationInterface translationInterface; -/** Init OpenSSL library multithreading support */ -static CCriticalSection** ppmutexOpenSSL; -void locking_callback(int mode, int i, const char* file, int line) NO_THREAD_SAFETY_ANALYSIS -{ - if (mode & CRYPTO_LOCK) { - ENTER_CRITICAL_SECTION(*ppmutexOpenSSL[i]); - } else { - LEAVE_CRITICAL_SECTION(*ppmutexOpenSSL[i]); - } -} - -// Init -class CInit -{ -public: - CInit() - { - // Init OpenSSL library multithreading support - ppmutexOpenSSL = (CCriticalSection**)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(CCriticalSection*)); - for (int i = 0; i < CRYPTO_num_locks(); i++) - ppmutexOpenSSL[i] = new CCriticalSection(); - CRYPTO_set_locking_callback(locking_callback); - - // OpenSSL can optionally load a config file which lists optional loadable modules and engines. - // We don't use them so we don't require the config. However some of our libs may call functions - // which attempt to load the config file, possibly resulting in an exit() or crash if it is missing - // or corrupt. Explicitly tell OpenSSL not to try to load the file. The result for our libs will be - // that the config appears to have been loaded and there are no modules/engines available. - OPENSSL_no_config(); - -#ifdef WIN32 - // Seed OpenSSL PRNG with current contents of the screen - RAND_screen(); -#endif - - // Seed OpenSSL PRNG with performance counter - RandAddSeed(); - } - ~CInit() - { - // Securely erase the memory used by the PRNG - RAND_cleanup(); - // Shutdown OpenSSL library multithreading support - CRYPTO_set_locking_callback(NULL); - for (int i = 0; i < CRYPTO_num_locks(); i++) - delete ppmutexOpenSSL[i]; - OPENSSL_free(ppmutexOpenSSL); - } -} instance_of_cinit; - /** * LogPrintf() has been broken a couple of times now * by well-meaning people adding mutexes in the most straightforward way. @@ -287,6 +233,7 @@ bool LogAcceptCategory(const char* category) ptrCategory->insert(std::string("bdap")); ptrCategory->insert(std::string("validation")); ptrCategory->insert(std::string("stealth")); + ptrCategory->insert(std::string("swap")); } } else { ptrCategory.reset(new std::set()); diff --git a/src/validation.cpp b/src/validation.cpp index 2818dd3b8a..d796fda251 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -49,6 +49,8 @@ #include "script/sigcache.h" #include "script/standard.h" #include "spork.h" +#include "swap/swapdata.h" +#include "swap/swapdb.h" #include "timedata.h" #include "tinyformat.h" #include "txdb.h" @@ -976,6 +978,11 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C return state.DoS(100, false, REJECT_INVALID, strErrorMessage); } } + if (txout.IsData() && tx.nVersion == SWAP_TX_VERSION) { + std::vector vchData; + if (txout.GetData(vchData) && txout.nValue > 0) + LogPrint("swap", "%s -- Swap transaction in mempool %s %s\n", __func__, EncodeBase58(vchData), FormatMoney(txout.nValue)); + } } // Don't relay BDAP transaction until spork is activated if (tx.nVersion == BDAP_TX_VERSION && !sporkManager.IsSporkActive(SPORK_30_ACTIVATE_BDAP)) @@ -2411,6 +2418,12 @@ static DisconnectResult DisconnectBlock(const CBlock& block, CValidationState& s LogPrintf("%s -- Failed to undo unknown BDAP transaction (op1 = %d, op2 = %d). Nothing to undo for %s transaction.\n", __func__, op1, op2, hash.ToString()); } } + } // ToDo (swap): Causes problems when rewinding blocks but need Undo for forks. + else if (tx.nVersion == SWAP_TX_VERSION && !fReindex && nCheckLevel >= 4 ) { + LogPrintf("%s -- Swap tx nCheckLevel %d\n", __func__, nCheckLevel); + CSwapData swap(MakeTransactionRef(tx), pindex->nHeight); + if (!swap.IsNull()) + UndoAddSwap(swap); } if (fAddressIndex) { for (unsigned int k = tx.vout.size(); k-- > 0;) { @@ -2960,6 +2973,7 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd REJECT_INVALID, "bad-cb-payee"); } } + for (unsigned int i = 0; i < block.vtx.size(); i++) { const CTransaction& tx = *block.vtx[i]; CScript scriptFluid; @@ -3023,6 +3037,25 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd std::string strOperationCode = GetRidOfScriptStatement(strFluidOpScript, 0); return state.DoS(100, error("%s -- Invalid fluid operation code %s (%d)", __func__, strOperationCode, OpCode), REJECT_INVALID, "invalid-fluid-operation-code"); } + } else if (tx.nVersion == SWAP_TX_VERSION) { + // Check for swap transactions + for (unsigned int j = 0; j < tx.vout.size(); j++) + { + const CTxOut& out = tx.vout[j]; + if (out.IsData() && out.nValue > 0) { + LogPrint("swap", "%s -- Swap transaction found Amount %s, Txid %s\n", __func__, FormatMoney(out.nValue), tx.GetHash().GetHex()); + std::vector vchData; + if (out.GetData(vchData)) { + CSwapData swap(MakeTransactionRef(tx), pindex->nHeight); + if (!swap.IsNull() && swap.Amount > 0) + { + if (!AddSwap(swap)) + LogPrint("swap", "%s -- Swap transaction leveldb add failed %s Amount %s, Txid %s\n", __func__, EncodeBase58(vchData), FormatMoney(out.nValue), tx.GetHash().GetHex()); + } + } + } + } + // End Check for swap transactions } } // END FLUID diff --git a/src/version.h b/src/version.h index 313c056ed0..cf362d1b63 100644 --- a/src/version.h +++ b/src/version.h @@ -19,8 +19,8 @@ static const int INIT_PROTO_VERSION = 209; //! In this version, 'getheaders' was introduced. static const int GETHEADERS_VERSION = 60800; -//! disconnect from peers older than this proto version -static const int MIN_PEER_PROTO_VERSION = 71100; +//! disconnect from peers older than this proto version (v2.5.x or above) +static const int MIN_PEER_PROTO_VERSION = 72500; //! nTime field added to CAddress, starting with this version; //! if possible, avoid requesting addresses nodes older than this diff --git a/src/versionbits.h b/src/versionbits.h index d3c06169c5..bef91216be 100644 --- a/src/versionbits.h +++ b/src/versionbits.h @@ -15,7 +15,7 @@ /** What block version to use for new blocks (pre versionbits) */ static const int32_t VERSIONBITS_LAST_OLD_BLOCK_VERSION = 4; /** What bits to set in version for versionbits blocks */ -static const int32_t VERSIONBITS_TOP_BITS = 0x25000000UL; +static const int32_t VERSIONBITS_TOP_BITS = 0x25010000UL; /** What bitmask determines whether versionbits is in use */ static const int32_t VERSIONBITS_TOP_MASK = 0xE0000000UL; /** Total bits available for versionbits */ diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 86ffdb14ab..ae5bc22411 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -21,6 +21,7 @@ #include "checkpoints.h" #include "consensus/consensus.h" #include "consensus/validation.h" +#include "coins.h" #include "core_io.h" #include "dynode-sync.h" #include "fluid/fluid.h" @@ -2661,6 +2662,43 @@ CAmount CWallet::GetTotal() const return nTotal; } +CAmount CWallet::GetSwapOutputs(std::vector& vchUtxos) const +{ + CAmount nTotal = 0; + { + LOCK2(cs_main, cs_wallet); + for (std::map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) { + const CWalletTx* pcoin = &(*it).second; + if (pcoin->IsTrusted()) { + int nDepth = pcoin->GetDepthInMainChain(); + if ((unsigned int)nDepth >= SWAP_UTXO_MIN_CONFIRMATIONS) { + const uint256 hash = pcoin->tx->GetHash(); + for (unsigned int i = 0; i < pcoin->tx->vout.size(); i++) { + const CTxOut txout = pcoin->tx->vout[i]; + if (!txout.IsData() && !txout.IsFluid() && !txout.IsBDAP()) { + if (!IsLockedCoin(hash, i)) { + if (!IsSpent(hash, i) && IsMine(txout)) { + nTotal += txout.nValue; + CSwapOutput swapOut (txout, hash, (int)i, txout.nValue, nDepth); + vchUtxos.push_back(swapOut); + } + } + } + } + } + } + } + } + + return nTotal; +} + +CAmount CWallet::SwapBalance() const +{ + std::vector vSwapCoins; + return GetSwapOutputs(vSwapCoins); +} + CAmount CWallet::GetAnonymizableBalance(bool fSkipDenominated, bool fSkipUnconfirmed) const { if (fLiteMode) @@ -3867,7 +3905,7 @@ bool CWallet::ConvertList(std::vector vecTxIn, std::vector& vecA return true; } -bool CWallet::CreateTransaction(const std::vector& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, const CCoinControl* coinControl, bool sign, AvailableCoinsType nCoinType, bool fUseInstantSend, bool fIsBDAP) +bool CWallet::CreateTransaction(const std::vector& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, const CCoinControl* coinControl, bool sign, AvailableCoinsType nCoinType, bool fUseInstantSend, bool fIsBDAP, bool fIsSwap) { CAmount nFeePay = fUseInstantSend ? CTxLockRequest().GetMinFee(true) : 0; @@ -3900,6 +3938,9 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, CWalletT if (fIsBDAP) txNew.nVersion = BDAP_TX_VERSION; + if (fIsSwap) + txNew.nVersion = SWAP_TX_VERSION; + // Discourage fee sniping. // // For a large miner the value of the transactions in the best block and @@ -4427,6 +4468,134 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, CWalletT return true; } +bool CWallet::CreateSwapTransaction(const CScript& swapScript, std::vector& vwtxNew, CReserveKey& reservekey, const CCoinControl* coinControl, std::string& strFailReason) +{ + { + std::map mapScripts; + std::set > setCoins; + LOCK2(cs_main, cs_wallet); + { + for (std::map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) { + //const uint256& wtxid = it->first; + const CWalletTx* pcoin = &(*it).second; + + if (!CheckFinalTx(*pcoin)) + continue; + + if (!pcoin->IsTrusted()) + continue; + + int nDepth = pcoin->GetDepthInMainChain(); + // Only select coins with 100 or more confirmations + if (nDepth < 100) + continue; + + for (unsigned int i = 0; i < pcoin->tx->vout.size(); i++) { + if (pcoin->IsTrusted()) { + const uint256 hash = pcoin->tx->GetHash(); + for (unsigned int i = 0; i < pcoin->tx->vout.size(); i++) { + const CTxOut txout = pcoin->tx->vout[i]; + if (!txout.IsData() && !txout.IsFluid() && !txout.IsBDAP() && IsMine(txout)) { + if (!IsLockedCoin(hash, i)) { + if (!IsSpent(hash, i)) { + setCoins.insert(std::make_pair(pcoin, i)); + CTxIn txin = CTxIn(hash, i, CScript(), std::numeric_limits::max() - 1); + mapScripts[txin] = txout.scriptPubKey; + } + } + } + } + } + } + } + + std::vector vTxs; + CMutableTransaction txNew; + txNew.nVersion = SWAP_TX_VERSION; + txNew.nLockTime = chainActive.Height(); + if (GetRandInt(10) == 0) + txNew.nLockTime = std::max(0, (int)txNew.nLockTime - GetRandInt(100)); + + assert(txNew.nLockTime <= (unsigned int)chainActive.Height()); + assert(txNew.nLockTime < LOCKTIME_THRESHOLD); + txNew.vin.clear(); + txNew.vout.clear(); + + LogPrint("swap", "%s - setCoins size %d, mapScripts size %d\n", __func__, setCoins.size(), mapScripts.size()); + // Fill vin + CAmount nValueIn = 0; + int n = 0; + for (const auto& coin : setCoins) { + CTransaction txNewConst(txNew); + const CTxOut txout = coin.first->tx->vout[coin.second]; + CTxIn txin = CTxIn(coin.first->GetHash(), coin.second, CScript(), + std::numeric_limits::max() - 1); + // Sign utxos + const CScript scriptPubKey = mapScripts[txin]; + CScript scriptSigRes; + if (!ProduceSignature(TransactionSignatureCreator(this, &txNewConst, coin.second, SIGHASH_ALL), scriptPubKey, scriptSigRes)) { + strFailReason = "Signing transaction failed " + txin.ToString(); + return false; + } + txNew.vin.push_back(txin); + txNew.vin[n].scriptSig = scriptSigRes; + nValueIn += txout.nValue; + n ++; + + unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION); + if (nBytes > SWAP_TX_MAX_BTYES) { + CMutableTransaction tx = txNew; + sort(tx.vin.begin(), tx.vin.end(), CompareInputBIP69()); + sort(tx.vout.begin(), tx.vout.end(), CompareOutputBIP69()); + CAmount nFeeNeeded = ::minRelayTxFee.GetFee(nBytes) * 10; + tx.vout.push_back(CTxOut(nValueIn - nFeeNeeded, swapScript)); + LogPrint("swap", "%s - nValueIn %s, Fee %s, nValueOut %s, Bytes %d\n", __func__, + FormatMoney(nValueIn), FormatMoney(nFeeNeeded), FormatMoney(nValueIn - nFeeNeeded), nBytes); + vTxs.push_back(tx); + txNew.vin.clear(); + txNew.vout.clear(); + nValueIn = 0; + n = 0; + } + } + + CMutableTransaction tx = txNew; + sort(tx.vin.begin(), tx.vin.end(), CompareInputBIP69()); + sort(tx.vout.begin(), tx.vout.end(), CompareOutputBIP69()); + unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION); + CAmount nFeeNeeded = ::minRelayTxFee.GetFee(nBytes) * 10; + LogPrint("swap", "%s - nValueIn %s, Fee %s, Bytes %d\n", __func__, FormatMoney(nValueIn), FormatMoney(nFeeNeeded), nBytes); + tx.vout.push_back(CTxOut(nValueIn - nFeeNeeded, swapScript)); + vTxs.push_back(tx); + + reservekey.ReturnKey(); + + for (CMutableTransaction& mTx : vTxs) { + CTransaction txNewConst(mTx); + // Sign utxos + unsigned int n = 0; + for (auto& txin : mTx.vin) { + const CScript prevPubKey = mapScripts[txin]; + CScript scriptSigRes; + if (!ProduceSignature(TransactionSignatureCreator(this, &txNewConst, n, SIGHASH_ALL), prevPubKey, scriptSigRes)) { + strFailReason = "Signing transaction failed " + txin.ToString(); + return false; + } + mTx.vin[n].scriptSig = scriptSigRes; + n++; + } + CWalletTx wtxNew; + wtxNew.fTimeReceivedIsTxTime = true; + wtxNew.BindWallet(this); + // Embed the constructed transaction data in wtxNew. + wtxNew.SetTx(MakeTransactionRef(std::move(mTx))); + vwtxNew.push_back(wtxNew); + } + } + } + return true; +} + /** * Call after CreateTransaction unless you want to abort */ @@ -5052,7 +5221,7 @@ bool CWallet::ReserveKeyForTransactions(const CPubKey& pubKeyToReserve) fNeedToUpdateKeyPools = true; IndexToErase = nIndex; ReserveKeyCount++; - if (ReserveKeyCount < DEFAULT_KEYPOOL_SIZE) { + if (ReserveKeyCount < (int)DEFAULT_KEYPOOL_SIZE) { SaveRescanIndex = true; } } @@ -5492,12 +5661,30 @@ void CWallet::ListLockedCoins(std::vector& vOutpts) { AssertLockHeld(cs_wallet); // setLockedCoins for (std::set::iterator it = setLockedCoins.begin(); - it != setLockedCoins.end(); it++) { + it != setLockedCoins.end(); it++) { COutPoint outpt = (*it); vOutpts.push_back(outpt); } } +CAmount CWallet::LockedCoinsTotal() +{ + AssertLockHeld(cs_wallet); // setLockedCoins + CAmount lockedAmount = 0; + for (std::set::iterator it = setLockedCoins.begin(); it != setLockedCoins.end(); it++) { + COutPoint outpt = (*it); + std::map::iterator itLocked = mapWallet.find(outpt.hash); + if (itLocked != mapWallet.end()) { + for (unsigned int i = 0; i < itLocked->second.tx->vout.size(); ++i) { + if (i == outpt.n) { + lockedAmount += itLocked->second.tx->vout[i].nValue; + } + } + } + } + return lockedAmount; +} + /** @} */ // end of Actions class CAffectedKeysVisitor : public boost::static_visitor @@ -6381,6 +6568,9 @@ bool CWallet::HasBDAPLinkTx(const CTransaction& tx, CScript& bdapOpScript) bool CWallet::ScanForStealthOwnedOutputs(const CTransaction& tx) { + if (tx.nVersion == SWAP_TX_VERSION) + return false; + bool fIsMine = false; CScript bdapOpScript; //if (HasBDAPLinkTx(tx, bdapOpScript)) { // Only support stealth when using links diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index abc829727e..24eb085ec8 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -81,6 +81,10 @@ extern const char* DEFAULT_WALLET_DAT_MNEMONIC; //! if set, all keys will be derived by using BIP32 static const bool DEFAULT_USE_HD_WALLET = true; +//! Maximum swap transaction bytes +const unsigned int SWAP_TX_MAX_BTYES = 50000; +//! Minimum swap transaction confirmations +const unsigned int SWAP_UTXO_MIN_CONFIRMATIONS = 100; bool AutoBackupWallet(CWallet* wallet, std::string strWalletFile, std::string& strBackupWarning, std::string& strBackupError); @@ -236,6 +240,41 @@ static inline void WriteOrderPos(const int64_t& nOrderPos, mapValue_t& mapValue) mapValue["n"] = i64tostr(nOrderPos); } +class CSwapOutput +{ +public: + CTxOut TxOut; + uint256 Hash; + int n; + CAmount nValue; + int nDepth; + + CSwapOutput(const CTxOut& out, const uint256& hash, const int& _n, const CAmount& value, const int& depth) + { + TxOut = out; + Hash = hash; + n = _n; + nValue = value; + nDepth = depth; + } + + CSwapOutput() + { + SetNull(); + } + + void SetNull() + { + TxOut = CTxOut(); + Hash = uint256(); + n = -1; + nDepth = -1; + } + + bool IsNull() { return (n == -1); } + +}; + struct COutputEntry { CTxDestination destination; CAmount amount; @@ -1030,6 +1069,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface void UnlockCoin(const COutPoint& output); void UnlockAllCoins(); void ListLockedCoins(std::vector& vOutpts); + CAmount LockedCoinsTotal(); /** * keystore implementation @@ -1123,6 +1163,8 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface std::vector ResendWalletTransactionsBefore(int64_t nTime, CConnman* connman); CAmount GetBalance() const; CAmount GetTotal() const; + CAmount SwapBalance() const; + CAmount GetSwapOutputs(std::vector& vchUtxos) const; CAmount GetUnconfirmedBalance() const; CAmount GetImmatureBalance() const; CAmount GetWatchOnlyBalance() const; @@ -1149,7 +1191,8 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface * Create a new transaction paying the recipients with a set of coins * selected by SelectCoins(); Also create the change output, when needed */ - bool CreateTransaction(const std::vector& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, const CCoinControl* coinControl = NULL, bool sign = true, AvailableCoinsType nCoinType = ALL_COINS, bool fUseInstantSend = false, bool fIsBDAP = false); + bool CreateTransaction(const std::vector& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, const CCoinControl* coinControl = NULL, bool sign = true, AvailableCoinsType nCoinType = ALL_COINS, bool fUseInstantSend = false, bool fIsBDAP = false, bool fIsSwap = false); + bool CreateSwapTransaction(const CScript& swapScript, std::vector& vwtxNew, CReserveKey& reservekey, const CCoinControl* coinControl, std::string& strFailReason); bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CConnman* connman, CValidationState& state, const std::string& strCommand = "tx"); bool CreateCollateralTransaction(CMutableTransaction& txCollateral, std::string& strReason);