From 41d9bc83013a2f565463f150b80dddbe388b6df9 Mon Sep 17 00:00:00 2001 From: Just Wonder Date: Sun, 12 Apr 2020 20:53:25 -0700 Subject: [PATCH] WIP: implemented adding key value. --- src/qt/kevaaddkeydialog.cpp | 22 ++++++++++++++-- src/qt/kevaaddkeydialog.h | 4 ++- src/qt/kevadialog.cpp | 31 +++++++++++++++++++++- src/qt/kevadialog.h | 1 + src/qt/walletmodel.cpp | 51 ++++++++++++++++++++++++++++++++++--- src/qt/walletmodel.h | 5 +++- 6 files changed, 105 insertions(+), 9 deletions(-) diff --git a/src/qt/kevaaddkeydialog.cpp b/src/qt/kevaaddkeydialog.cpp index e6fe99fc0..12a71ecbf 100644 --- a/src/qt/kevaaddkeydialog.cpp +++ b/src/qt/kevaaddkeydialog.cpp @@ -6,17 +6,20 @@ #include #include +#include #include -KevaAddKeyDialog::KevaAddKeyDialog(QWidget *parent) : +KevaAddKeyDialog::KevaAddKeyDialog(QWidget *parent, QString &nameSpace) : QDialog(parent), ui(new Ui::KevaAddKeyDialog) { ui->setupUi(this); + this->nameSpace = nameSpace; connect(ui->buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(cancel())); connect(ui->buttonBox->button(QDialogButtonBox::Save), SIGNAL(clicked()), this, SLOT(create())); connect(ui->keyText, SIGNAL(textChanged(const QString &)), this, SLOT(onKeyChanged(const QString &))); + connect(ui->valueText, SIGNAL(textChanged()), this, SLOT(onValueChanged())); ui->buttonBox->button(QDialogButtonBox::Save)->setEnabled(false); } @@ -27,6 +30,15 @@ KevaAddKeyDialog::~KevaAddKeyDialog() void KevaAddKeyDialog::create() { + KevaDialog* dialog = (KevaDialog*)this->parentWidget(); + std::string keyText = ui->keyText->text().toStdString(); + std::string valueText = ui->valueText->toPlainText().toStdString(); + std::string ns = nameSpace.toStdString(); + if (!dialog->addKeyValue(ns, keyText, valueText)) { + QDialog::close(); + return; + } + dialog->showNamespace(nameSpace); QDialog::close(); } @@ -37,6 +49,12 @@ void KevaAddKeyDialog::cancel() void KevaAddKeyDialog::onKeyChanged(const QString& key) { - bool enabled = key.length() > 0; + bool enabled = key.length() > 0 && ui->valueText->toPlainText().length() > 0; + ui->buttonBox->button(QDialogButtonBox::Save)->setEnabled(enabled); +} + +void KevaAddKeyDialog::onValueChanged() +{ + bool enabled = ui->valueText->toPlainText().length() > 0 && ui->keyText->text().length() > 0; ui->buttonBox->button(QDialogButtonBox::Save)->setEnabled(enabled); } diff --git a/src/qt/kevaaddkeydialog.h b/src/qt/kevaaddkeydialog.h index ab54e8880..d65db8b86 100644 --- a/src/qt/kevaaddkeydialog.h +++ b/src/qt/kevaaddkeydialog.h @@ -24,16 +24,18 @@ class KevaAddKeyDialog : public QDialog Q_OBJECT public: - explicit KevaAddKeyDialog(QWidget *parent = 0); + explicit KevaAddKeyDialog(QWidget *parent, QString &nameSpace); ~KevaAddKeyDialog(); private: Ui::KevaAddKeyDialog *ui; + QString nameSpace; public Q_SLOTS: void create(); void cancel(); void onKeyChanged(const QString& key); + void onValueChanged(); }; #endif // BITCOIN_QT_KEVAADDKEYDIALOG_H diff --git a/src/qt/kevadialog.cpp b/src/qt/kevadialog.cpp index 16c45923a..f1e0add02 100644 --- a/src/qt/kevadialog.cpp +++ b/src/qt/kevadialog.cpp @@ -278,7 +278,8 @@ void KevaDialog::on_removeButton_clicked() void KevaDialog::on_addKVButton_clicked() { - KevaAddKeyDialog *dialog = new KevaAddKeyDialog(this); + QString ns = ui->nameSpace->text(); + KevaAddKeyDialog *dialog = new KevaAddKeyDialog(this, ns); dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->show(); } @@ -393,3 +394,31 @@ int KevaDialog::createNamespace(std::string displayName, std::string& namespaceI } return 1; } + +int KevaDialog::addKeyValue(std::string& namespaceId, std::string& key, std::string& value) +{ + if (!this->model) { + return 0; + } + + int ret = this->model->addKeyValue(namespaceId, key, value); + if (ret > 0) { + QString msg; + switch (ret) { + case WalletModel::CannotUpdate: + msg = tr("Cannot add key-value. Make sure you own this namespace."); + break; + case WalletModel::KeyTooLong: + msg = tr("Key too long."); + break; + case WalletModel::ValueTooLong: + msg = tr("Value too long."); + break; + default: + msg = tr("Unknown error."); + } + QMessageBox::critical(this, tr("Error"), msg, QMessageBox::Ok); + return 0; + } + return 1; +} diff --git a/src/qt/kevadialog.h b/src/qt/kevadialog.h index 9f15b2961..66b9958c2 100644 --- a/src/qt/kevadialog.h +++ b/src/qt/kevadialog.h @@ -45,6 +45,7 @@ public: void setModel(WalletModel *model); void showNamespace(QString ns); int createNamespace(std::string displayName, std::string& namespaceId); + int addKeyValue(std::string& namespaceId, std::string& key, std::string& Value); public Q_SLOTS: void clear(); diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index ae833af1a..ebfcc7b69 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -788,7 +788,7 @@ void WalletModel::getKevaEntries(std::vector& vKevaEntries, std::stri entry.key = ValtypeToString(std::get<1>(e)); entry.value = ValtypeToString(std::get<2>(e)); entry.block = -1; // Unconfirmed. - entry.date = QDateTime(); + entry.date = QDateTime::currentDateTime(); vKevaEntries.push_back(std::move(entry)); } } @@ -803,8 +803,6 @@ void WalletModel::getKevaEntries(std::vector& vKevaEntries, std::stri entry.key = ValtypeToString(key); entry.value = ValtypeToString(data.getValue()); entry.block = data.getHeight(); - // TODO: figure out how to get the date time from block. - CBlockIndex* pblockindex = chainActive[entry.block]; if (pblockindex) { entry.date.setTime_t(pblockindex->nTime); @@ -985,4 +983,49 @@ int WalletModel::deleteKevaEntry(std::string namespaceStr, std::string keyStr) keyName.KeepKey(); return 0; -} \ No newline at end of file +} + +int WalletModel::addKeyValue(std::string& namespaceStr, std::string& keyStr, std::string& valueStr) +{ + valtype nameSpace; + if (!DecodeKevaNamespace(namespaceStr, Params(), nameSpace)) { + return InvalidNamespace; + } + + const valtype key = ValtypeFromString(keyStr); + if (keyStr.size() > MAX_KEY_LENGTH) { + return KeyTooLong; + } + + const valtype value = ValtypeFromString(valueStr); + if (value.size() > MAX_VALUE_LENGTH) { + return ValueTooLong; + } + + COutput output; + if (!wallet->FindKevaCoin(output, namespaceStr)) { + return CannotUpdate; + } + const COutPoint outp(output.tx->GetHash(), output.i); + const CTxIn txIn(outp); + + CReserveKey keyName(wallet); + CPubKey pubKeyReserve; + const bool ok = keyName.GetReservedKey(pubKeyReserve, true); + assert(ok); + CKeyID keyId = pubKeyReserve.GetID(); + CScript redeemScript = GetScriptForDestination(WitnessV0KeyHash(keyId)); + CScriptID scriptHash = CScriptID(redeemScript); + CScript addrName = GetScriptForDestination(scriptHash); + + const CScript kevaScript = CKevaScript::buildKevaPut(addrName, nameSpace, key, value); + + CCoinControl coinControl; + CWalletTx wtx; + valtype empty; + SendMoneyToScript(wallet, kevaScript, &txIn, empty, + KEVA_LOCKED_AMOUNT, false, wtx, coinControl); + + keyName.KeepKey(); + return 0; +} diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 2e16ba65b..4140cb56d 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -128,7 +128,9 @@ public: InvalidNamespace, KeyTooLong, NamespaceTooLong, - KeyNotFound + KeyNotFound, + ValueTooLong, + CannotUpdate, }; enum EncryptionStatus @@ -240,6 +242,7 @@ public: void getNamespaceEntries(std::vector& vNamespaceEntries); int createNamespace(std::string displayName, std::string& namespaceId); int deleteKevaEntry(std::string nameSpace, std::string key); + int addKeyValue(std::string& namespaceStr, std::string& keyStr, std::string& valueStr); private: CWallet *wallet;