Initial cut at manually creating blocks.

This commit is contained in:
clemahieu 2014-11-29 17:29:18 -06:00
commit 06364f5ff2
8 changed files with 321 additions and 10 deletions

View file

@ -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 ()))
{

View file

@ -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 &);

View file

@ -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));

View file

@ -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;

View file

@ -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");
}
}

View file

@ -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;
};

View file

@ -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)
{

View file

@ -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;