Fix for failing Unit tests

This commit is contained in:
Meheboob Khan 2022-08-24 19:55:08 +02:00
parent 34df0c0754
commit 28df2e744d
2 changed files with 613 additions and 18 deletions

View file

@ -134,6 +134,8 @@ public:
std::string operator()(const T& op)const;
std::string operator()(const transfer_operation& op)const;
std::string operator()(const transfer_from_blind_operation& op)const;
std::string operator()(const transfer_to_blind_operation& op)const;
std::string operator()(const account_create_operation& op)const;
std::string operator()(const account_update_operation& op)const;
std::string operator()(const asset_create_operation& op)const;
@ -2156,8 +2158,8 @@ public:
return sign_transaction( tx, broadcast );
} FC_CAPTURE_AND_RETHROW( (owner_account)(url)(block_signing_key)(broadcast) ) }
signed_transaction activate_deregistered_son(const string & owner_account,
bool broadcast /* = false */)
signed_transaction activate_deregistered_son(const string & owner_account,
bool broadcast /* = false */)
{ try {
son_object son = get_son(owner_account);
@ -2406,7 +2408,7 @@ public:
op.sidechain = sidechain;
op.peerplays_uid = peerplays_uid;
op.peerplays_transaction_id = peerplays_transaction_id;
op.peerplays_from = peerplays_from;
op.peerplays_from = peerplays_from;
op.peerplays_asset = asset(asset_val.amount * asset_price.base.amount / asset_price.quote.amount);
op.withdraw_sidechain = withdraw_sidechain;
op.withdraw_address = withdraw_address;
@ -2857,9 +2859,11 @@ public:
{
account_id_type son_owner_account_id = get_account_id(son);
fc::optional<son_object> son_obj = _remote_db->get_son_by_account_id(son_owner_account_id);
if (!son_obj)
FC_THROW("Account ${son} is not registered as a SON", ("son", son));
auto insert_result = voting_account_object.options.votes.insert(son_obj->vote_id);
dlog("Approving son account ${son}", ("son", son));
if (!insert_result.second)
FC_THROW("Account ${account} was already voting for SON ${son}", ("account", voting_account)("son", son));
}
@ -2870,13 +2874,16 @@ public:
if (!son_obj)
FC_THROW("Account ${son} is not registered as a SON", ("son", son));
unsigned votes_removed = voting_account_object.options.votes.erase(son_obj->vote_id);
dlog("Rejecting son account ${son}", ("son", son));
dlog("votes_removed ${votes_removed}", ("votes_removed", votes_removed));
if (!votes_removed)
FC_THROW("Account ${account} is already not voting for SON ${son}", ("account", voting_account)("son", son));
}
voting_account_object.options.extensions.value.num_son = desired_number_of_sons;
voting_account_object.options.num_son = desired_number_of_sons;
dlog("desired_number_of_sons = ${desired_number_of_sons}", ("desired_number_of_sons", desired_number_of_sons));
account_update_operation account_update_op;
account_update_op.account = voting_account_object.id;
dlog("account_update_op.account = ${account_update_op.account}", ("account_update_op.account", account_update_op.account));
account_update_op.new_options = voting_account_object.options;
signed_transaction tx;
@ -3470,6 +3477,70 @@ public:
return ss.str();
};
m["get_blind_balances"] = [this](variant result, const fc::variants& a)
{
auto r = result.as<vector<asset>>( GRAPHENE_MAX_NESTED_OBJECTS );
vector<asset_object> asset_recs;
std::transform(r.begin(), r.end(), std::back_inserter(asset_recs), [this](const asset& a) {
return get_asset(a.asset_id);
});
std::stringstream ss;
for( unsigned i = 0; i < asset_recs.size(); ++i )
ss << asset_recs[i].amount_to_pretty_string(r[i]) << "\n";
return ss.str();
};
m["transfer_to_blind"] = [this](variant result, const fc::variants& a)
{
auto r = result.as<blind_confirmation>( GRAPHENE_MAX_NESTED_OBJECTS );
std::stringstream ss;
r.trx.operations[0].visit( operation_printer( ss, *this, operation_result() ) );
ss << "\n";
for( const auto& out : r.outputs )
{
asset_object a = get_asset( out.decrypted_memo.amount.asset_id );
ss << a.amount_to_pretty_string( out.decrypted_memo.amount ) << " to " << out.label << "\n\t receipt: " << out.confirmation_receipt <<"\n\n";
}
return ss.str();
};
m["blind_transfer"] = [this](variant result, const fc::variants& a)
{
auto r = result.as<blind_confirmation>( GRAPHENE_MAX_NESTED_OBJECTS );
std::stringstream ss;
r.trx.operations[0].visit( operation_printer( ss, *this, operation_result() ) );
ss << "\n";
for( const auto& out : r.outputs )
{
asset_object a = get_asset( out.decrypted_memo.amount.asset_id );
ss << a.amount_to_pretty_string( out.decrypted_memo.amount ) << " to " << out.label << "\n\t receipt: " << out.confirmation_receipt <<"\n\n";
}
return ss.str();
};
m["receive_blind_transfer"] = [this](variant result, const fc::variants& a)
{
auto r = result.as<blind_receipt>( GRAPHENE_MAX_NESTED_OBJECTS );
std::stringstream ss;
asset_object as = get_asset( r.amount.asset_id );
ss << as.amount_to_pretty_string( r.amount ) << " " << r.from_label << " => " << r.to_label << " " << r.memo <<"\n";
return ss.str();
};
m["blind_history"] = [this](variant result, const fc::variants& a)
{
auto records = result.as<vector<blind_receipt>>( GRAPHENE_MAX_NESTED_OBJECTS );
std::stringstream ss;
ss << "WHEN "
<< " " << "AMOUNT" << " " << "FROM" << " => " << "TO" << " " << "MEMO" <<"\n";
ss << "====================================================================================\n";
for( auto& r : records )
{
asset_object as = get_asset( r.amount.asset_id );
ss << fc::get_approximate_relative_time_string( r.date )
<< " " << as.amount_to_pretty_string( r.amount ) << " " << r.from_label << " => " << r.to_label << " " << r.memo <<"\n";
}
return ss.str();
};
m["get_upcoming_tournaments"] = m["get_tournaments"] = m["get_tournaments_by_state"] = [this](variant result, const fc::variants& a)
{
const vector<tournament_object> tournaments = result.as<vector<tournament_object> >( GRAPHENE_MAX_NESTED_OBJECTS );
@ -4330,6 +4401,26 @@ std::string operation_printer::operator()(const T& op)const
out << " result: " << str_result;
return "";
}
std::string operation_printer::operator()(const transfer_from_blind_operation& op)const
{
auto a = wallet.get_asset( op.fee.asset_id );
auto receiver = wallet.get_account( op.to );
out << receiver.name
<< " received " << a.amount_to_pretty_string( op.amount ) << " from blinded balance";
return "";
}
std::string operation_printer::operator()(const transfer_to_blind_operation& op)const
{
auto fa = wallet.get_asset( op.fee.asset_id );
auto a = wallet.get_asset( op.amount.asset_id );
auto sender = wallet.get_account( op.from );
out << sender.name
<< " sent " << a.amount_to_pretty_string( op.amount ) << " to " << op.outputs.size() << " blinded balance" << (op.outputs.size()>1?"s":"")
<< " fee: " << fa.amount_to_pretty_string( op.fee );
return "";
}
string operation_printer::operator()(const transfer_operation& op) const
{
out << "Transfer " << wallet.get_asset(op.amount.asset_id).amount_to_pretty_string(op.amount)
@ -5324,7 +5415,7 @@ signed_transaction wallet_api::sidechain_withdrawal_transaction(const string &so
const string &withdraw_amount)
{
return my->sidechain_withdrawal_transaction(son_name_or_id,
block_num,
block_num,
sidechain,
peerplays_uid,
peerplays_transaction_id,
@ -5454,7 +5545,7 @@ signed_transaction wallet_api::sidechain_deposit_transaction( const string &son
const string &peerplays_from_name_or_id,
const string &peerplays_to_name_or_id)
{
return my->sidechain_deposit_transaction(son_name_or_id,
return my->sidechain_deposit_transaction(son_name_or_id,
sidechain,
transaction_id,
operation_index,
@ -6100,6 +6191,495 @@ bool wallet_api::set_key_label( public_key_type key, string label
}
return false;
}
map<string,public_key_type> wallet_api::get_blind_accounts()const
{
map<string,public_key_type> result;
for( const auto& item : my->_wallet.labeled_keys )
result[item.label] = item.key;
return result;
}
map<string,public_key_type> wallet_api::get_my_blind_accounts()const
{
FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" );
map<string,public_key_type> result;
for( const auto& item : my->_wallet.labeled_keys )
{
if( my->_keys.find(item.key) != my->_keys.end() )
result[item.label] = item.key;
}
return result;
}
public_key_type wallet_api::create_blind_account( string label, string brain_key )
{
FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" );
auto label_itr = my->_wallet.labeled_keys.get<by_label>().find(label);
if( label_itr != my->_wallet.labeled_keys.get<by_label>().end() )
FC_ASSERT( !"Key with label already exists" );
brain_key = fc::trim_and_normalize_spaces( brain_key );
auto secret = fc::sha256::hash( brain_key.c_str(), brain_key.size() );
auto priv_key = fc::ecc::private_key::regenerate( secret );
public_key_type pub_key = priv_key.get_public_key();
FC_ASSERT( set_key_label( pub_key, label ) );
my->_keys[pub_key] = graphene::utilities::key_to_wif( priv_key );
save_wallet_file();
return pub_key;
}
vector<asset> wallet_api::get_blind_balances( string key_or_label )
{
vector<asset> result;
map<asset_id_type, share_type> balances;
vector<commitment_type> used;
auto pub_key = get_public_key( key_or_label );
auto& to_asset_used_idx = my->_wallet.blind_receipts.get<by_to_asset_used>();
auto start = to_asset_used_idx.lower_bound( std::make_tuple(pub_key,asset_id_type(0),false) );
auto end = to_asset_used_idx.lower_bound( std::make_tuple(pub_key,asset_id_type(uint32_t(0xffffffff)),true) );
while( start != end )
{
if( !start->used )
{
auto answer = my->_remote_db->get_blinded_balances( {start->commitment()} );
if( answer.size() )
balances[start->amount.asset_id] += start->amount.amount;
else
used.push_back( start->commitment() );
}
++start;
}
for( const auto& u : used )
{
auto itr = my->_wallet.blind_receipts.get<by_commitment>().find( u );
my->_wallet.blind_receipts.modify( itr, []( blind_receipt& r ){ r.used = true; } );
}
for( auto item : balances )
result.push_back( asset( item.second, item.first ) );
return result;
}
blind_confirmation wallet_api::transfer_from_blind( string from_blind_account_key_or_label,
string to_account_id_or_name,
string amount_in,
string symbol,
bool broadcast )
{ try {
transfer_from_blind_operation from_blind;
auto fees = my->_remote_db->get_global_properties().parameters.current_fees;
fc::optional<asset_object> asset_obj = get_asset(symbol);
FC_ASSERT(asset_obj.valid(), "Could not find asset matching ${asset}", ("asset", symbol));
auto amount = asset_obj->amount_from_string(amount_in);
from_blind.fee = fees->calculate_fee( from_blind, asset_obj->options.core_exchange_rate );
auto blind_in = asset_obj->amount_to_string( from_blind.fee + amount );
auto conf = blind_transfer_help( from_blind_account_key_or_label,
from_blind_account_key_or_label,
blind_in, symbol, false, true/*to_temp*/ );
FC_ASSERT( conf.outputs.size() > 0 );
auto to_account = my->get_account( to_account_id_or_name );
from_blind.to = to_account.id;
from_blind.amount = amount;
from_blind.blinding_factor = conf.outputs.back().decrypted_memo.blinding_factor;
from_blind.inputs.push_back( {conf.outputs.back().decrypted_memo.commitment, authority() } );
from_blind.fee = fees->calculate_fee( from_blind, asset_obj->options.core_exchange_rate );
idump( (from_blind) );
conf.trx.operations.push_back(from_blind);
ilog( "about to validate" );
conf.trx.validate();
if( broadcast && conf.outputs.size() == 2 ) {
// Save the change
blind_confirmation::output conf_output;
blind_confirmation::output change_output = conf.outputs[0];
// The wallet must have a private key for confirmation.to, this is used to decrypt the memo
public_key_type from_key = get_public_key(from_blind_account_key_or_label);
conf_output.confirmation.to = from_key;
conf_output.confirmation.one_time_key = change_output.confirmation.one_time_key;
conf_output.confirmation.encrypted_memo = change_output.confirmation.encrypted_memo;
conf_output.confirmation_receipt = conf_output.confirmation;
//try {
receive_blind_transfer( conf_output.confirmation_receipt, from_blind_account_key_or_label, "@"+to_account.name );
//} catch ( ... ){}
}
ilog( "about to broadcast" );
conf.trx = sign_transaction( conf.trx, broadcast );
return conf;
} FC_CAPTURE_AND_RETHROW( (from_blind_account_key_or_label)(to_account_id_or_name)(amount_in)(symbol) ) }
blind_confirmation wallet_api::blind_transfer( string from_key_or_label,
string to_key_or_label,
string amount_in,
string symbol,
bool broadcast )
{
return blind_transfer_help( from_key_or_label, to_key_or_label, amount_in, symbol, broadcast, false );
}
blind_confirmation wallet_api::blind_transfer_help( string from_key_or_label,
string to_key_or_label,
string amount_in,
string symbol,
bool broadcast,
bool to_temp )
{
blind_confirmation confirm;
try {
FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" );
public_key_type from_key = get_public_key(from_key_or_label);
public_key_type to_key = get_public_key(to_key_or_label);
fc::optional<asset_object> asset_obj = get_asset(symbol);
FC_ASSERT(asset_obj.valid(), "Could not find asset matching ${asset}", ("asset", symbol));
blind_transfer_operation blind_tr;
blind_tr.outputs.resize(2);
auto fees = my->_remote_db->get_global_properties().parameters.current_fees;
auto amount = asset_obj->amount_from_string(amount_in);
asset total_amount = asset_obj->amount(0);
vector<fc::sha256> blinding_factors;
//auto from_priv_key = my->get_private_key( from_key );
blind_tr.fee = fees->calculate_fee( blind_tr, asset_obj->options.core_exchange_rate );
vector<commitment_type> used;
auto& to_asset_used_idx = my->_wallet.blind_receipts.get<by_to_asset_used>();
auto start = to_asset_used_idx.lower_bound( std::make_tuple(from_key,amount.asset_id,false) );
auto end = to_asset_used_idx.lower_bound( std::make_tuple(from_key,amount.asset_id,true) );
while( start != end )
{
auto result = my->_remote_db->get_blinded_balances( {start->commitment() } );
if( result.size() == 0 )
{
used.push_back( start->commitment() );
}
else
{
blind_tr.inputs.push_back({start->commitment(), start->control_authority});
blinding_factors.push_back( start->data.blinding_factor );
total_amount += start->amount;
if( total_amount >= amount + blind_tr.fee )
break;
}
++start;
}
for( const auto& u : used )
{
auto itr = my->_wallet.blind_receipts.get<by_commitment>().find( u );
my->_wallet.blind_receipts.modify( itr, []( blind_receipt& r ){ r.used = true; } );
}
FC_ASSERT( total_amount >= amount+blind_tr.fee, "Insufficent Balance", ("available",total_amount)("amount",amount)("fee",blind_tr.fee) );
auto one_time_key = fc::ecc::private_key::generate();
auto secret = one_time_key.get_shared_secret( to_key );
auto child = fc::sha256::hash( secret );
auto nonce = fc::sha256::hash( one_time_key.get_secret() );
auto blind_factor = fc::sha256::hash( child );
auto from_secret = one_time_key.get_shared_secret( from_key );
auto from_child = fc::sha256::hash( from_secret );
auto from_nonce = fc::sha256::hash( nonce );
auto change = total_amount - amount - blind_tr.fee;
fc::sha256 change_blind_factor;
fc::sha256 to_blind_factor;
if( change.amount > 0 )
{
idump(("to_blind_factor")(blind_factor) );
blinding_factors.push_back( blind_factor );
change_blind_factor = fc::ecc::blind_sum( blinding_factors, blinding_factors.size() - 1 );
wdump(("change_blind_factor")(change_blind_factor) );
}
else // change == 0
{
blind_tr.outputs.resize(1);
blind_factor = fc::ecc::blind_sum( blinding_factors, blinding_factors.size() );
idump(("to_sum_blind_factor")(blind_factor) );
blinding_factors.push_back( blind_factor );
idump(("nochange to_blind_factor")(blind_factor) );
}
fc::ecc::public_key from_pub_key = from_key;
fc::ecc::public_key to_pub_key = to_key;
blind_output to_out;
to_out.owner = to_temp ? authority() : authority( 1, public_key_type( to_pub_key.child( child ) ), 1 );
to_out.commitment = fc::ecc::blind( blind_factor, amount.amount.value );
idump(("to_out.blind")(blind_factor)(to_out.commitment) );
if( blind_tr.outputs.size() > 1 )
{
to_out.range_proof = fc::ecc::range_proof_sign( 0, to_out.commitment, blind_factor, nonce, 0, 0, amount.amount.value );
blind_output change_out;
change_out.owner = authority( 1, public_key_type( from_pub_key.child( from_child ) ), 1 );
change_out.commitment = fc::ecc::blind( change_blind_factor, change.amount.value );
change_out.range_proof = fc::ecc::range_proof_sign( 0, change_out.commitment, change_blind_factor, from_nonce, 0, 0, change.amount.value );
blind_tr.outputs[1] = change_out;
blind_confirmation::output conf_output;
conf_output.label = from_key_or_label;
conf_output.pub_key = from_key;
conf_output.decrypted_memo.from = from_key;
conf_output.decrypted_memo.amount = change;
conf_output.decrypted_memo.blinding_factor = change_blind_factor;
conf_output.decrypted_memo.commitment = change_out.commitment;
conf_output.decrypted_memo.check = from_secret._hash[0];
conf_output.confirmation.one_time_key = one_time_key.get_public_key();
conf_output.confirmation.to = from_key;
conf_output.confirmation.encrypted_memo = fc::aes_encrypt( from_secret, fc::raw::pack( conf_output.decrypted_memo ) );
conf_output.auth = change_out.owner;
conf_output.confirmation_receipt = conf_output.confirmation;
confirm.outputs.push_back( conf_output );
}
blind_tr.outputs[0] = to_out;
blind_confirmation::output conf_output;
conf_output.label = to_key_or_label;
conf_output.pub_key = to_key;
conf_output.decrypted_memo.from = from_key;
conf_output.decrypted_memo.amount = amount;
conf_output.decrypted_memo.blinding_factor = blind_factor;
conf_output.decrypted_memo.commitment = to_out.commitment;
conf_output.decrypted_memo.check = secret._hash[0];
conf_output.confirmation.one_time_key = one_time_key.get_public_key();
conf_output.confirmation.to = to_key;
conf_output.confirmation.encrypted_memo = fc::aes_encrypt( secret, fc::raw::pack( conf_output.decrypted_memo ) );
conf_output.auth = to_out.owner;
conf_output.confirmation_receipt = conf_output.confirmation;
confirm.outputs.push_back( conf_output );
/** commitments must be in sorted order */
std::sort( blind_tr.outputs.begin(), blind_tr.outputs.end(),
[&]( const blind_output& a, const blind_output& b ){ return a.commitment < b.commitment; } );
std::sort( blind_tr.inputs.begin(), blind_tr.inputs.end(),
[&]( const blind_input& a, const blind_input& b ){ return a.commitment < b.commitment; } );
confirm.trx.operations.emplace_back( std::move(blind_tr) );
ilog( "validate before" );
confirm.trx.validate();
confirm.trx = sign_transaction(confirm.trx, broadcast);
if( broadcast )
{
for( const auto& out : confirm.outputs )
{
try { receive_blind_transfer( out.confirmation_receipt, from_key_or_label, "" ); } catch ( ... ){}
}
}
return confirm;
} FC_CAPTURE_AND_RETHROW( (from_key_or_label)(to_key_or_label)(amount_in)(symbol)(broadcast)(confirm) ) }
/**
* Transfers a public balance from @from to one or more blinded balances using a
* stealth transfer.
*/
blind_confirmation wallet_api::transfer_to_blind( string from_account_id_or_name,
string asset_symbol,
/** map from key or label to amount */
vector<pair<string, string>> to_amounts,
bool broadcast )
{ try {
FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" );
idump((to_amounts));
blind_confirmation confirm;
account_object from_account = my->get_account(from_account_id_or_name);
fc::optional<asset_object> asset_obj = get_asset(asset_symbol);
FC_ASSERT(asset_obj, "Could not find asset matching ${asset}", ("asset", asset_symbol));
transfer_to_blind_operation bop;
bop.from = from_account.id;
vector<fc::sha256> blinding_factors;
asset total_amount = asset_obj->amount(0);
for( auto item : to_amounts )
{
auto one_time_key = fc::ecc::private_key::generate();
auto to_key = get_public_key( item.first );
auto secret = one_time_key.get_shared_secret( to_key );
auto child = fc::sha256::hash( secret );
auto nonce = fc::sha256::hash( one_time_key.get_secret() );
auto blind_factor = fc::sha256::hash( child );
blinding_factors.push_back( blind_factor );
auto amount = asset_obj->amount_from_string(item.second);
total_amount += amount;
fc::ecc::public_key to_pub_key = to_key;
blind_output out;
out.owner = authority( 1, public_key_type( to_pub_key.child( child ) ), 1 );
out.commitment = fc::ecc::blind( blind_factor, amount.amount.value );
if( to_amounts.size() > 1 )
out.range_proof = fc::ecc::range_proof_sign( 0, out.commitment, blind_factor, nonce, 0, 0, amount.amount.value );
blind_confirmation::output conf_output;
conf_output.label = item.first;
conf_output.pub_key = to_key;
conf_output.decrypted_memo.amount = amount;
conf_output.decrypted_memo.blinding_factor = blind_factor;
conf_output.decrypted_memo.commitment = out.commitment;
conf_output.decrypted_memo.check = secret._hash[0];
conf_output.confirmation.one_time_key = one_time_key.get_public_key();
conf_output.confirmation.to = to_key;
conf_output.confirmation.encrypted_memo = fc::aes_encrypt( secret, fc::raw::pack( conf_output.decrypted_memo ) );
conf_output.confirmation_receipt = conf_output.confirmation;
confirm.outputs.push_back( conf_output );
bop.outputs.push_back(out);
}
bop.amount = total_amount;
bop.blinding_factor = fc::ecc::blind_sum( blinding_factors, blinding_factors.size() );
/** commitments must be in sorted order */
std::sort( bop.outputs.begin(), bop.outputs.end(),
[&]( const blind_output& a, const blind_output& b ){ return a.commitment < b.commitment; } );
confirm.trx.operations.push_back( bop );
my->set_operation_fees( confirm.trx, my->_remote_db->get_global_properties().parameters.current_fees);
confirm.trx.validate();
confirm.trx = sign_transaction(confirm.trx, broadcast);
if( broadcast )
{
for( const auto& out : confirm.outputs )
{
try { receive_blind_transfer( out.confirmation_receipt, "@"+from_account.name, "from @"+from_account.name ); } catch ( ... ){}
}
}
return confirm;
} FC_CAPTURE_AND_RETHROW( (from_account_id_or_name)(asset_symbol)(to_amounts) ) }
blind_receipt wallet_api::receive_blind_transfer( string confirmation_receipt, string opt_from, string opt_memo )
{
FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" );
stealth_confirmation conf(confirmation_receipt);
FC_ASSERT( conf.to );
blind_receipt result;
result.conf = conf;
auto to_priv_key_itr = my->_keys.find( *conf.to );
FC_ASSERT( to_priv_key_itr != my->_keys.end(), "No private key for receiver", ("conf",conf) );
auto to_priv_key = wif_to_key( to_priv_key_itr->second );
FC_ASSERT( to_priv_key );
auto secret = to_priv_key->get_shared_secret( conf.one_time_key );
auto child = fc::sha256::hash( secret );
auto child_priv_key = to_priv_key->child( child );
//auto blind_factor = fc::sha256::hash( child );
auto plain_memo = fc::aes_decrypt( secret, conf.encrypted_memo );
auto memo = fc::raw::unpack<stealth_confirmation::memo_data>( plain_memo );
result.to_key = *conf.to;
result.to_label = get_key_label( result.to_key );
if( memo.from )
{
result.from_key = *memo.from;
result.from_label = get_key_label( result.from_key );
if( result.from_label == string() )
{
result.from_label = opt_from;
set_key_label( result.from_key, result.from_label );
}
}
else
{
result.from_label = opt_from;
}
result.amount = memo.amount;
result.memo = opt_memo;
// confirm the amount matches the commitment (verify the blinding factor)
auto commtiment_test = fc::ecc::blind( memo.blinding_factor, memo.amount.amount.value );
FC_ASSERT( fc::ecc::verify_sum( {commtiment_test}, {memo.commitment}, 0 ) );
blind_balance bal;
bal.amount = memo.amount;
bal.to = *conf.to;
if( memo.from ) bal.from = *memo.from;
bal.one_time_key = conf.one_time_key;
bal.blinding_factor = memo.blinding_factor;
bal.commitment = memo.commitment;
bal.used = false;
auto child_pubkey = child_priv_key.get_public_key();
auto owner = authority(1, public_key_type(child_pubkey), 1);
result.control_authority = owner;
result.data = memo;
auto child_key_itr = owner.key_auths.find( child_pubkey );
if( child_key_itr != owner.key_auths.end() )
my->_keys[child_key_itr->first] = key_to_wif( child_priv_key );
// my->_wallet.blinded_balances[memo.amount.asset_id][bal.to].push_back( bal );
result.date = fc::time_point::now();
my->_wallet.blind_receipts.insert( result );
my->_keys[child_pubkey] = key_to_wif( child_priv_key );
save_wallet_file();
return result;
}
vector<blind_receipt> wallet_api::blind_history( string key_or_account )
{
vector<blind_receipt> result;
auto pub_key = get_public_key( key_or_account );
if( pub_key == public_key_type() )
return vector<blind_receipt>();
for( auto& r : my->_wallet.blind_receipts )
{
if( r.from_key == pub_key || r.to_key == pub_key )
result.push_back( r );
}
std::sort( result.begin(), result.end(), [&]( const blind_receipt& a, const blind_receipt& b ){ return a.date > b.date; } );
return result;
}
///////////////
// peerplays //

View file

@ -39,7 +39,7 @@ public:
fixture_(fixture)
{
fixture_.init_nathan();
fixture_.generate_blocks(HARDFORK_SON3_TIME);
fixture_.generate_blocks(HARDFORK_SON_FOR_HIVE_TIME);
fixture_.generate_block();
}
@ -232,6 +232,7 @@ BOOST_AUTO_TEST_CASE( son_voting )
con.wallet_api_ptr->create_vesting_balance("nathan", "1000", "1.3.0", vesting_balance_type::gpos, true);
// Vote for a son1account
BOOST_TEST_MESSAGE("Voting for son1account");
BOOST_CHECK(generate_maintenance_block());
vote_son1_tx = con.wallet_api_ptr->vote_for_son("nathan", "son1account", true, true);
BOOST_CHECK(generate_maintenance_block());
@ -337,8 +338,7 @@ BOOST_FIXTURE_TEST_CASE( select_top_fifteen_sons, cli_fixture )
global_property_object gpo;
gpo = con.wallet_api_ptr->get_global_properties();
//! Set son number as 5 (as the begining son count)
unsigned int son_number = 5;
unsigned int son_number = gpo.parameters.maximum_son_count();
flat_map<sidechain_type, string> sidechain_public_keys;
@ -401,7 +401,7 @@ BOOST_FIXTURE_TEST_CASE( select_top_fifteen_sons, cli_fixture )
BOOST_TEST_MESSAGE("gpo: " << gpo.active_sons.size());
BOOST_CHECK(generate_maintenance_block());
BOOST_CHECK(gpo.active_sons.size() == son_number);
BOOST_CHECK(gpo.active_sons.size() == gpo.parameters.maximum_son_count());
} catch( fc::exception& e ) {
BOOST_TEST_MESSAGE("SON cli wallet tests exception");
@ -454,13 +454,20 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test )
sidechain_public_keys.clear();
sidechain_public_keys[sidechain_type::bitcoin] = "bitcoin_address 1";
BOOST_TEST_MESSAGE("sidechain_public_keys add for bitcoin account 1");
sidechain_public_keys[sidechain_type::hive] = "hive account 1";
BOOST_TEST_MESSAGE("sidechain_public_keys add for hive account 1");
sth.create_son("son1account", "http://son1", sidechain_public_keys);
BOOST_TEST_MESSAGE("created son account 1");
sidechain_public_keys.clear();
sidechain_public_keys[sidechain_type::bitcoin] = "bitcoin_address 2";
BOOST_TEST_MESSAGE("sidechain_public_keys add for bitcoin account 2");
sidechain_public_keys[sidechain_type::hive] = "hive account 2";
BOOST_TEST_MESSAGE("sidechain_public_keys add for hive account 2");
sth.create_son("son2account", "http://son2", sidechain_public_keys);
BOOST_TEST_MESSAGE("created son account 2");
BOOST_TEST_MESSAGE("Vote for 2 accounts with update_son_votes");
@ -472,13 +479,17 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test )
// Get votes at start
son1_obj = con.wallet_api_ptr->get_son("son1account");
son1_start_votes = son1_obj.total_votes;
BOOST_TEST_MESSAGE("son1_start_votes: " << son1_start_votes);
son2_obj = con.wallet_api_ptr->get_son("son2account");
son2_start_votes = son2_obj.total_votes;
BOOST_TEST_MESSAGE("son2_start_votes: " << son2_start_votes);
std::vector<std::string> accepted;
std::vector<std::string> rejected;
signed_transaction update_votes_tx;
generate_block();
BOOST_CHECK(generate_maintenance_block());
// Vote for both SONs
accepted.clear();
rejected.clear();
@ -493,10 +504,12 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test )
// Verify the votes
son1_obj = con.wallet_api_ptr->get_son("son1account");
son1_end_votes = son1_obj.total_votes;
BOOST_TEST_MESSAGE("son1_end_votes: " << son1_end_votes);
BOOST_CHECK(son1_end_votes > son1_start_votes);
son1_start_votes = son1_end_votes;
son2_obj = con.wallet_api_ptr->get_son("son2account");
son2_end_votes = son2_obj.total_votes;
BOOST_TEST_MESSAGE("son2_end_votes: " << son2_end_votes);
BOOST_CHECK(son2_end_votes > son2_start_votes);
son2_start_votes = son2_end_votes;
@ -513,18 +526,21 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test )
// Verify the votes
son1_obj = con.wallet_api_ptr->get_son("son1account");
son1_end_votes = son1_obj.total_votes;
BOOST_TEST_MESSAGE("son1_end_votes: " << son1_end_votes);
BOOST_CHECK(son1_end_votes < son1_start_votes);
son1_start_votes = son1_end_votes;
son2_obj = con.wallet_api_ptr->get_son("son2account");
// voice distribution changed, SON2 now has all voices
son2_end_votes = son2_obj.total_votes;
BOOST_TEST_MESSAGE("son2_end_votes: " << son2_end_votes);
BOOST_CHECK((son2_end_votes > son2_start_votes)); // nathan spent funds for vb, it has different voting power
son2_start_votes = son2_end_votes;
// Try to reject incorrect SON
accepted.clear();
rejected.clear();
rejected.push_back("son1accnt");
rejected.push_back("son1account");
BOOST_CHECK_THROW(update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted,
rejected, 1, true), fc::exception);
generate_block();
@ -560,8 +576,8 @@ BOOST_AUTO_TEST_CASE( update_son_votes_test )
// Try to accept and reject the same SON
accepted.clear();
rejected.clear();
rejected.push_back("son1accnt");
accepted.push_back("son1accnt");
rejected.push_back("son1account");
accepted.push_back("son1account");
BOOST_REQUIRE_THROW(update_votes_tx = con.wallet_api_ptr->update_son_votes("nathan", accepted,
rejected, 1, true), fc::exception);
BOOST_CHECK(generate_maintenance_block());
@ -645,8 +661,7 @@ BOOST_FIXTURE_TEST_CASE( cli_list_active_sons, cli_fixture )
global_property_object gpo;
gpo = con.wallet_api_ptr->get_global_properties();
//! Set son number as 5 (as the begining son count)
unsigned int son_number = 5;
unsigned int son_number = gpo.parameters.maximum_son_count();
flat_map<sidechain_type, string> sidechain_public_keys;
@ -688,7 +703,7 @@ BOOST_FIXTURE_TEST_CASE( cli_list_active_sons, cli_fixture )
map<string, son_id_type> active_sons = con.wallet_api_ptr->list_active_sons();
BOOST_CHECK(active_sons.size() == son_number);
for(unsigned int i = 1; i < son_number + 1; i++)
for(unsigned int i = 1; i < son_number; i++)
{
std::string name = "sonaccount" + fc::to_pretty_string(i);
BOOST_CHECK(active_sons.find(name) != active_sons.end());