Skip to content

Commit

Permalink
Add payment sidechain, bug fixes, refactoring, gui
Browse files Browse the repository at this point in the history
* Added payment sidechain keypair
* Fixed several GUI bugs related to multi-sidechain support
* Fixed several wallet bugs related to multi-sidechain support
* Fixed several validation bugs related to multi-sidechain support
  • Loading branch information
CryptAxe committed Oct 21, 2018
1 parent b9e49de commit b2350a9
Show file tree
Hide file tree
Showing 17 changed files with 159 additions and 101 deletions.
1 change: 1 addition & 0 deletions src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ RES_ICONS = \
qt/res/icons/remove.png \
qt/res/icons/send.png \
qt/res/icons/sidechain_one.png \
qt/res/icons/sidechain_payments.png \
qt/res/icons/synced.png \
qt/res/icons/transaction0.png \
qt/res/icons/transaction2.png \
Expand Down
5 changes: 4 additions & 1 deletion src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1786,8 +1786,11 @@ bool AppInitMain()

// Watch sidechain deposit addresses
for (const Sidechain& sidechain : ValidSidechains) {
std::vector<unsigned char> data(ParseHex(std::string(sidechain.sidechainHex)));
std::vector<unsigned char> data;
data = std::vector<unsigned char>(ParseHex(sidechain.sidechainHex));

CScript script(data.begin(), data.end());

if (!pwallet->HaveWatchOnly(script)) {
pwallet->AddWatchOnly(script, 0 /* nCreateTime */);
}
Expand Down
43 changes: 21 additions & 22 deletions src/primitives/transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,28 +161,27 @@ bool CCriticalData::IsBMMRequest(uint8_t& nSidechain, uint16_t& nPrevBlockRef) c
if (bytes[0] != 0x00 || bytes[1] != 0xbf || bytes[2] != 0x00)
return false;

// Convert bytes to script for easy parsing
CScript script(bytes.begin(), bytes.end());

// Get nSidechain
CScript::const_iterator psidechain = script.begin() + 3;
opcodetype opcode;
std::vector<unsigned char> vchSidechain;
if (!script.GetOp(psidechain, opcode, vchSidechain))
return false;

// Is nSidechain valid?
nSidechain = CScriptNum(vchSidechain, true).getint();
if (!IsSidechainNumberValid(nSidechain))
return false;

// Get prevBlockRef
CScript::const_iterator pprevblock = psidechain + vchSidechain.size() + 1;
std::vector<unsigned char> vchPrevBlockRef;
if (!script.GetOp(pprevblock, opcode, vchPrevBlockRef))
return false;

nPrevBlockRef = CScriptNum(vchPrevBlockRef, true).getint();
if (bytes.size() == 4) {
nSidechain = 0;
if (!IsSidechainNumberValid(nSidechain))
return false;

std::vector<unsigned char> vch;
vch.push_back(bytes[3]);
nPrevBlockRef = CScriptNum(vch, false).getint();

} else {
std::vector<unsigned char> vch;
vch.push_back(bytes[3]);

nSidechain = CScriptNum(vch, false).getint();
if (!IsSidechainNumberValid(nSidechain))
return false;

std::vector<unsigned char> vchPrev;
vchPrev.push_back(bytes[4]);
nPrevBlockRef = CScriptNum(vchPrev, false).getint();
}

return true;
}
1 change: 1 addition & 0 deletions src/qt/drivenet.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
<file alias="overview">res/icons/overview.png</file>
<file alias="export">res/icons/export.png</file>
<file alias="sidechain_one">res/icons/sidechain_one.png</file>
<file alias="sidechain_payments">res/icons/sidechain_payments.png</file>
<file alias="synced">res/icons/synced.png</file>
<file alias="remove">res/icons/remove.png</file>
<file alias="tx_mined">res/icons/tx_mined.png</file>
Expand Down
11 changes: 3 additions & 8 deletions src/qt/forms/sidechainpage.ui
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,8 @@
<item>
<widget class="QComboBox" name="comboBoxSidechains">
<property name="currentText">
<string>Sidechain One</string>
<string/>
</property>
<item>
<property name="text">
<string>Sidechain One</string>
</property>
</item>
</widget>
</item>
<item>
Expand Down Expand Up @@ -180,13 +175,13 @@
<item>
<widget class="QPushButton" name="pushButtonDeposit">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Deposit</string>
<string/>
</property>
<property name="icon">
<iconset resource="../drivenet.qrc">
Expand Down
Binary file added src/qt/res/icons/sidechain_payments.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 26 additions & 5 deletions src/qt/sidechainpage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
#include <miner.h>
#include <net.h>
#include <primitives/block.h>
#include <sidechain.h>
#include <txdb.h>
#include <validation.h>
#include <wallet/coincontrol.h>
Expand All @@ -48,20 +47,24 @@ SidechainPage::SidechainPage(QWidget *parent) :
for (const Sidechain& s : ValidSidechains) {
QListWidgetItem *item = new QListWidgetItem(ui->listWidgetSidechains);

// TODO keep list of sidechain icons and display correct icon based on nSidechain
// Set icon
QIcon icon(":/icons/sidechain_one");
QIcon icon(SidechainIcons[s.nSidechain]);
item->setIcon(icon);

// Set text
item->setText(QString::fromStdString(s.GetSidechainName()));
QFont font = item->font();
font.setPointSize(22);
font.setPointSize(16);
item->setFont(font);

ui->listWidgetSidechains->addItem(item);
}

// Setup sidechain selection combo box
for (const Sidechain& s : ValidSidechains) {
ui->comboBoxSidechains->addItem(QString::fromStdString(s.GetSidechainName()));
}

// Initialize models
escrowModel = new SidechainEscrowTableModel(this);
withdrawalModel = new SidechainWithdrawalTableModel(this);
Expand Down Expand Up @@ -207,7 +210,7 @@ void SidechainPage::on_pushButtonDeposit_clicked()
// Successful deposit message box
messageBox.setWindowTitle("Deposit transaction created!");
QString result = "Deposited to " + QString::fromStdString(GetSidechainName(nSidechain));
result += " Sidechain.\n";
result += "\n";
result += "txid: " + QString::fromStdString(tx->GetHash().ToString());
result += "\n";
result += "Amount deposited: ";
Expand All @@ -228,6 +231,24 @@ void SidechainPage::on_pushButtonClear_clicked()
ui->payTo->clear();
}

void SidechainPage::on_comboBoxSidechains_currentIndexChanged(const int i)
{
if (!IsSidechainNumberValid(i))
return;

ui->listWidgetSidechains->setCurrentRow(i);

// Update deposit button text
QString strSidechain = QString::fromStdString(GetSidechainName(i));
QString str = "Deposit to: " + strSidechain;
ui->pushButtonDeposit->setText(str);
}

void SidechainPage::on_listWidgetSidechains_doubleClicked(const QModelIndex& i)
{
ui->comboBoxSidechains->setCurrentIndex(i.row());
}

bool SidechainPage::validateDepositAmount()
{
if (!ui->payAmount->validate()) {
Expand Down
14 changes: 14 additions & 0 deletions src/qt/sidechainpage.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
#ifndef SIDECHAINPAGE_H
#define SIDECHAINPAGE_H

#include <QString>
#include <QWidget>

#include <amount.h>
#include <sidechain.h>
#include <uint256.h>

#include <string>
Expand All @@ -22,6 +24,13 @@ namespace Ui {
class SidechainPage;
}

// Sidechain icons
static const std::array<QString, VALID_SIDECHAINS_COUNT> SidechainIcons =
{{
{":/icons/sidechain_one"},
{":/icons/sidechain_payments"},
}};

class SidechainPage : public QWidget
{
Q_OBJECT
Expand All @@ -43,6 +52,10 @@ public Q_SLOTS:

void on_pushButtonClear_clicked();

void on_comboBoxSidechains_currentIndexChanged(const int index);

void on_listWidgetSidechains_doubleClicked(const QModelIndex& index);

private:
Ui::SidechainPage *ui;

Expand All @@ -54,6 +67,7 @@ public Q_SLOTS:
void SetupTables();

bool validateDepositAmount();

};

#endif // SIDECHAINPAGE_H
6 changes: 3 additions & 3 deletions src/rpc/misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -727,8 +727,8 @@ UniValue createbmmcriticaldatatx(const JSONRPCRequest& request)
bytes[1] = 0xbf;
bytes[2] = 0x00;

bytes << CScriptNum::serialize(nSidechain);
bytes << CScriptNum::serialize(nDAG);
bytes << CScriptNum(nSidechain);
bytes << CScriptNum(nDAG);

CCriticalData criticalData;
criticalData.bytes = std::vector<unsigned char>(bytes.begin(), bytes.end());
Expand Down Expand Up @@ -800,7 +800,7 @@ UniValue listsidechainctip(const JSONRPCRequest& request)
#endif

// Is nSidechain valid?
uint8_t nSidechain = std::stoi(request.params[0].getValStr());
uint8_t nSidechain = (unsigned int)request.params[0].get_int();
if (!IsSidechainNumberValid(nSidechain))
throw std::runtime_error("Invalid sidechain number");

Expand Down
16 changes: 7 additions & 9 deletions src/sidechain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ std::string Sidechain::GetSidechainName() const
switch (nSidechain) {
case SIDECHAIN_ONE:
return "Sidechain One";
case SIDECHAIN_PAYMENT:
return "Payment Sidechain";
default:
break;
}
Expand Down Expand Up @@ -166,14 +168,10 @@ bool SCDBIndex::GetMember(uint256 hashWT, SidechainWTPrimeState& wt) const

bool IsSidechainNumberValid(uint8_t nSidechain)
{
if (!(nSidechain < ValidSidechains.size()))
return false;

// Check that number corresponds to a valid sidechain
switch (nSidechain) {
case SIDECHAIN_ONE:
return true;
default:
return false;
for (const Sidechain& s : ValidSidechains) {
if (s.nSidechain == nSidechain)
return true;
}

return false;
}
20 changes: 14 additions & 6 deletions src/sidechain.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

//! Max number of WT^(s) per sidechain during verification period
static const int SIDECHAIN_MAX_WT = 32; // TODO remove (CryptAxe wants this, psztorc does not)
static const size_t VALID_SIDECHAINS_COUNT = 1;
static const size_t VALID_SIDECHAINS_COUNT = 2;

// These are the temporary values to speed things up during testing
static const int SIDECHAIN_VERIFICATION_PERIOD = 300;
Expand All @@ -27,6 +27,7 @@ static const CAmount SIDECHAIN_DEPOSIT_FEE = 0.00001 * COIN;

enum SidechainNumber {
SIDECHAIN_ONE = 0,
SIDECHAIN_PAYMENT = 1,
};

struct Sidechain {
Expand Down Expand Up @@ -132,16 +133,23 @@ static const std::array<Sidechain, VALID_SIDECHAINS_COUNT> ValidSidechains =
//
// {nSidechain, sidechain keyID, sidechain private key, public key}
//
// Sidechain One (test sidechain): 4ZZC8413qr9gWRymw2PryT3mY3KikidNxg
// Sidechain One (test sidechain)
{SIDECHAIN_ONE,
"f790b44c3cd78a786819cd4cb6fd696e8d81c0d9",
"Kxpt9ph9fdYzw1dVThf5fPuAHzsFzKaWfYiHx3EzYwVb6PQPy6f9",
"76a914d9c0818d6e69fdb64ccd1968788ad73c4cb490f788ac"},
"51c6eb4891cbb94ca30518b5f8441ea078c849eb",
"L4nNEPEuYwNaKMj1RZVsAuXPq5xbhdio43dTRzAr5CZgQHrSpFU8",
"76a91451c6eb4891cbb94ca30518b5f8441ea078c849eb88ac"},
//
// Payments sidechain
{SIDECHAIN_PAYMENT,
"7c33a3f6d9d5b873f96dba4b12d6aaf6be71fbd2",
"L3UjtLhNXKZaDgFtf14EHkxV1p5CKUoyRUT5DcU7aUS1X2yX8hhg",
"76a9147c33a3f6d9d5b873f96dba4b12d6aaf6be71fbd288ac"},
}};

static const std::map<std::string, int> ValidSidechainField =
{
{"76a914d9c0818d6e69fdb64ccd1968788ad73c4cb490f788ac", SIDECHAIN_ONE},
{"76a91451c6eb4891cbb94ca30518b5f8441ea078c849eb88ac", SIDECHAIN_ONE},
{"76a9147c33a3f6d9d5b873f96dba4b12d6aaf6be71fbd288ac", SIDECHAIN_PAYMENT},
};


Expand Down
19 changes: 9 additions & 10 deletions src/sidechaindb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ void SidechainDB::AddDeposits(const std::vector<CTransaction>& vtx, const uint25
}

// scriptPubKey must contain keyID
if (scriptPubKey.size() < sizeof(uint160) + 2)
if (scriptPubKey.size() != 23 && scriptPubKey.size() != 24)
continue;
if (scriptPubKey.front() != OP_RETURN)
continue;
Expand All @@ -43,7 +43,7 @@ void SidechainDB::AddDeposits(const std::vector<CTransaction>& vtx, const uint25
if (!IsSidechainNumberValid(nSidechain))
continue;

CScript::const_iterator pkey = scriptPubKey.begin() + 2;
CScript::const_iterator pkey = scriptPubKey.begin() + 2 + (scriptPubKey.size() == 24);
opcodetype opcode;
std::vector<unsigned char> vch;
if (!scriptPubKey.GetOp(pkey, opcode, vch))
Expand Down Expand Up @@ -173,6 +173,7 @@ bool SidechainDB::CheckWorkScore(uint8_t nSidechain, const uint256& hashWTPrime)

std::vector<SidechainDeposit> SidechainDB::GetDeposits(uint8_t nSidechain) const
{
// TODO C++11 const for loop
std::vector<SidechainDeposit> vSidechainDeposit;
for (size_t i = 0; i < vDepositCache.size(); i++) {
if (vDepositCache[i].nSidechain == nSidechain)
Expand Down Expand Up @@ -269,8 +270,10 @@ bool SidechainDB::HasState() const
return false;

// Check if any SCDBIndex(s) are populated
if (SCDB[SIDECHAIN_ONE].IsPopulated())
return true;
for (const SCDBIndex& i : SCDB) {
if (i.IsPopulated())
return true;
}

if (vWTPrimeCache.size())
return true;
Expand Down Expand Up @@ -431,14 +434,10 @@ bool SidechainDB::Update(int nHeight, const uint256& hashBlock, const std::vecto
uint256 hashWTPrime = uint256(std::vector<unsigned char>(scriptPubKey.begin() + 6, scriptPubKey.begin() + 38));

// Get sidechain number
CScript::const_iterator pnsidechain = scriptPubKey.begin() + 38;
std::vector<unsigned char> vchNS;
opcodetype opcode;
if (!scriptPubKey.GetOp(pnsidechain, opcode, vchNS))
if (vchNS.size() < 1 || vchNS.size() > 4)
continue;
vchNS.push_back(scriptPubKey[39]);

CScriptNum nSidechain(vchNS, true);
CScriptNum nSidechain(vchNS, false);

if (!AddWTPrime(nSidechain.getint(), hashWTPrime, nHeight)) {
// TODO handle failure or at least log something
Expand Down
Loading

0 comments on commit b2350a9

Please sign in to comment.