Initial cut at manually creating blocks.
This commit is contained in:
parent
e8c1215f58
commit
06364f5ff2
8 changed files with 321 additions and 10 deletions
|
@ -544,6 +544,11 @@ bool rai::wallet::fetch (rai::public_key const & pub, rai::private_key & prv)
|
|||
return result;
|
||||
}
|
||||
|
||||
bool rai::wallet::exists (rai::public_key const & pub)
|
||||
{
|
||||
return find (pub) != end ();
|
||||
}
|
||||
|
||||
rai::key_iterator::key_iterator (leveldb::DB * db_a) :
|
||||
iterator (db_a->NewIterator (leveldb::ReadOptions ()))
|
||||
{
|
||||
|
|
|
@ -298,6 +298,7 @@ namespace rai {
|
|||
rai::uint256_union salt ();
|
||||
void insert (rai::private_key const &);
|
||||
bool fetch (rai::public_key const &, rai::private_key &);
|
||||
bool exists (rai::public_key const &);
|
||||
bool generate_send (rai::ledger &, rai::public_key const &, rai::uint128_t const &, std::vector <std::unique_ptr <rai::send_block>> &);
|
||||
bool valid_password ();
|
||||
key_iterator find (rai::uint256_union const &);
|
||||
|
|
|
@ -34,6 +34,13 @@ TEST (uint256_union, encryption)
|
|||
ASSERT_EQ (number1, number2);
|
||||
}
|
||||
|
||||
TEST (uint256_union, decode_empty)
|
||||
{
|
||||
std::string text;
|
||||
rai::uint256_union val;
|
||||
ASSERT_TRUE (val.decode_hex (text));
|
||||
}
|
||||
|
||||
TEST (uint256_union, parse_zero)
|
||||
{
|
||||
rai::uint256_union input (rai::uint256_t (0));
|
||||
|
|
|
@ -228,7 +228,9 @@ TEST (wallet, find_existing)
|
|||
rai::wallet wallet (init, boost::filesystem::unique_path ());
|
||||
ASSERT_FALSE (init);
|
||||
rai::keypair key1;
|
||||
ASSERT_FALSE (wallet.exists (key1.pub));
|
||||
wallet.insert (key1.prv);
|
||||
ASSERT_TRUE (wallet.exists (key1.pub));
|
||||
auto existing (wallet.find (key1.pub));
|
||||
ASSERT_NE (wallet.end (), existing);
|
||||
++existing;
|
||||
|
|
273
rai/qt/qt.cpp
273
rai/qt/qt.cpp
|
@ -638,6 +638,9 @@ destination_label (new QLabel ("Destination:")),
|
|||
destination (new QLineEdit),
|
||||
representative_label (new QLabel ("Representative:")),
|
||||
representative (new QLineEdit),
|
||||
block (new QPlainTextEdit),
|
||||
status (new QLabel),
|
||||
create (new QPushButton ("Create")),
|
||||
back (new QPushButton ("Back")),
|
||||
client (client_a)
|
||||
{
|
||||
|
@ -645,6 +648,10 @@ client (client_a)
|
|||
group->addButton (receive);
|
||||
group->addButton (change);
|
||||
group->addButton (open);
|
||||
group->setId (send, 0);
|
||||
group->setId (receive, 1);
|
||||
group->setId (change, 2);
|
||||
group->setId (open, 3);
|
||||
|
||||
button_layout->addWidget (send);
|
||||
button_layout->addWidget (receive);
|
||||
|
@ -662,7 +669,9 @@ client (client_a)
|
|||
layout->addWidget (destination);
|
||||
layout->addWidget (representative_label);
|
||||
layout->addWidget (representative);
|
||||
layout->addStretch ();
|
||||
layout->addWidget (block);
|
||||
layout->addWidget (status);
|
||||
layout->addWidget (create);
|
||||
layout->addWidget (back);
|
||||
window->setLayout (layout);
|
||||
QObject::connect (send, &QRadioButton::toggled, [this] ()
|
||||
|
@ -697,6 +706,27 @@ client (client_a)
|
|||
activate_change ();
|
||||
}
|
||||
});
|
||||
QObject::connect (create, &QPushButton::released, [this] ()
|
||||
{
|
||||
switch (group->checkedId ())
|
||||
{
|
||||
case 0:
|
||||
create_send ();
|
||||
break;
|
||||
case 1:
|
||||
create_receive ();
|
||||
break;
|
||||
case 2:
|
||||
create_change ();
|
||||
break;
|
||||
case 3:
|
||||
create_open ();
|
||||
break;
|
||||
default:
|
||||
assert (false);
|
||||
break;
|
||||
}
|
||||
});
|
||||
QObject::connect (back, &QPushButton::released, [this] ()
|
||||
{
|
||||
client.pop_main_stack ();
|
||||
|
@ -748,4 +778,245 @@ void rai_qt::block_creation::activate_change ()
|
|||
account->show ();
|
||||
representative_label->show ();
|
||||
representative->show ();
|
||||
}
|
||||
|
||||
void rai_qt::block_creation::create_send ()
|
||||
{
|
||||
rai::account account_l;
|
||||
auto error (account_l.decode_hex (account->text ().toStdString ()));
|
||||
if (!error)
|
||||
{
|
||||
rai::amount amount_l;
|
||||
error = account_l.decode_hex (amount->text ().toStdString ());
|
||||
if (!error)
|
||||
{
|
||||
rai::account destination_l;
|
||||
error = destination_l.decode_hex (destination->text ().toStdString ());
|
||||
if (!error)
|
||||
{
|
||||
rai::private_key key;
|
||||
if (client.client_m.wallet.fetch (account_l, key))
|
||||
{
|
||||
auto balance (client.client_m.ledger.account_balance (account_l));
|
||||
if (amount_l.number () <= balance)
|
||||
{
|
||||
rai::frontier frontier;
|
||||
auto error (client.client_m.store.latest_get (account_l, frontier));
|
||||
assert (!error);
|
||||
rai::send_block send;
|
||||
send.hashables.destination = destination_l;
|
||||
send.hashables.previous = frontier.hash;
|
||||
send.hashables.balance = rai::amount (balance - amount_l.number ());
|
||||
rai::sign_message (key, account_l, send.hash (), send.signature);
|
||||
key.clear ();
|
||||
send.work = client.client_m.ledger.create_work (send);
|
||||
std::string block_l;
|
||||
send.serialize_json (block_l);
|
||||
block->setPlainText (QString (block_l.c_str ()));
|
||||
status->setStyleSheet ("QLabel { color: black }");
|
||||
status->setText ("Created block");
|
||||
}
|
||||
else
|
||||
{
|
||||
status->setStyleSheet ("QLabel { color: red }");
|
||||
status->setText ("Insufficient balance");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status->setStyleSheet ("QLabel { color: red }");
|
||||
status->setText ("Account is not in wallet");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status->setStyleSheet ("QLabel { color: red }");
|
||||
status->setText ("Unable to decode destination");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status->setStyleSheet ("QLabel { color: red }");
|
||||
status->setText ("Unable to decode amount");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status->setStyleSheet ("QLabel { color: red }");
|
||||
status->setText ("Unable to decode account");
|
||||
}
|
||||
}
|
||||
|
||||
void rai_qt::block_creation::create_receive ()
|
||||
{
|
||||
rai::block_hash source_l;
|
||||
auto error (source_l.decode_hex (source->text ().toStdString ()));
|
||||
if (!error)
|
||||
{
|
||||
rai::account source;
|
||||
rai::amount amount;
|
||||
rai::account destination;
|
||||
if (!client.client_m.store.pending_get (source_l, source, amount, destination))
|
||||
{
|
||||
rai::frontier frontier;
|
||||
auto error (client.client_m.store.latest_get (destination, frontier));
|
||||
if (!error)
|
||||
{
|
||||
rai::private_key key;
|
||||
auto error (client.client_m.wallet.fetch (destination, key));
|
||||
if (!error)
|
||||
{
|
||||
rai::receive_block receive;
|
||||
receive.hashables.previous = frontier.hash;
|
||||
receive.hashables.source = source_l;
|
||||
rai::sign_message (key, destination, receive.hash (), receive.signature);
|
||||
key.clear ();
|
||||
receive.work = client.client_m.ledger.create_work (receive);
|
||||
std::string block_l;
|
||||
receive.serialize_json (block_l);
|
||||
block->setPlainText (QString (block_l.c_str ()));
|
||||
status->setStyleSheet ("QLabel { color: black }");
|
||||
status->setText ("Created block");
|
||||
}
|
||||
else
|
||||
{
|
||||
status->setStyleSheet ("QLabel { color: red }");
|
||||
status->setText ("Account is not in wallet");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status->setStyleSheet ("QLabel { color: red }");
|
||||
status->setText ("Account not yet open");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status->setStyleSheet ("QLabel { color: red }");
|
||||
status->setText ("Source block is not pending to receive");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status->setStyleSheet ("QLabel { color: red }");
|
||||
status->setText ("Unable to decode source");
|
||||
}
|
||||
}
|
||||
|
||||
void rai_qt::block_creation::create_change ()
|
||||
{
|
||||
rai::account account_l;
|
||||
auto error (account_l.decode_hex (account->text ().toStdString ()));
|
||||
if (!error)
|
||||
{
|
||||
rai::account representative_l;
|
||||
error = representative_l.decode_hex (representative->text ().toStdString ());
|
||||
if (!error)
|
||||
{
|
||||
rai::frontier frontier;
|
||||
auto error (client.client_m.store.latest_get (account_l, frontier));
|
||||
if (!error)
|
||||
{
|
||||
rai::private_key key;
|
||||
auto error (client.client_m.wallet.fetch (account_l, key));
|
||||
if (!error)
|
||||
{
|
||||
rai::change_block change (representative_l, frontier.hash, key, account_l);
|
||||
key.clear ();
|
||||
change.work = client.client_m.ledger.create_work (change);
|
||||
std::string block_l;
|
||||
change.serialize_json (block_l);
|
||||
block->setPlainText (QString (block_l.c_str ()));
|
||||
status->setStyleSheet ("QLabel { color: black }");
|
||||
status->setText ("Created block");
|
||||
}
|
||||
else
|
||||
{
|
||||
status->setStyleSheet ("QLabel { color: red }");
|
||||
status->setText ("Account is not in wallet");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status->setStyleSheet ("QLabel { color: red }");
|
||||
status->setText ("Account not yet open");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status->setStyleSheet ("QLabel { color: red }");
|
||||
status->setText ("Unable to decode representative");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status->setStyleSheet ("QLabel { color: red }");
|
||||
status->setText ("Unable to decode account");
|
||||
}
|
||||
}
|
||||
|
||||
void rai_qt::block_creation::create_open ()
|
||||
{
|
||||
rai::block_hash source_l;
|
||||
auto error (source_l.decode_hex (source->text ().toStdString ()));
|
||||
if (!error)
|
||||
{
|
||||
rai::account representative_l;
|
||||
error = representative_l.decode_hex (representative->text ().toStdString ());
|
||||
if (!error)
|
||||
{
|
||||
rai::account source;
|
||||
rai::amount amount;
|
||||
rai::account destination;
|
||||
if (!client.client_m.store.pending_get (source_l, source, amount, destination))
|
||||
{
|
||||
rai::frontier frontier;
|
||||
auto error (client.client_m.store.latest_get (destination, frontier));
|
||||
if (error)
|
||||
{
|
||||
rai::private_key key;
|
||||
auto error (client.client_m.wallet.fetch (destination, key));
|
||||
if (!error)
|
||||
{
|
||||
rai::open_block open;
|
||||
open.hashables.source = source_l;
|
||||
open.hashables.representative = representative_l;
|
||||
rai::sign_message (key, destination, open.hash (), open.signature);
|
||||
key.clear ();
|
||||
open.work = client.client_m.ledger.create_work (open);
|
||||
std::string block_l;
|
||||
open.serialize_json (block_l);
|
||||
block->setPlainText (QString (block_l.c_str ()));
|
||||
status->setStyleSheet ("QLabel { color: black }");
|
||||
status->setText ("Created block");
|
||||
}
|
||||
else
|
||||
{
|
||||
status->setStyleSheet ("QLabel { color: red }");
|
||||
status->setText ("Account is not in wallet");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status->setStyleSheet ("QLabel { color: red }");
|
||||
status->setText ("Account already open");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status->setStyleSheet ("QLabel { color: red }");
|
||||
status->setText ("Source block is not pending to receive");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status->setStyleSheet ("QLabel { color: red }");
|
||||
status->setText ("Unable to decode representative");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status->setStyleSheet ("QLabel { color: red }");
|
||||
status->setText ("Unable to decode source");
|
||||
}
|
||||
}
|
|
@ -103,6 +103,10 @@ namespace rai_qt {
|
|||
void activate_receive ();
|
||||
void activate_change ();
|
||||
void activate_open ();
|
||||
void create_send ();
|
||||
void create_receive ();
|
||||
void create_change ();
|
||||
void create_open ();
|
||||
QWidget * window;
|
||||
QVBoxLayout * layout;
|
||||
QButtonGroup * group;
|
||||
|
@ -121,6 +125,9 @@ namespace rai_qt {
|
|||
QLineEdit * destination;
|
||||
QLabel * representative_label;
|
||||
QLineEdit * representative;
|
||||
QPlainTextEdit * block;
|
||||
QLabel * status;
|
||||
QPushButton * create;
|
||||
QPushButton * back;
|
||||
rai_qt::client & client;
|
||||
};
|
||||
|
|
|
@ -623,22 +623,33 @@ void rai::uint256_union::encode_hex (std::string & text) const
|
|||
|
||||
bool rai::uint256_union::decode_hex (std::string const & text)
|
||||
{
|
||||
auto result (text.size () > 64);
|
||||
if (!result)
|
||||
auto result (false);
|
||||
if (!text.empty ())
|
||||
{
|
||||
std::stringstream stream (text);
|
||||
stream << std::hex << std::noshowbase;
|
||||
rai::uint256_t number_l;
|
||||
try
|
||||
if (text.size () <= 64)
|
||||
{
|
||||
stream >> number_l;
|
||||
*this = number_l;
|
||||
std::stringstream stream (text);
|
||||
stream << std::hex << std::noshowbase;
|
||||
rai::uint256_t number_l;
|
||||
try
|
||||
{
|
||||
stream >> number_l;
|
||||
*this = number_l;
|
||||
}
|
||||
catch (std::runtime_error &)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
catch (std::runtime_error &)
|
||||
else
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1207,6 +1218,12 @@ work (work_a)
|
|||
rai::sign_message (prv_a, pub_a, hash (), signature);
|
||||
}
|
||||
|
||||
rai::change_block::change_block (rai::account const & representative_a, rai::block_hash const & previous_a, rai::private_key const & prv_a, rai::public_key const & pub_a) :
|
||||
hashables (representative_a, previous_a)
|
||||
{
|
||||
rai::sign_message (prv_a, pub_a, hash (), signature);
|
||||
}
|
||||
|
||||
rai::change_block::change_block (bool & error_a, rai::stream & stream_a) :
|
||||
hashables (error_a, stream_a)
|
||||
{
|
||||
|
|
|
@ -289,6 +289,7 @@ namespace rai
|
|||
{
|
||||
public:
|
||||
change_block (rai::account const &, rai::block_hash const &, uint64_t, rai::private_key const &, rai::public_key const &);
|
||||
change_block (rai::account const &, rai::block_hash const &, rai::private_key const &, rai::public_key const &);
|
||||
change_block (bool &, rai::stream &);
|
||||
change_block (bool &, boost::property_tree::ptree const &);
|
||||
using rai::block::hash;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue