diff --git a/libraries/chain/include/graphene/chain/protocol/son_wallet_withdraw.hpp b/libraries/chain/include/graphene/chain/protocol/son_wallet_withdraw.hpp index 7aed5dde..99c263be 100644 --- a/libraries/chain/include/graphene/chain/protocol/son_wallet_withdraw.hpp +++ b/libraries/chain/include/graphene/chain/protocol/son_wallet_withdraw.hpp @@ -14,15 +14,14 @@ namespace graphene { namespace chain { fc::time_point_sec timestamp; peerplays_sidechain::sidechain_type sidechain; - std::string sidechain_uid; - std::string sidechain_transaction_id; - std::string sidechain_from; - std::string sidechain_to; - std::string sidechain_currency; - fc::safe sidechain_amount; + std::string peerplays_uid; + std::string peerplays_transaction_id; chain::account_id_type peerplays_from; - chain::account_id_type peerplays_to; chain::asset peerplays_asset; + peerplays_sidechain::sidechain_type withdraw_sidechain; + std::string withdraw_address; + std::string withdraw_currency; + safe withdraw_amount; account_id_type fee_payer()const { return payer; } share_type calculate_fee(const fee_parameters_type& k)const { return 0; } @@ -45,7 +44,7 @@ namespace graphene { namespace chain { FC_REFLECT(graphene::chain::son_wallet_withdraw_create_operation::fee_parameters_type, (fee) ) FC_REFLECT(graphene::chain::son_wallet_withdraw_create_operation, (fee)(payer) - (timestamp) (sidechain) (sidechain_uid) (sidechain_transaction_id) (sidechain_from) (sidechain_to) (sidechain_currency) (sidechain_amount) (peerplays_from) (peerplays_to) (peerplays_asset)) + (timestamp) (sidechain) (peerplays_uid) (peerplays_transaction_id) (peerplays_from) (peerplays_asset) (withdraw_sidechain) (withdraw_address) (withdraw_currency) (withdraw_amount) ) FC_REFLECT(graphene::chain::son_wallet_withdraw_process_operation::fee_parameters_type, (fee) ) FC_REFLECT(graphene::chain::son_wallet_withdraw_process_operation, (fee)(payer) (son_wallet_withdraw_id)) diff --git a/libraries/chain/include/graphene/chain/sidechain_address_object.hpp b/libraries/chain/include/graphene/chain/sidechain_address_object.hpp index 910e5f9c..1a8b6967 100644 --- a/libraries/chain/include/graphene/chain/sidechain_address_object.hpp +++ b/libraries/chain/include/graphene/chain/sidechain_address_object.hpp @@ -34,7 +34,6 @@ namespace graphene { namespace chain { struct by_sidechain; struct by_account_and_sidechain; struct by_sidechain_and_deposit_address; - struct by_sidechain_and_withdraw_address; using sidechain_address_multi_index_type = multi_index_container< sidechain_address_object, indexed_by< @@ -58,12 +57,6 @@ namespace graphene { namespace chain { member, member > - >, - ordered_unique< tag, - composite_key, - member - > > > >; diff --git a/libraries/chain/include/graphene/chain/son_wallet_withdraw_object.hpp b/libraries/chain/include/graphene/chain/son_wallet_withdraw_object.hpp index 4b507f85..68e870e0 100644 --- a/libraries/chain/include/graphene/chain/son_wallet_withdraw_object.hpp +++ b/libraries/chain/include/graphene/chain/son_wallet_withdraw_object.hpp @@ -19,41 +19,39 @@ namespace graphene { namespace chain { time_point_sec timestamp; peerplays_sidechain::sidechain_type sidechain; int64_t confirmations; - std::string sidechain_uid; - std::string sidechain_transaction_id; - std::string sidechain_from; - std::string sidechain_to; - std::string sidechain_currency; - safe sidechain_amount; + std::string peerplays_uid; + std::string peerplays_transaction_id; chain::account_id_type peerplays_from; - chain::account_id_type peerplays_to; chain::asset peerplays_asset; - + peerplays_sidechain::sidechain_type withdraw_sidechain; + std::string withdraw_address; + std::string withdraw_currency; + safe withdraw_amount; bool processed; }; - struct by_sidechain; - struct by_sidechain_uid; + struct by_peerplays_uid; + struct by_withdraw_sidechain; struct by_processed; - struct by_sidechain_and_processed; + struct by_withdraw_sidechain_and_processed; using son_wallet_withdraw_multi_index_type = multi_index_container< son_wallet_withdraw_object, indexed_by< ordered_unique< tag, member >, - ordered_non_unique< tag, - member + ordered_unique< tag, + member >, - ordered_unique< tag, - member + ordered_non_unique< tag, + member >, ordered_non_unique< tag, member >, - ordered_non_unique< tag, + ordered_non_unique< tag, composite_key, + member, member > > @@ -64,6 +62,6 @@ namespace graphene { namespace chain { FC_REFLECT_DERIVED( graphene::chain::son_wallet_withdraw_object, (graphene::db::object), (timestamp) (sidechain) (confirmations) - (sidechain_uid) (sidechain_transaction_id) (sidechain_from) (sidechain_to) (sidechain_currency) (sidechain_amount) - (peerplays_from) (peerplays_to) (peerplays_asset) + (peerplays_uid) (peerplays_transaction_id) (peerplays_from) (peerplays_asset) + (withdraw_sidechain) (withdraw_address) (withdraw_currency) (withdraw_amount) (processed) ) diff --git a/libraries/chain/son_wallet_withdraw_evaluator.cpp b/libraries/chain/son_wallet_withdraw_evaluator.cpp index 52f7ee9d..d3a32a1b 100644 --- a/libraries/chain/son_wallet_withdraw_evaluator.cpp +++ b/libraries/chain/son_wallet_withdraw_evaluator.cpp @@ -11,29 +11,27 @@ void_result create_son_wallet_withdraw_evaluator::do_evaluate(const son_wallet_w FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK"); FC_ASSERT( op.payer == GRAPHENE_SON_ACCOUNT, "SON paying account must be set as payer." ); - //const auto& idx = db().get_index_type().indices().get(); - //FC_ASSERT(idx.find(op.sidechain_uid) == idx.end(), "Already registered " + op.sidechain_uid); return void_result(); } FC_CAPTURE_AND_RETHROW( (op) ) } object_id_type create_son_wallet_withdraw_evaluator::do_apply(const son_wallet_withdraw_create_operation& op) { try { - const auto& idx = db().get_index_type().indices().get(); - auto itr = idx.find(op.sidechain_uid); + const auto& idx = db().get_index_type().indices().get(); + auto itr = idx.find(op.peerplays_uid); if (itr == idx.end()) { - const auto& new_son_wallet_withdraw_object = db().create( [&]( son_wallet_withdraw_object& swto ){ - swto.timestamp = op.timestamp; - swto.sidechain = op.sidechain; - swto.confirmations = 1; - swto.sidechain_uid = op.sidechain_uid; - swto.sidechain_transaction_id = op.sidechain_transaction_id; - swto.sidechain_from = op.sidechain_from; - swto.sidechain_to = op.sidechain_to; - swto.sidechain_amount = op.sidechain_amount; - swto.peerplays_from = op.peerplays_from; - swto.peerplays_to = op.peerplays_to; - swto.peerplays_asset = op.peerplays_asset; - swto.processed = false; + const auto& new_son_wallet_withdraw_object = db().create( [&]( son_wallet_withdraw_object& swwo ){ + swwo.timestamp = op.timestamp; + swwo.sidechain = op.sidechain; + swwo.confirmations = 1; + swwo.peerplays_uid = op.peerplays_uid; + swwo.peerplays_transaction_id = op.peerplays_transaction_id; + swwo.peerplays_from = op.peerplays_from; + swwo.peerplays_asset = op.peerplays_asset; + swwo.withdraw_sidechain = op.withdraw_sidechain; + swwo.withdraw_address = op.withdraw_address; + swwo.withdraw_currency = op.withdraw_currency; + swwo.withdraw_amount = op.withdraw_amount; + swwo.processed = false; }); return new_son_wallet_withdraw_object.id; } else { @@ -51,49 +49,7 @@ void_result process_son_wallet_withdraw_evaluator::do_evaluate(const son_wallet_ const auto& idx = db().get_index_type().indices().get(); const auto& itr = idx.find(op.son_wallet_withdraw_id); - FC_ASSERT(itr != idx.end(), "Son wallet transfer not found"); - //FC_ASSERT(itr->processed == false, "Son wallet transfer is already processed"); - - const database& d = db(); - - const account_object& from_account = itr->peerplays_to(d); // reversed, for withdrawal - const account_object& to_account = itr->peerplays_from(d); // reversed, for withdrawal - const asset_object& asset_type = itr->peerplays_asset.asset_id(d); - - try { - - GRAPHENE_ASSERT( - is_authorized_asset( d, from_account, asset_type ), - transfer_from_account_not_whitelisted, - "'from' account ${from} is not whitelisted for asset ${asset}", - ("from",from_account.id) - ("asset",itr->peerplays_asset.asset_id) - ); - GRAPHENE_ASSERT( - is_authorized_asset( d, to_account, asset_type ), - transfer_to_account_not_whitelisted, - "'to' account ${to} is not whitelisted for asset ${asset}", - ("to",to_account.id) - ("asset",itr->peerplays_asset.asset_id) - ); - - if( asset_type.is_transfer_restricted() ) - { - GRAPHENE_ASSERT( - from_account.id == asset_type.issuer || to_account.id == asset_type.issuer, - transfer_restricted_transfer_asset, - "Asset {asset} has transfer_restricted flag enabled", - ("asset", itr->peerplays_asset.asset_id) - ); - } - - bool insufficient_balance = d.get_balance( from_account, asset_type ).amount >= itr->peerplays_asset.amount; - FC_ASSERT( insufficient_balance, - "Insufficient Balance: ${balance}, unable to transfer '${total_transfer}' from account '${a}' to '${t}'", - ("a",from_account.name)("t",to_account.name)("total_transfer",d.to_pretty_string(itr->peerplays_asset))("balance",d.to_pretty_string(d.get_balance(from_account, asset_type))) ); - - return void_result(); - } FC_RETHROW_EXCEPTIONS( error, "Unable to transfer ${a} from ${f} to ${t}", ("a",d.to_pretty_string(itr->peerplays_asset))("f",from_account.name)("t",to_account.name) ); + FC_ASSERT(itr != idx.end(), "Son wallet withdraw not found"); } FC_CAPTURE_AND_RETHROW( (op) ) } object_id_type process_son_wallet_withdraw_evaluator::do_apply(const son_wallet_withdraw_process_operation& op) @@ -106,12 +62,6 @@ object_id_type process_son_wallet_withdraw_evaluator::do_apply(const son_wallet_ db().modify(*itr, [&op](son_wallet_withdraw_object &swto) { swto.processed = true; }); - - const account_id_type from_account = itr->peerplays_to; // reversed, for withdrawal - const account_id_type to_account = itr->peerplays_from; // reversed, for withdrawal - - db().adjust_balance( from_account, -itr->peerplays_asset ); - db().adjust_balance( to_account, itr->peerplays_asset ); } } return op.son_wallet_withdraw_id; diff --git a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp index 01f43972..e5680d45 100644 --- a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp +++ b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -376,83 +375,14 @@ void peerplays_sidechain_plugin_impl::recreate_primary_wallet() net_manager->recreate_primary_wallet(); } -void peerplays_sidechain_plugin_impl::process_deposits() { - - const auto& idx = plugin.database().get_index_type().indices().get(); - const auto& idx_range = idx.equal_range(false); - - std::for_each(idx_range.first, idx_range.second, - [&] (const son_wallet_deposit_object& swdo) { - - const chain::global_property_object& gpo = plugin.database().get_global_properties(); - - for (son_id_type son_id : plugin.get_sons()) { - if (plugin.is_active_son(son_id)) { - - son_wallet_deposit_process_operation p_op; - p_op.payer = GRAPHENE_SON_ACCOUNT; - p_op.son_wallet_deposit_id = swdo.id; - - proposal_create_operation proposal_op; - proposal_op.fee_paying_account = plugin.get_son_object(son_id).son_account; - proposal_op.proposed_ops.emplace_back( op_wrapper( p_op ) ); - uint32_t lifetime = ( gpo.parameters.block_interval * gpo.active_witnesses.size() ) * 3; - proposal_op.expiration_time = time_point_sec( plugin.database().head_block_time().sec_since_epoch() + lifetime ); - - ilog("sidechain_net_handler: sending proposal for transfer operation ${swdo} by ${son}", ("swdo", swdo.id) ("son", son_id)); - signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_key(son_id), proposal_op); - trx.validate(); - ilog("sidechain_net_handler: transaction validated ${swdo} by ${son}", ("swdo", swdo.id) ("son", son_id)); - try { - plugin.database().push_transaction(trx, database::validation_steps::skip_block_size_check); - if(plugin.app().p2p_node()) - plugin.app().p2p_node()->broadcast(net::trx_message(trx)); - } catch(fc::exception e){ - ilog("sidechain_net_handler: sending proposal for transfer operation failed with exception ${e}",("e", e.what())); -} - } - } - }); +void peerplays_sidechain_plugin_impl::process_deposits() +{ + net_manager->process_deposits(); } -void peerplays_sidechain_plugin_impl::process_withdrawals() { - - const auto& idx = plugin.database().get_index_type().indices().get(); - const auto& idx_range = idx.equal_range(false); - - std::for_each(idx_range.first, idx_range.second, - [&] (const son_wallet_withdraw_object& swwo) { - - const chain::global_property_object& gpo = plugin.database().get_global_properties(); - - for (son_id_type son_id : plugin.get_sons()) { - if (plugin.is_active_son(son_id)) { - - ilog("Withdraw to process: ${swwo}", ("swwo", swwo)); - //son_wallet_withdraw_process_operation p_op; - //p_op.payer = GRAPHENE_SON_ACCOUNT; - //p_op.son_wallet_withdraw_id = swwo.id; - // - //proposal_create_operation proposal_op; - //proposal_op.fee_paying_account = plugin.get_son_object(son_id).son_account; - //proposal_op.proposed_ops.emplace_back( op_wrapper( p_op ) ); - //uint32_t lifetime = ( gpo.parameters.block_interval * gpo.active_witnesses.size() ) * 3; - //proposal_op.expiration_time = time_point_sec( plugin.database().head_block_time().sec_since_epoch() + lifetime ); - // - //ilog("sidechain_net_handler: sending proposal for transfer operation ${swwo} by ${son}", ("swwo", swwo.id) ("son", son_id)); - //signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_key(son_id), proposal_op); - //trx.validate(); - //ilog("sidechain_net_handler: transaction validated ${swwo} by ${son}", ("swwo", swwo.id) ("son", son_id)); - //try { - // plugin.database().push_transaction(trx, database::validation_steps::skip_block_size_check); - // if(plugin.app().p2p_node()) - // plugin.app().p2p_node()->broadcast(net::trx_message(trx)); - //} catch(fc::exception e){ - // ilog("sidechain_net_handler: sending proposal for transfer operation failed with exception ${e}",("e", e.what())); - //} -} - } - }); +void peerplays_sidechain_plugin_impl::process_withdrawals() +{ + net_manager->process_withdrawals(); } void peerplays_sidechain_plugin_impl::on_block_applied( const signed_block& b ) @@ -544,6 +474,18 @@ void peerplays_sidechain_plugin_impl::on_objects_new(const vectorid ); continue; } + + if(proposal->proposed_transaction.operations.size() == 1 + && proposal->proposed_transaction.operations[0].which() == chain::operation::tag::value) { + approve_proposal( son_id, proposal->id ); + continue; + } + + if(proposal->proposed_transaction.operations.size() == 1 + && proposal->proposed_transaction.operations[0].which() == chain::operation::tag::value) { + approve_proposal( son_id, proposal->id ); + continue; + } } } } diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp index 45ace614..1f201106 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp @@ -1,6 +1,8 @@ #include #include +#include +#include #include @@ -101,19 +103,24 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_ // Withdrawal request if ((sed.peerplays_to == GRAPHENE_SON_ACCOUNT) && (sed.sidechain_currency.compare("1.3.0") == 0)) { + // BTC Payout only (for now) + const auto& sidechain_addresses_idx = database.get_index_type().indices().get(); + const auto& addr_itr = sidechain_addresses_idx.find(std::make_tuple(sed.peerplays_from, sidechain_type::bitcoin)); + if ( addr_itr == sidechain_addresses_idx.end() ) + return; + son_wallet_withdraw_create_operation op; op.payer = GRAPHENE_SON_ACCOUNT; op.timestamp = sed.timestamp; op.sidechain = sed.sidechain; - op.sidechain_uid = sed.sidechain_uid; - op.sidechain_transaction_id = sed.sidechain_transaction_id; - op.sidechain_from = sed.sidechain_from; - op.sidechain_to = sed.sidechain_to; - op.sidechain_currency = sed.sidechain_currency; - op.sidechain_amount = sed.sidechain_amount; + op.peerplays_uid = sed.sidechain_uid; + op.peerplays_transaction_id = sed.sidechain_transaction_id; op.peerplays_from = sed.peerplays_from; - op.peerplays_to = sed.peerplays_to; op.peerplays_asset = sed.peerplays_asset; + op.withdraw_sidechain = sidechain_type::bitcoin; // BTC payout only (for now) + op.withdraw_address = addr_itr->withdraw_address; // BTC payout only (for now) + op.withdraw_currency = "BTC"; // BTC payout only (for now) + op.withdraw_amount = sed.peerplays_asset.amount * 1000; // BTC payout only (for now) for (son_id_type son_id : plugin.get_sons()) { if (plugin.is_active_son(son_id)) { @@ -145,11 +152,80 @@ void sidechain_net_handler::recreate_primary_wallet() { } void sidechain_net_handler::process_deposits() { - FC_ASSERT(false, "process_deposits not implemented"); + const auto& idx = plugin.database().get_index_type().indices().get(); + const auto& idx_range = idx.equal_range(std::make_tuple(sidechain, false)); + + std::for_each(idx_range.first, idx_range.second, + [&] (const son_wallet_deposit_object& swdo) { + + const chain::global_property_object& gpo = plugin.database().get_global_properties(); + + for (son_id_type son_id : plugin.get_sons()) { + if (plugin.is_active_son(son_id)) { + + son_wallet_deposit_process_operation p_op; + p_op.payer = GRAPHENE_SON_ACCOUNT; + p_op.son_wallet_deposit_id = swdo.id; + + proposal_create_operation proposal_op; + proposal_op.fee_paying_account = plugin.get_son_object(son_id).son_account; + proposal_op.proposed_ops.emplace_back( op_wrapper( p_op ) ); + uint32_t lifetime = ( gpo.parameters.block_interval * gpo.active_witnesses.size() ) * 3; + proposal_op.expiration_time = time_point_sec( plugin.database().head_block_time().sec_since_epoch() + lifetime ); + + ilog("sidechain_net_handler: sending proposal for transfer operation ${swdo} by ${son}", ("swdo", swdo.id) ("son", son_id)); + signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_key(son_id), proposal_op); + trx.validate(); + ilog("sidechain_net_handler: transaction validated ${swdo} by ${son}", ("swdo", swdo.id) ("son", son_id)); + try { + plugin.database().push_transaction(trx, database::validation_steps::skip_block_size_check); + if(plugin.app().p2p_node()) + plugin.app().p2p_node()->broadcast(net::trx_message(trx)); + } catch(fc::exception e){ + ilog("sidechain_net_handler: sending proposal for transfer operation failed with exception ${e}",("e", e.what())); + } + } + } + }); } void sidechain_net_handler::process_withdrawals() { - FC_ASSERT(false, "process_withdrawals not implemented"); + const auto& idx = plugin.database().get_index_type().indices().get(); + const auto& idx_range = idx.equal_range(std::make_tuple(sidechain, false)); + + std::for_each(idx_range.first, idx_range.second, + [&] (const son_wallet_withdraw_object& swwo) { + + const chain::global_property_object& gpo = plugin.database().get_global_properties(); + + for (son_id_type son_id : plugin.get_sons()) { + if (plugin.is_active_son(son_id)) { + + ilog("SON ${son_id}: Withdraw to process: ${swwo}", ("son_id", son_id) ("swwo", swwo)); + //son_wallet_withdraw_process_operation p_op; + //p_op.payer = GRAPHENE_SON_ACCOUNT; + //p_op.son_wallet_withdraw_id = swwo.id; + // + //proposal_create_operation proposal_op; + //proposal_op.fee_paying_account = plugin.get_son_object(son_id).son_account; + //proposal_op.proposed_ops.emplace_back( op_wrapper( p_op ) ); + //uint32_t lifetime = ( gpo.parameters.block_interval * gpo.active_witnesses.size() ) * 3; + //proposal_op.expiration_time = time_point_sec( plugin.database().head_block_time().sec_since_epoch() + lifetime ); + // + //ilog("sidechain_net_handler: sending proposal for transfer operation ${swwo} by ${son}", ("swwo", swwo.id) ("son", son_id)); + //signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_key(son_id), proposal_op); + //trx.validate(); + //ilog("sidechain_net_handler: transaction validated ${swwo} by ${son}", ("swwo", swwo.id) ("son", son_id)); + //try { + // plugin.database().push_transaction(trx, database::validation_steps::skip_block_size_check); + // if(plugin.app().p2p_node()) + // plugin.app().p2p_node()->broadcast(net::trx_message(trx)); + //} catch(fc::exception e){ + // ilog("sidechain_net_handler: sending proposal for transfer operation failed with exception ${e}",("e", e.what())); + //} + } + } + }); } } } // graphene::peerplays_sidechain diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp index cf2fefdc..c0e8c5f6 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp @@ -425,9 +425,11 @@ void sidechain_net_handler_bitcoin::recreate_primary_wallet() { } void sidechain_net_handler_bitcoin::process_deposits() { + sidechain_net_handler::process_deposits(); } void sidechain_net_handler_bitcoin::process_withdrawals() { + sidechain_net_handler::process_withdrawals(); } std::string sidechain_net_handler_bitcoin::create_multisignature_wallet( const std::vector public_keys ) { diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_peerplays.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_peerplays.cpp index 0ae5c1c6..609616f2 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_peerplays.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_peerplays.cpp @@ -32,9 +32,11 @@ void sidechain_net_handler_peerplays::recreate_primary_wallet() { } void sidechain_net_handler_peerplays::process_deposits() { + sidechain_net_handler::process_deposits(); } void sidechain_net_handler_peerplays::process_withdrawals() { + sidechain_net_handler::process_withdrawals(); } std::string sidechain_net_handler_peerplays::create_multisignature_wallet( const std::vector public_keys ) { @@ -75,7 +77,7 @@ void sidechain_net_handler_peerplays::on_block_applied(const signed_block& b) { sed.sidechain_transaction_id = trx.id().str(); sed.sidechain_from = fc::to_string(transfer_op.from.space_id) + "." + fc::to_string(transfer_op.from.type_id) + "." + fc::to_string((uint64_t)transfer_op.from.instance); sed.sidechain_to = fc::to_string(transfer_op.to.space_id) + "." + fc::to_string(transfer_op.to.type_id) + "." + fc::to_string((uint64_t)transfer_op.to.instance); - sed.sidechain_currency = transfer_op.amount.asset_id(plugin.database()).symbol; + sed.sidechain_currency = fc::to_string(transfer_op.amount.asset_id.space_id) + "." + fc::to_string(transfer_op.amount.asset_id.type_id) + "." + fc::to_string((uint64_t)transfer_op.amount.asset_id.instance); //transfer_op.amount.asset_id(plugin.database()).symbol; sed.sidechain_amount = transfer_op.amount.amount; sed.peerplays_from = transfer_op.from; sed.peerplays_to = transfer_op.to;