Skip to content

Commit 736a0ce

Browse files
author
ABW
committed
add issue/burn methods to dgpo for HIVE/HBD and use it to replace temporary set_from_asset in unit tests
1 parent c5fdfe3 commit 736a0ce

2 files changed

Lines changed: 121 additions & 26 deletions

File tree

libraries/chain/include/hive/chain/detail/state/global_property_object.hpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <fc/uint128.hpp>
55

66
#include <hive/chain/hive_object_types.hpp>
7+
#include <hive/chain/util/balance.hpp>
78

89
#include <hive/protocol/asset.hpp>
910
#include <hive/protocol/config.hpp>
@@ -38,6 +39,10 @@ class dynamic_global_property_object : public object< dynamic_global_property_ob
3839

3940
//main HIVE token counter
4041
const HIVE_asset& get_current_supply() const { return current_supply; }
42+
//creates HIVE out of thin air - for inflation
43+
inline temp_HIVE_balance issue_HIVE( const HIVE_asset& hive_amount );
44+
//burns all HIVE on given balance into the void - for clearing null
45+
inline void burn_HIVE( temp_HIVE_balance& hive_balance );
4146
//all HIVE in existence including those that would be created if all HBD was converted to HIVE
4247
const HIVE_asset& get_virtual_supply() const { return virtual_supply; }
4348

@@ -48,6 +53,10 @@ class dynamic_global_property_object : public object< dynamic_global_property_ob
4853
const HBD_asset& get_current_hbd_supply() const { return current_hbd_supply; }
4954
//initial HBD tokens
5055
const HBD_asset& get_initial_hbd_supply() const { return init_hbd_supply; }
56+
//creates HBD out of thin air - for interest
57+
inline temp_HBD_balance issue_HBD( const HBD_asset& hbd_amount, const HBD_price& exchange_rate );
58+
//burns all HBD on given balance into the void - for clearing null
59+
inline void burn_HBD( temp_HBD_balance& hbd_balance, const HBD_price& exchange_rate );
5160

5261
HBD_asset& access_current_hbd_supply() { return current_hbd_supply; } //TODO: should not be needed with init/burn/convert
5362
HBD_asset& access_initial_hbd_supply() { return init_hbd_supply; } //TODO: should not be needed with proper genesis rework
@@ -263,6 +272,40 @@ class dynamic_global_property_object : public object< dynamic_global_property_ob
263272
CHAINBASE_UNPACK_CONSTRUCTOR( dynamic_global_property_object );
264273
};
265274

275+
inline temp_HIVE_balance dynamic_global_property_object::issue_HIVE( const HIVE_asset& hive_amount )
276+
{
277+
temp_HIVE_balance hive_balance;
278+
hive_balance.issue_asset( hive_amount );
279+
current_supply += hive_amount;
280+
virtual_supply += hive_amount;
281+
return hive_balance;
282+
}
283+
284+
inline void dynamic_global_property_object::burn_HIVE( temp_HIVE_balance& hive_balance )
285+
{
286+
const HIVE_asset& hive_amount = hive_balance;
287+
current_supply -= hive_amount;
288+
virtual_supply -= hive_amount;
289+
hive_balance.burn_asset( hive_amount );
290+
}
291+
292+
inline temp_HBD_balance dynamic_global_property_object::issue_HBD( const HBD_asset& hbd_amount, const HBD_price& exchange_rate )
293+
{
294+
temp_HBD_balance hbd_balance;
295+
hbd_balance.issue_asset( hbd_amount );
296+
current_hbd_supply += hbd_amount;
297+
virtual_supply += hbd_amount * exchange_rate;
298+
return hbd_balance;
299+
}
300+
301+
inline void dynamic_global_property_object::burn_HBD( temp_HBD_balance& hbd_balance, const HBD_price& exchange_rate )
302+
{
303+
const HBD_asset& hbd_amount = hbd_balance;
304+
current_hbd_supply -= hbd_amount;
305+
virtual_supply -= hbd_amount * exchange_rate;
306+
hbd_balance.burn_asset( hbd_amount );
307+
}
308+
266309
} } // hive::chain
267310

268311
FC_REFLECT( hive::chain::dynamic_global_property_object,

tests/unit/tests/basic_tests.cpp

Lines changed: 78 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1930,45 +1930,64 @@ BOOST_AUTO_TEST_CASE( temp_balance_nonzero_destruction_is_bug )
19301930
HIVE_REQUIRE_ASSERT(
19311931
{
19321932
temp_HIVE_balance lost_funds;
1933-
lost_funds.set_from_asset( HIVE_asset( 100 ) ); // TODO: change to dgpo.issue
1933+
db->modify( db->get_dynamic_global_properties(), [&]( dynamic_global_property_object& dgpo )
1934+
{
1935+
lost_funds = dgpo.issue_HIVE( HIVE_asset( 100 ) );
1936+
} );
19341937
},
19351938
"this->is_empty() && \"temp_tiny_balance\""
19361939
);
1940+
// total supply is now invalid, losing funds is a fatal error in the code, but let's continue anyway
19371941

19381942
// temp_balance (dynamic symbol) version
19391943
HIVE_REQUIRE_ASSERT(
19401944
{
1941-
temp_HIVE_balance tmp;
1942-
tmp.set_from_asset( HIVE_asset( 100 ) ); // TODO: change to dgpo.issue
19431945
temp_balance lost_funds( HIVE_SYMBOL );
1944-
lost_funds.transfer_from( tmp );
1946+
db->modify( db->get_dynamic_global_properties(), [&]( dynamic_global_property_object& dgpo )
1947+
{
1948+
auto tmp = dgpo.issue_HIVE( HIVE_asset( 100 ) );
1949+
lost_funds.transfer_from( tmp );
1950+
} );
19451951
},
19461952
"is_empty() && \"temp_balance\""
19471953
);
19481954

19491955
// Verify that zero-amount temp is fine
19501956
{
19511957
temp_HIVE_balance no_funds_from_start, no_funds_after_burn, no_funds_after_transfer;
1952-
no_funds_after_burn.set_from_asset( HIVE_asset( 200 ) ); // TODO: change to dgpo.issue
1958+
db->modify( db->get_dynamic_global_properties(), [&]( dynamic_global_property_object& dgpo )
1959+
{
1960+
no_funds_after_burn = dgpo.issue_HIVE( HIVE_asset( 200 ) );
1961+
} );
19531962
no_funds_after_burn.transfer_to( no_funds_after_transfer, HIVE_asset( 100 ) );
19541963
BOOST_REQUIRE_EQUAL( no_funds_after_burn, HIVE_asset( 100 ) ); // funds were on the balance
19551964
BOOST_REQUIRE_EQUAL( no_funds_after_transfer, HIVE_asset( 100 ) ); // funds were on the balance
19561965
no_funds_after_burn.transfer_from( no_funds_after_transfer );
1957-
no_funds_after_burn.set_from_asset( HIVE_asset( 0 ) ); // TODO: change to dgpo.burn
1966+
db->modify( db->get_dynamic_global_properties(), [&]( dynamic_global_property_object& dgpo )
1967+
{
1968+
dgpo.burn_HIVE( no_funds_after_burn );
1969+
} );
19581970
BOOST_REQUIRE_EQUAL( no_funds_after_burn, HIVE_asset( 0 ) ); // funds were removed from balance
19591971
BOOST_REQUIRE_EQUAL( no_funds_after_transfer, HIVE_asset( 0 ) ); // funds were removed from balance
19601972
} // No throw
19611973

19621974
// Verify that zero-amount temp is fine (dynamic symbol version)
19631975
{
1964-
temp_HIVE_balance tmp;
1965-
tmp.set_from_asset( HIVE_asset( 100 ) ); // TODO: change to dgpo.issue
1966-
temp_balance no_funds_from_start( HIVE_SYMBOL ), no_funds_after_transfer( HIVE_SYMBOL ); // there is no burn for dynamic asset balance
1967-
tmp.transfer_to( no_funds_after_transfer );
1968-
BOOST_REQUIRE_EQUAL( no_funds_after_transfer, ASSET( "0.100 TESTS" ) ); // funds were on the balance
1976+
const auto& exchange_rate = db->get_feed_history().current_median_history;
1977+
temp_HBD_balance tmp;
1978+
temp_balance no_funds_from_start( HBD_SYMBOL ), no_funds_after_transfer( HBD_SYMBOL ); // there is no burn for dynamic asset balance
1979+
db->modify( db->get_dynamic_global_properties(), [&]( dynamic_global_property_object& dgpo )
1980+
{
1981+
tmp = dgpo.issue_HBD( HBD_asset( 100 ), exchange_rate );
1982+
tmp.transfer_to( no_funds_after_transfer );
1983+
} );
1984+
BOOST_REQUIRE_EQUAL( no_funds_after_transfer, ASSET( "0.100 TBD" ) ); // funds were on the balance
19691985
no_funds_after_transfer.transfer_to( tmp );
1970-
BOOST_REQUIRE_EQUAL( no_funds_after_transfer, ASSET( "0.000 TESTS" ) ); // funds were removed from balance
1971-
tmp.set_from_asset( HIVE_asset( 0 ) ); // TODO: change to dgpo.burn
1986+
BOOST_REQUIRE_EQUAL( no_funds_after_transfer, ASSET( "0.000 TBD" ) ); // funds were removed from balance
1987+
db->modify( db->get_dynamic_global_properties(), [&]( dynamic_global_property_object& dgpo )
1988+
{
1989+
dgpo.burn_HBD( tmp, exchange_rate );
1990+
} );
19721991
} // No throw
19731992
}
19741993

@@ -1979,24 +1998,30 @@ BOOST_AUTO_TEST_CASE( temp_balance_nonzero_during_undo )
19791998
// a second exception (which would call std::terminate).
19801999
BOOST_TEST_MESSAGE( "Testing: temp_balance destruction during exception unwinding (undo path)" );
19812000

2001+
temp_HIVE_balance tmp;
2002+
db->modify( db->get_dynamic_global_properties(), [&]( dynamic_global_property_object& dgpo )
2003+
{
2004+
tmp = dgpo.issue_HIVE( HIVE_asset( 200 ) );
2005+
} );
2006+
19822007
// temp_tiny_balance: exception thrown while temp has non-zero amount
19832008
HIVE_REQUIRE_ASSERT(
19842009
{
19852010
temp_HIVE_balance nonempty_funds;
1986-
nonempty_funds.set_from_asset( HIVE_asset( 100 ) ); // TODO: change to dgpo.issue
2011+
nonempty_funds.transfer_from( tmp, HIVE_asset( 100 ) );
19872012
BOOST_REQUIRE_EQUAL( nonempty_funds, HIVE_asset( 100 ) );
19882013
FC_ASSERT( false && "simulating undo - transaction rejected" );
19892014
},
19902015
"false && \"simulating undo - transaction rejected\""
19912016
);
19922017
// If the destructor threw during unwinding, std::terminate would have been called
19932018
// and this line would never execute. Reaching here proves correct behavior.
2019+
// Note: normally the issue_HIVE would also be reverted, but we are in the test so
2020+
// without full undo we actually have broken invariants now; let's continue anyway
19942021

19952022
// temp_balance (dynamic symbol) version
19962023
HIVE_REQUIRE_ASSERT(
19972024
{
1998-
temp_HIVE_balance tmp;
1999-
tmp.set_from_asset( HIVE_asset( 100 ) ); // TODO: change to dgpo.issue
20002025
temp_balance nonempty_funds( HIVE_SYMBOL );
20012026
nonempty_funds.transfer_from( tmp );
20022027
BOOST_REQUIRE_EQUAL( nonempty_funds, ASSET( "0.100 TESTS" ) );
@@ -2018,30 +2043,45 @@ BOOST_AUTO_TEST_CASE( temp_balance_nonzero_overwrite_is_bug )
20182043
{
20192044
temp_HIVE_balance nonempty_funds;
20202045
temp_HIVE_balance tmp;
2021-
tmp.set_from_asset( HIVE_asset( 100 ) ); // TODO: change to dgpo.issue
2046+
db->modify( db->get_dynamic_global_properties(), [&]( dynamic_global_property_object& dgpo )
2047+
{
2048+
tmp = dgpo.issue_HIVE( HIVE_asset( 100 ) );
2049+
} );
20222050
nonempty_funds.transfer_from( tmp, HIVE_asset( 80 ) );
20232051
BOOST_REQUIRE_EQUAL( nonempty_funds, HIVE_asset( 80 ) );
20242052
nonempty_funds = std::move( tmp ); // not allowed
20252053
},
20262054
"this->is_empty() && \"temp_tiny_balance move assign\""
20272055
);
2056+
// what just happened was a fatal error, normally it would be handled by undo, but we don't have it here;
2057+
// let's continue anyway
20282058

20292059
// move assign is ok as long as target balance is empty
20302060
{
20312061
temp_HIVE_balance empty_funds, tmp;
2032-
tmp.set_from_asset( HIVE_asset( 100 ) ); // TODO: change to dgpo.issue
2062+
db->modify( db->get_dynamic_global_properties(), [&]( dynamic_global_property_object& dgpo )
2063+
{
2064+
tmp = dgpo.issue_HIVE( HIVE_asset( 100 ) );
2065+
} );
20332066
BOOST_REQUIRE_EQUAL( empty_funds, HIVE_asset( 0 ) );
20342067
empty_funds = std::move( tmp ); // ok
20352068
BOOST_REQUIRE_EQUAL( empty_funds, HIVE_asset( 100 ) );
2036-
empty_funds.set_from_asset( HIVE_asset( 0 ) ); // TODO: replace with dgpo.burn
2069+
db->modify( db->get_dynamic_global_properties(), [&]( dynamic_global_property_object& dgpo )
2070+
{
2071+
dgpo.burn_HIVE( empty_funds );
2072+
} );
20372073
}
20382074

20392075
// temp_balance: exception thrown while temp is overwritten while with non-zero amount
20402076
HIVE_REQUIRE_ASSERT(
20412077
{
20422078
temp_balance nonempty_funds( HIVE_SYMBOL );
20432079
temp_balance tmp( HIVE_SYMBOL );
2044-
tmp.set_from_asset( ASSET( "0.100 TESTS" ) ); // TODO: change to dgpo.issue
2080+
db->modify( db->get_dynamic_global_properties(), [&]( dynamic_global_property_object& dgpo )
2081+
{
2082+
auto new_hive = dgpo.issue_HIVE( HIVE_asset( 100 ) );
2083+
tmp.transfer_from( new_hive );
2084+
} );
20452085
nonempty_funds.transfer_from( tmp, ASSET( "0.080 TESTS" ) );
20462086
BOOST_REQUIRE_EQUAL( nonempty_funds, ASSET( "0.080 TESTS" ) );
20472087
nonempty_funds = std::move( tmp ); // not allowed
@@ -2051,12 +2091,22 @@ BOOST_AUTO_TEST_CASE( temp_balance_nonzero_overwrite_is_bug )
20512091

20522092
// move assign is ok as long as target balance is empty, even when assets are different
20532093
{
2094+
const auto& exchange_rate = db->get_feed_history().current_median_history;
20542095
temp_balance empty_funds( HIVE_SYMBOL ), tmp( HBD_SYMBOL );
2055-
tmp.set_from_asset( ASSET( "0.100 TBD" ) ); // TODO: change to dgpo.issue
2096+
db->modify( db->get_dynamic_global_properties(), [&]( dynamic_global_property_object& dgpo )
2097+
{
2098+
auto new_hbd = dgpo.issue_HBD( HBD_asset( 100 ), exchange_rate );
2099+
tmp.transfer_from( new_hbd );
2100+
} );
20562101
BOOST_REQUIRE_EQUAL( empty_funds, ASSET( "0.000 TESTS" ) );
20572102
empty_funds = std::move( tmp ); // ok
20582103
BOOST_REQUIRE_EQUAL( empty_funds, ASSET( "0.100 TBD" ) );
2059-
empty_funds.set_from_asset( ASSET( "0.000 TBD" ) ); // TODO: replace with dgpo.burn
2104+
db->modify( db->get_dynamic_global_properties(), [&]( dynamic_global_property_object& dgpo )
2105+
{
2106+
temp_HBD_balance hbd;
2107+
hbd.transfer_from( empty_funds );
2108+
dgpo.burn_HBD( hbd, exchange_rate );
2109+
} );
20602110
}
20612111
}
20622112

@@ -2938,10 +2988,12 @@ BOOST_AUTO_TEST_CASE( removal_of_nonempty_balance_is_a_bug )
29382988
any.transfer_from( e.access_fee() );
29392989
} );
29402990
db->remove( *escrow );
2941-
// TODO: return balance to alice or burn with dgpo once it is available
2942-
hive.set_from_asset( HIVE_asset( 0 ) );
2943-
hbd.set_from_asset( HBD_asset( 0 ) );
2944-
any.set_from_asset( asset( 0, any.as_asset().symbol ) );
2991+
db->modify( db->get_dynamic_global_properties(), [&]( dynamic_global_property_object& dgpo )
2992+
{
2993+
dgpo.burn_HIVE( hive );
2994+
hbd.transfer_from( any );
2995+
dgpo.burn_HBD( hbd, db->get_feed_history().current_median_history );
2996+
} );
29452997
}
29462998

29472999
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)