Compute scaled precision at compile time, use in tests (fixes failures by prev commit)

This commit is contained in:
theoreticalbts 2015-08-11 14:48:38 -04:00
parent 44c174ad4a
commit 3eedabbac2
5 changed files with 67 additions and 8 deletions

View file

@ -110,9 +110,7 @@ asset asset_object::amount_from_string(string amount_string) const
share_type satoshis = 0;
share_type scaled_precision = 1;
for( uint8_t i = 0; i < precision; ++i )
scaled_precision *= 10;
share_type scaled_precision = asset::scaled_precision( precision );
const auto decimal_pos = amount_string.find( '.' );
const string lhs = amount_string.substr( negative_found, decimal_pos );

View file

@ -21,6 +21,8 @@
namespace graphene { namespace chain {
extern const int64_t scaled_precision_lut[];
struct asset
{
asset( share_type a = 0, asset_id_type id = asset_id_type() )
@ -80,6 +82,12 @@ namespace graphene { namespace chain {
FC_ASSERT( a.asset_id == b.asset_id );
return asset( a.amount + b.amount, a.asset_id );
}
static share_type scaled_precision( uint8_t precision )
{
FC_ASSERT( precision < 19 );
return scaled_precision_lut[ precision ];
}
};
/**

View file

@ -146,4 +146,27 @@ namespace graphene { namespace chain {
return (asset( cp.numerator(), settlement_price.base.asset_id ) / asset( cp.denominator(), settlement_price.quote.asset_id ));
}
// compile-time table of powers of 10 using template metaprogramming
template< int N >
struct p10
{
static const int64_t v = 10 * p10<N-1>::v;
};
template<>
struct p10<0>
{
static const int64_t v = 1;
};
const int64_t scaled_precision_lut[19] =
{
p10< 0 >::v, p10< 1 >::v, p10< 2 >::v, p10< 3 >::v,
p10< 4 >::v, p10< 5 >::v, p10< 6 >::v, p10< 7 >::v,
p10< 8 >::v, p10< 9 >::v, p10< 10 >::v, p10< 11 >::v,
p10< 12 >::v, p10< 13 >::v, p10< 14 >::v, p10< 15 >::v,
p10< 16 >::v, p10< 17 >::v, p10< 18 >::v
};
} } // graphene::chain

View file

@ -314,10 +314,40 @@ BOOST_AUTO_TEST_CASE( witness_rng_test_bits )
} FC_LOG_AND_RETHROW()
}
BOOST_AUTO_TEST_CASE( exceptions )
{
GRAPHENE_CHECK_THROW(FC_THROW_EXCEPTION(balance_claim_invalid_claim_amount, "Etc"), balance_claim_invalid_claim_amount);
}
BOOST_AUTO_TEST_CASE( scaled_precision )
{
const int64_t _k = 1000;
const int64_t _m = _k*_k;
const int64_t _g = _m*_k;
const int64_t _t = _g*_k;
const int64_t _p = _t*_k;
const int64_t _e = _p*_k;
BOOST_CHECK( asset::scaled_precision( 0) == share_type( 1 ) );
BOOST_CHECK( asset::scaled_precision( 1) == share_type( 10 ) );
BOOST_CHECK( asset::scaled_precision( 2) == share_type( 100 ) );
BOOST_CHECK( asset::scaled_precision( 3) == share_type( 1*_k) );
BOOST_CHECK( asset::scaled_precision( 4) == share_type( 10*_k) );
BOOST_CHECK( asset::scaled_precision( 5) == share_type( 100*_k) );
BOOST_CHECK( asset::scaled_precision( 6) == share_type( 1*_m) );
BOOST_CHECK( asset::scaled_precision( 7) == share_type( 10*_m) );
BOOST_CHECK( asset::scaled_precision( 8) == share_type( 100*_m) );
BOOST_CHECK( asset::scaled_precision( 9) == share_type( 1*_g) );
BOOST_CHECK( asset::scaled_precision(10) == share_type( 10*_g) );
BOOST_CHECK( asset::scaled_precision(11) == share_type( 100*_g) );
BOOST_CHECK( asset::scaled_precision(12) == share_type( 1*_t) );
BOOST_CHECK( asset::scaled_precision(13) == share_type( 10*_t) );
BOOST_CHECK( asset::scaled_precision(14) == share_type( 100*_t) );
BOOST_CHECK( asset::scaled_precision(15) == share_type( 1*_p) );
BOOST_CHECK( asset::scaled_precision(16) == share_type( 10*_p) );
BOOST_CHECK( asset::scaled_precision(17) == share_type( 100*_p) );
BOOST_CHECK( asset::scaled_precision(18) == share_type( 1*_e) );
GRAPHENE_CHECK_THROW( asset::scaled_precision(19), fc::exception );
}
BOOST_AUTO_TEST_SUITE_END()

View file

@ -921,7 +921,7 @@ BOOST_AUTO_TEST_CASE( uia_fees )
const asset_dynamic_data_object& asset_dynamic = test_asset.dynamic_asset_data_id(db);
const account_object& nathan_account = get_account("nathan");
const account_object& committee_account = account_id_type()(db);
const auto prec = asset_id_type()(db).precision;
const share_type prec = asset::scaled_precision( asset_id_type()(db).precision );
fund_fee_pool(committee_account, test_asset, 1000*prec);
BOOST_CHECK(asset_dynamic.fee_pool == 1000*prec);
@ -1128,7 +1128,7 @@ BOOST_AUTO_TEST_CASE( fill_order )
BOOST_AUTO_TEST_CASE( witness_pay_test )
{ try {
const auto prec = asset_id_type()(db).precision;
const share_type prec = asset::scaled_precision( asset_id_type()(db).precision );
// there is an immediate maintenance interval in the first block
// which will initialize last_budget_time
@ -1188,7 +1188,7 @@ BOOST_AUTO_TEST_CASE( witness_pay_test )
PUSH_TX( db, trx );
auto pay_fee_time = db.head_block_time().sec_since_epoch();
trx.clear();
BOOST_CHECK_EQUAL(get_balance(*nathan, *core), 20000*prec - account_upgrade_operation::fee_parameters_type().membership_lifetime_fee );;
BOOST_CHECK( get_balance(*nathan, *core) == 20000*prec - account_upgrade_operation::fee_parameters_type().membership_lifetime_fee );;
generate_block();
nathan = &get_account("nathan");
@ -1215,7 +1215,7 @@ BOOST_AUTO_TEST_CASE( witness_pay_test )
schedule_maint();
// The 80% lifetime referral fee went to the committee account, which burned it. Check that it's here.
BOOST_CHECK_EQUAL( core->reserved(db).value, 8000*prec );
BOOST_CHECK( core->reserved(db).value == 8000*prec );
generate_block();
BOOST_CHECK_EQUAL( core->reserved(db).value, 999999406 );
BOOST_CHECK_EQUAL( db.get_dynamic_global_properties().witness_budget.value, ref_budget );