cli_wallet: Implement propose_fee_change

This commit is contained in:
theoreticalbts 2015-09-29 11:55:15 -04:00
parent 96e8f8dd6d
commit 6daa54da46
3 changed files with 170 additions and 6 deletions

View file

@ -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<T>::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<typename T>
static_variant_map create_static_variant_map()
{
T dummy;
int n = dummy.count();
impl::static_variant_map_visitor vtor;
for( int i=0; i<n; i++ )
{
dummy.set_which(i);
vtor.which = i;
dummy.visit( vtor );
}
return vtor.m;
}
} } // namespace graphene::wallet

View file

@ -1280,11 +1280,16 @@ class wallet_api
/** Propose a fee change.
*
* Not implemented.
*
* @param proposing_account The account paying the fee to propose the tx
* @param expiration_time Timestamp specifying when the proposal will either take effect or expire.
* @param changed_values Map of operation type to new fee. Operations may be specified by name or ID.
* The "scale" key changes the scale. All other operations will maintain current values.
* @param broadcast true if you wish to broadcast the transaction
* @return the signed version of the transaction
*/
signed_transaction propose_fee_change(
const string& proposing_account,
fc::time_point_sec expiration_time,
const variant_object& changed_values,
bool broadcast = false);

View file

@ -51,10 +51,12 @@
#include <graphene/app/api.hpp>
#include <graphene/chain/asset_object.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <graphene/utilities/key_conversion.hpp>
#include <graphene/utilities/words.hpp>
#include <graphene/wallet/wallet.hpp>
#include <graphene/wallet/api_documentation.hpp>
#include <graphene/wallet/reflect_util.hpp>
#include <fc/smart_ref_impl.hpp>
#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<uint32_t>::max() );
scale = uint32_t( _scale );
continue;
}
// is key a number?
auto is_numeric = [&]() -> bool
{
size_t n = key.size();
for( size_t i=0; i<n; i++ )
{
if( !isdigit( key[i] ) )
return false;
}
return true;
};
int which;
if( is_numeric() )
which = std::stoi( key );
else
{
const auto& n2w = _operation_which_map.name_to_which;
auto it = n2w.find( key );
FC_ASSERT( it != n2w.end(), "unknown operation" );
which = it->second;
}
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<string, operation> _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(