diff --git a/libraries/wallet/include/graphene/wallet/reflect_util.hpp b/libraries/wallet/include/graphene/wallet/reflect_util.hpp new file mode 100644 index 00000000..d32c96ef --- /dev/null +++ b/libraries/wallet/include/graphene/wallet/reflect_util.hpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2015, Cryptonomex, Inc. + * All rights reserved. + * + * This source code is provided for evaluation in private test networks only, until September 8, 2015. After this date, this license expires and + * the code may not be used, modified or distributed for any purpose. Redistribution and use in source and binary forms, with or without modification, + * are permitted until September 8, 2015, provided that the following conditions are met: + * + * 1. The code and/or derivative works are used only for private test networks consisting of no more than 10 P2P nodes. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#pragma once + +// This file contains various reflection methods that are used to +// support the wallet, e.g. allow specifying operations by name +// instead of ID. + +namespace graphene { namespace wallet { + +struct static_variant_map +{ + flat_map< string, int > name_to_which; + vector< string > which_to_name; +}; + +namespace impl { + +struct static_variant_map_visitor +{ + static_variant_map_visitor() {} + + typedef void result_type; + + template< typename T > + result_type operator()( const T& dummy ) + { + assert( which == m.which_to_name.size() ); + std::string name = js_name::name(); + m.name_to_which[ name ] = which; + m.which_to_name.push_back( name ); + } + + static_variant_map m; + int which; +}; + +} // namespace impl + +template< typename T > +T from_which_variant( int which, const variant& v ) +{ + // Parse a variant for a known which() + T result; + result.set_which( which ); + from_variant( v, result ); + return result; +} + +template +static_variant_map create_static_variant_map() +{ + T dummy; + int n = dummy.count(); + impl::static_variant_map_visitor vtor; + for( int i=0; i #include +#include #include #include #include #include +#include #include #ifndef WIN32 @@ -1999,10 +2001,84 @@ public: signed_transaction propose_fee_change( const string& proposing_account, - const variant_object& changed_values, + fc::time_point_sec expiration_time, + const variant_object& changed_fees, bool broadcast = false) { - FC_ASSERT( false, "not implemented" ); + const chain_parameters& current_params = get_global_properties().parameters; + const fee_schedule_type& current_fees = *(current_params.current_fees); + + flat_map< int, fee_parameters > fee_map; + fee_map.reserve( current_fees.parameters.size() ); + for( const fee_parameters& op_fee : current_fees.parameters ) + fee_map[ op_fee.which() ] = op_fee; + uint32_t scale = current_fees.scale; + + for( const auto& item : changed_fees ) + { + const string& key = item.key(); + if( key == "scale" ) + { + int64_t _scale = item.value().as_int64(); + FC_ASSERT( _scale >= 0 ); + FC_ASSERT( _scale <= std::numeric_limits::max() ); + scale = uint32_t( _scale ); + continue; + } + // is key a number? + auto is_numeric = [&]() -> bool + { + size_t n = key.size(); + for( size_t i=0; isecond; + } + + fee_parameters fp = from_which_variant< fee_parameters >( which, item.value() ); + fee_map[ which ] = fp; + } + + fee_schedule_type new_fees; + + for( const std::pair< int, fee_parameters >& item : fee_map ) + new_fees.parameters.insert( item.second ); + new_fees.scale = scale; + + chain_parameters new_params = current_params; + new_params.current_fees = new_fees; + + committee_member_update_global_parameters_operation update_op; + update_op.new_parameters = new_params; + + proposal_create_operation prop_op; + + prop_op.expiration_time = expiration_time; + prop_op.review_period_seconds = current_params.committee_proposal_review_period; + prop_op.fee_paying_account = get_account(proposing_account).id; + + prop_op.proposed_ops.emplace_back( update_op ); + current_params.current_fees->set_fee( prop_op.proposed_ops.back().op ); + + signed_transaction tx; + tx.operations.push_back(prop_op); + set_operation_fees(tx, current_params.current_fees); + tx.validate(); + + return sign_transaction(tx, broadcast); } signed_transaction approve_proposal( @@ -2171,6 +2247,8 @@ public: flat_map _prototype_ops; + static_variant_map _operation_which_map = create_static_variant_map< operation >(); + #ifdef __unix__ mode_t _old_umask; #endif @@ -2876,11 +2954,12 @@ signed_transaction wallet_api::propose_parameter_change( signed_transaction wallet_api::propose_fee_change( const string& proposing_account, - const variant_object& changed_values, + fc::time_point_sec expiration_time, + const variant_object& changed_fees, bool broadcast /* = false */ ) { - return my->propose_fee_change( proposing_account, changed_values, broadcast ); + return my->propose_fee_change( proposing_account, expiration_time, changed_fees, broadcast ); } signed_transaction wallet_api::approve_proposal(