BitShares-Core  6.1.0
BitShares blockchain implementation and command-line interface software
operation_printer.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Cryptonomex, Inc., and contributors.
3  *
4  * The MIT License
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #include "operation_printer.hpp"
26 #include "wallet_api_impl.hpp"
28 
29 namespace graphene { namespace wallet { namespace detail {
30 
32 {
33 public:
34  typedef std::string result_type;
35 
36  result_type operator()( const fc::ripemd160& hash )const
37  {
38  return "RIPEMD160 " + hash.str();
39  }
40 
41  result_type operator()( const fc::sha1& hash )const
42  {
43  return "SHA1 " + hash.str();
44  }
45 
46  result_type operator()( const fc::sha256& hash )const
47  {
48  return "SHA256 " + hash.str();
49  }
50  result_type operator()( const fc::hash160& hash )const
51  {
52  return "HASH160 " + hash.str();
53  }
54 };
55 
56 std::string operation_printer::format_asset(const graphene::protocol::asset& a)const
57 {
58  return wallet.get_asset(a.asset_id).amount_to_pretty_string(a);
59 }
60 
61 void operation_printer::print_fee(const graphene::protocol::asset& a)const
62 {
63  out << " (Fee: " << format_asset(a) << ")";
64 }
65 
67 {
68  operation_result_printer rprinter(wallet);
69  std::string str_result = result.visit(rprinter);
70  if( str_result != "" )
71  {
72  out << " result: " << str_result;
73  }
74 }
75 
77 {
78  std::string outstr;
79  if( memo )
80  {
81  if( wallet.is_locked() )
82  {
83  out << " -- Unlock wallet to see memo.";
84  } else {
85  try {
86  FC_ASSERT( wallet._keys.count(memo->to) > 0 || wallet._keys.count(memo->from) > 0,
87  "Memo is encrypted to a key ${to} or ${from} not in this wallet.",
88  ("to", memo->to)("from",memo->from) );
89  if( wallet._keys.count(memo->to) > 0 ) {
90  auto my_key = wif_to_key(wallet._keys.at(memo->to));
91  FC_ASSERT(my_key, "Unable to recover private key to decrypt memo. Wallet may be corrupted.");
92  outstr = memo->get_message(*my_key, memo->from);
93  out << " -- Memo: " << outstr;
94  } else {
95  auto my_key = wif_to_key(wallet._keys.at(memo->from));
96  FC_ASSERT(my_key, "Unable to recover private key to decrypt memo. Wallet may be corrupted.");
97  outstr = memo->get_message(*my_key, memo->to);
98  out << " -- Memo: " << outstr;
99  }
100  } catch (const fc::exception& e) {
101  out << " -- could not decrypt memo";
102  }
103  }
104  }
105  return outstr;
106 }
107 
108 void operation_printer::print_preimage(const std::vector<char>& preimage)const
109 {
110  if (preimage.size() == 0)
111  return;
112  out << " with preimage \"";
113  // cut it at 300 bytes max
114  auto flags = out.flags();
115  out << std::hex << setw(2) << setfill('0');
116  for (size_t i = 0; i < std::min<size_t>(300, preimage.size()); i++)
117  out << +preimage[i];
118  out.flags(flags);
119  if (preimage.size() > 300)
120  out << "...(truncated due to size)";
121  out << "\"";
122 }
123 
124 void operation_printer::print_redeem(const graphene::protocol::htlc_id_type& id,
125  const std::string& redeemer, const std::vector<char>& preimage,
126  const graphene::protocol::asset& op_fee)const
127 {
128  out << redeemer << " redeemed HTLC with id "
129  << std::string( static_cast<object_id_type>(id));
130  print_preimage( preimage );
131  print_fee(op_fee);
132 }
133 
135 {
136  auto receiver = wallet.get_account( op.to );
137 
138  out << receiver.name
139  << " received " << format_asset( op.amount ) << " from blinded balance";
140  return "";
141 }
143 {
144  auto sender = wallet.get_account( op.from );
145 
146  out << sender.name
147  << " sent " << format_asset( op.amount ) << " to " << op.outputs.size()
148  << " blinded balance" << (op.outputs.size()>1?"s":"");
149  print_fee( op.fee );
150  return "";
151 }
152 
154 {
155  out << "Transfer " << format_asset(op.amount)
156  << " from " << wallet.get_account(op.from).name << " to " << wallet.get_account(op.to).name;
157  std::string memo = print_memo( op.memo );
158  print_fee(op.fee);
159  return memo;
160 }
161 
163 {
164  out << wallet.get_account(op.issuer).name
165  << " force-transfer " << format_asset(op.amount)
166  << " from " << wallet.get_account(op.from).name << " to " << wallet.get_account(op.to).name;
167  std::string memo = print_memo( op.memo );
168  print_fee(op.fee);
169  return memo;
170 }
171 
173 {
174  out << "Create Account '" << op.name << "' with registrar "
175  << wallet.get_account(op.registrar).name << " and referrer "
176  << wallet.get_account(op.referrer).name;
177  print_fee(op.fee);
178  print_result();
179  return "";
180 }
181 
183 {
184  out << "Update Account '" << wallet.get_account(op.account).name << "'";
185  print_fee(op.fee);
186  return "";
187 }
188 
190 {
191  out << "Create ";
192  if( op.bitasset_opts.valid() )
193  out << "BitAsset ";
194  else
195  out << "User-Issue Asset ";
196  out << "'" << op.symbol << "' with issuer " << wallet.get_account(op.issuer).name;
197  print_fee(op.fee);
198  print_result();
199  return "";
200 }
201 
203 {
204  out << "Update asset '" << wallet.get_asset(op.asset_to_update).symbol << "'";
205  print_fee(op.fee);
206  return "";
207 }
208 
210 {
211  out << "Update bitasset options of '" << wallet.get_asset(op.asset_to_update).symbol << "'";
212  print_fee(op.fee);
213  return "";
214 }
215 
217 {
218  out << wallet.get_account(op.issuer).name
219  << " issue " << format_asset(op.asset_to_issue)
220  << " to " << wallet.get_account(op.issue_to_account).name;
221  std::string memo = print_memo( op.memo );
222  print_fee(op.fee);
223  return memo;
224 }
225 
227 {
228  out << "Reserve (burn) " << format_asset(op.amount_to_reserve);
229  print_fee(op.fee);
230  return "";
231 }
232 
234 {
235  out << "Force-settle " << format_asset(op.amount);
236  print_fee(op.fee);
237  print_result();
238  return "";
239 }
240 
242 {
243  out << "Fund " << format_asset(op.amount) << " into asset fee pool of "
244  << wallet.get_asset(op.asset_id).symbol;
245  print_fee(op.fee);
246  print_result();
247  return "";
248 }
249 
251 {
252  out << "Claim " << format_asset(op.amount_to_claim) << " from asset fee pool of "
253  << wallet.get_asset(op.asset_id).symbol;
254  print_fee(op.fee);
255  print_result();
256  return "";
257 }
258 
260 {
261  out << "Update price feed producers of asset " << wallet.get_asset(op.asset_to_update).symbol
262  << " to ";
263  vector<string> accounts;
264  accounts.reserve( op.new_feed_producers.size() );
265  for( const auto& account_id : op.new_feed_producers )
266  {
267  accounts.push_back( wallet.get_account( account_id ).name );
268  }
269  out << fc::json::to_string(accounts);
270  print_fee(op.fee);
271  print_result();
272  return "";
273 }
274 
276 {
277  // TODO prettify the price
278  out << "Publish price feed " << format_asset(op.feed.settlement_price.base)
279  << " / " << format_asset(op.feed.settlement_price.quote);
280  print_fee(op.fee);
281  print_result();
282  return "";
283 }
284 
286 {
287  out << "Adjust debt position with delta debt amount " << format_asset(op.delta_debt)
288  << " and delta collateral amount " << format_asset(op.delta_collateral);
289  print_fee(op.fee);
290  print_result();
291  return "";
292 }
293 
295 {
296  out << "Create limit order to sell " << format_asset(op.amount_to_sell)
297  << " for " << format_asset(op.min_to_receive);
298  print_fee(op.fee);
299  print_result();
300  return "";
301 }
302 
304 {
305  out << "Cancel limit order " << std::string( static_cast<object_id_type>(op.order) );
306  print_fee(op.fee);
307  print_result();
308  return "";
309 }
310 
312 {
313  out << "Pays " << format_asset(op.pays) << " for " << format_asset(op.receives)
314  << " for order " << std::string( static_cast<object_id_type>(op.order_id) )
315  << " as " << ( op.is_maker ? "maker" : "taker" );
316  print_fee(op.fee);
317  print_result();
318  return "";
319 }
320 
322 {
323  out << "Update proposal " << std::string( static_cast<object_id_type>(op.proposal) );
324  print_fee(op.fee);
325  return "";
326 }
327 
329 {
330  print_redeem(op.htlc_id, wallet.get_account(op.redeemer).name, op.preimage, op.fee);
331  return "";
332 }
333 
335 {
336  print_redeem(op.htlc_id, wallet.get_account(op.redeemer).name, op.preimage, op.fee);
337  return "";
338 }
339 
341 {
342  static htlc_hash_to_string_visitor vtor;
343 
344  auto fee_asset = wallet.get_asset( op.fee.asset_id );
345  auto to = wallet.get_account( op.to );
346  auto from = wallet.get_account( op.from );
347  operation_result_printer rprinter(wallet);
348  std::string database_id = result.visit(rprinter);
349 
350  out << "Create HTLC from " << from.name << " to " << to.name
351  << " with id " << database_id
352  << " preimage hash: [" << op.preimage_hash.visit( vtor ) << "] ";
353  print_memo( op.extensions.value.memo );
354  // determine if the block that the HTLC is in is before or after LIB
355  int32_t pending_blocks = hist.block_num - wallet.get_dynamic_global_properties().last_irreversible_block_num;
356  if (pending_blocks > 0)
357  out << " (pending " << std::to_string(pending_blocks) << " blocks)";
358  print_fee(op.fee);
359  return "";
360 }
361 
363 {
364  return "";
365 }
366 
368 {
369  return std::string(oid);
370 }
371 
372 std::string operation_result_printer::operator()(const asset& a) const
373 {
374  return _wallet.get_asset(a.asset_id).amount_to_pretty_string(a);
375 }
376 
378 {
379  return fc::json::to_string(r);
380 }
381 
383 {
384  // TODO show pretty amounts instead of raw json
385  return fc::json::to_string(r);
386 }
387 
389 {
390  // TODO show pretty amounts instead of raw json
391  return fc::json::to_string(r);
392 }
393 
394 }}} // graphene::wallet::detail
static string to_string(const variant &v, output_formatting format=stringify_large_ints_and_doubles, uint32_t max_depth=DEFAULT_MAX_RECURSION_DEPTH)
Definition: json.cpp:650
account_id_type registrar
This account pays the fee. Must be a lifetime member.
Definition: account.hpp:100
std::string str() const
Definition: sha1.cpp:18
Update the set of feed-producing accounts for a BitAssetBitAssets have price feeds selected by taking...
Definition: asset_ops.hpp:430
result_type operator()(const fc::sha256 &hash) const
account_id_type from
Account to transfer asset from.
Definition: transfer.hpp:87
string str() const
Definition: hash160.cpp:46
asset amount
Amount of asset to force settle. This must be a market-issued asset.
Definition: asset_ops.hpp:283
Definition: api.cpp:48
fc::optional< fc::ecc::private_key > wif_to_key(const std::string &wif_key)
std::string operator()(const T &op) const
std::string print_memo(const fc::optional< graphene::protocol::memo_data > &memo) const
Update an existing account.
Definition: account.hpp:136
Used to generate a useful error report when an exception is thrown.At each level in the stack where t...
Definition: exception.hpp:56
Schedules a market-issued asset for automatic settlementHolders of market-issued assests may request ...
Definition: asset_ops.hpp:267
result_type operator()(const fc::ripemd160 &hash) const
std::string get_message(const fc::ecc::private_key &priv, const fc::ecc::public_key &pub) const
Definition: memo.cpp:61
visitor::result_type visit(visitor &v)
asset delta_collateral
the amount of collateral to add to the margin position
Definition: market.hpp:127
Publish price feeds for market-issued assetsPrice feed providers use this operation to publish their ...
Definition: asset_ops.hpp:462
Allows the issuer of an asset to transfer an asset from any account to any account if they have overr...
Definition: transfer.hpp:77
extension< additional_options_type > extensions
Definition: htlc.hpp:72
asset amount
The amount of asset to transfer from from to to.
Definition: transfer.hpp:91
public_key_type to
Definition: memo.hpp:43
string symbol
The ticker symbol of this asset.
Definition: asset_ops.hpp:205
used to take an asset out of circulation, returning to the issuer
Definition: asset_ops.hpp:513
Transfers an amount of one asset from one account to another.
Definition: transfer.hpp:45
Converts blinded/stealth balance to a public account balance.
account_id_type referrer
This account receives a portion of the fee split between registrar and referrer. Must be a member...
Definition: account.hpp:103
instructs the blockchain to attempt to sell one asset for anotherThe blockchain will atempt to sell a...
Definition: market.hpp:48
Update options specific to BitAssetsBitAssets have some options which are not relevant to other asset...
Definition: asset_ops.hpp:398
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
optional< memo_data > memo
User provided data encrypted to the memo key of the "to" account.
Definition: transfer.hpp:94
std::string operator()(const graphene::protocol::void_result &x) const
account_id_type issuer
Must be asset_to_issue->asset_id->issuer.
Definition: asset_ops.hpp:493
Update options common to all assetsThere are a number of options which all assets in the network use...
Definition: asset_ops.hpp:351
string str() const
Definition: ripemd160.cpp:21
result_type operator()(const fc::sha1 &hash) const
account_id_type issuer
This account must sign and pay the fee for this operation. Later, this account may update the asset...
Definition: asset_ops.hpp:203
optional< memo_data > memo
User provided data encrypted to the memo key of the "to" account.
Definition: transfer.hpp:61
Transfers BTS from the fee pool of a specified asset back to the issuer&#39;s balance.
Definition: asset_ops.hpp:601
void print_redeem(const graphene::protocol::htlc_id_type &id, const std::string &redeemer, const std::vector< char > &preimage, const graphene::protocol::asset &op_fee) const
account_id_type to
Account to transfer asset to.
Definition: transfer.hpp:89
account_id_type account
The account to update.
Definition: account.hpp:153
void print_preimage(const std::vector< char > &preimage) const
asset amount
The amount of asset to transfer from from to to.
Definition: transfer.hpp:58
std::string to_string(double)
Definition: string.cpp:73
asset delta_debt
the amount of the debt to be paid off, may be negative to issue new debt
Definition: market.hpp:128
asset_id_type asset_id
Definition: asset.hpp:37
The proposal_update_operation updates an existing transaction proposalThis operation allows accounts ...
Definition: proposal.hpp:119
optional< bitasset_options > bitasset_opts
Options only available for BitAssets. MUST be non-null if and only if the asset is market-issued...
Definition: asset_ops.hpp:217
account_id_type from
Account to transfer asset from.
Definition: transfer.hpp:54
string str() const
Definition: sha256.cpp:24
asset amount_to_claim
fee.asset_id must != asset_id
Definition: asset_ops.hpp:610
result_type operator()(const fc::hash160 &hash) const
public_key_type from
Definition: memo.hpp:42
account_id_type to
Account to transfer asset to.
Definition: transfer.hpp:56
Converts public account balance to a blinded or stealth balance.