Skip to content

Commit

Permalink
Merge branch 'develop' into merge-appbase
Browse files Browse the repository at this point in the history
  • Loading branch information
mvandeberg committed Feb 21, 2018
2 parents 2253acb + 1d7c4dd commit eb81ae3
Show file tree
Hide file tree
Showing 10 changed files with 190 additions and 100 deletions.
7 changes: 4 additions & 3 deletions libraries/chain/database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4418,9 +4418,10 @@ void database::validate_smt_invariants()const
for( ; itr != end; ++itr )
{
const smt_token_object& smt = *itr;
auto totalIt = theMap.find( smt.symbol );
asset total_supply = totalIt == theMap.end() ? asset(0, smt.symbol) : totalIt->second;
FC_ASSERT( asset(smt.current_supply, smt.symbol) == total_supply, "", ("smt current_supply",smt.current_supply)("total_supply",total_supply) );
auto totalIt = theMap.find( smt.liquid_symbol );
asset total_liquid_supply = totalIt == theMap.end() ? asset(0, smt.liquid_symbol) : totalIt->second;
FC_ASSERT( asset(smt.current_supply, smt.liquid_symbol) == total_liquid_supply,
"", ("smt current_supply",smt.current_supply)("total_liquid_supply",total_liquid_supply) );
}
}
FC_CAPTURE_LOG_AND_RETHROW( (head_block_num()) );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

namespace steem { namespace chain {

/**Note that the object represents both liquid and vesting variant of SMT.
* The same object is returned by indices when searched by liquid/vesting symbol/nai.
*/
class smt_token_object : public object< smt_token_object_type, smt_token_object >
{
smt_token_object() = delete;
Expand All @@ -32,15 +35,18 @@ class smt_token_object : public object< smt_token_object_type, smt_token_object
c( *this );
}

uint32_t get_nai() const
uint32_t get_liquid_nai() const
{
return symbol.to_nai();
return liquid_symbol.to_nai();
}

// id_type is actually oid<smt_token_object>
id_type id;

asset_symbol_type symbol;
/**The object represents both liquid and vesting variant of SMT
* To get vesting symbol, call liquid_symbol.get_paired_symbol()
*/
asset_symbol_type liquid_symbol;
account_name_type control_account;
smt_phase phase = smt_phase::account_elevated;

Expand Down Expand Up @@ -83,15 +89,34 @@ struct by_symbol;
struct by_nai;
struct by_control_account;

/**Comparison operators that allow to return the same object representation
* for both liquid and vesting symbol/nai.
*/
struct vesting_liquid_less
{
bool operator ()( const asset_symbol_type& lhs, const asset_symbol_type& rhs ) const
{
// Compare as if both symbols represented liquid version.
return ( lhs.is_vesting() ? lhs.get_paired_symbol() : lhs ) <
( rhs.is_vesting() ? rhs.get_paired_symbol() : rhs );
}

bool operator ()( const uint32_t& lhs, const uint32_t& rhs ) const
{
// Use the other operator, adding the same precision to both NAIs.
return operator()( asset_symbol_type::from_nai( lhs, 0 ) , asset_symbol_type::from_nai( rhs, 0 ) );
}
};

typedef multi_index_container <
smt_token_object,
indexed_by <
ordered_unique< tag< by_id >,
member< smt_token_object, smt_token_id_type, &smt_token_object::id > >,
ordered_unique< tag< by_symbol >,
member< smt_token_object, asset_symbol_type, &smt_token_object::symbol > >,
member< smt_token_object, asset_symbol_type, &smt_token_object::liquid_symbol >, vesting_liquid_less >,
ordered_unique< tag< by_nai >,
const_mem_fun< smt_token_object, uint32_t, &smt_token_object::get_nai > >,
const_mem_fun< smt_token_object, uint32_t, &smt_token_object::get_liquid_nai >, vesting_liquid_less >,
ordered_non_unique< tag< by_control_account >,
member< smt_token_object, account_name_type, &smt_token_object::control_account > >
>,
Expand All @@ -113,7 +138,7 @@ FC_REFLECT( steem::chain::smt_token_object::smt_market_maker_state,

FC_REFLECT( steem::chain::smt_token_object,
(id)
(symbol)
(liquid_symbol)
(control_account)
(phase)
(current_supply)
Expand Down
7 changes: 4 additions & 3 deletions libraries/chain/smt_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,12 @@ void smt_create_evaluator::do_apply( const smt_create_operation& o )
_db.adjust_balance( o.control_account , -o.smt_creation_fee );
_db.adjust_balance( STEEM_NULL_ACCOUNT, o.smt_creation_fee );

// Create SMT object common to both liquid and vesting variants of SMT.
_db.create< smt_token_object >( [&]( smt_token_object& token )
{
token.symbol = o.symbol;
token.liquid_symbol = o.symbol;
token.control_account = o.control_account;
token.market_maker.token_balance = asset( 0, token.symbol );
token.market_maker.token_balance = asset( 0, token.liquid_symbol );
});
}

Expand Down Expand Up @@ -140,7 +141,7 @@ void smt_setup_emissions_evaluator::do_apply( const smt_setup_emissions_operatio

const smt_token_object& smt = common_pre_setup_evaluation(_db, o.symbol, o.control_account);

FC_ASSERT( o.lep_abs_amount.symbol == smt.symbol );
FC_ASSERT( o.lep_abs_amount.symbol == smt.liquid_symbol );
// ^ Note that rep_abs_amount.symbol has been matched to lep's in validate().

_db.modify( smt, [&]( smt_token_object& token )
Expand Down
2 changes: 2 additions & 0 deletions libraries/plugins/chain/chain_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ void chain_plugin::plugin_startup()
void chain_plugin::plugin_shutdown()
{
ilog("closing chain database");
my->thread_pool_ios.stop();
my->thread_pool.join_all();
my->db.close();
ilog("database closed successfully");
}
Expand Down
106 changes: 57 additions & 49 deletions libraries/plugins/p2p/p2p_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ class p2p_plugin_impl : public graphene::net::node_delegate
uint32_t max_connections = 0;
bool force_validate = false;
bool block_producer = false;
bool running = true;

std::unique_ptr<graphene::net::node> node;

Expand All @@ -127,59 +128,61 @@ bool p2p_plugin_impl::has_item( const graphene::net::item_id& id )

bool p2p_plugin_impl::handle_block( const graphene::net::block_message& blk_msg, bool sync_mode, std::vector<fc::uint160_t>& )
{ try {
uint32_t head_block_num;
chain.db().with_read_lock( [&]()
if( running )
{
head_block_num = chain.db().head_block_num();
});
if (sync_mode)
fc_ilog(fc::logger::get("sync"),
"chain pushing sync block #${block_num} ${block_hash}, head is ${head}",
("block_num", blk_msg.block.block_num())
("block_hash", blk_msg.block_id)
("head", head_block_num));
else
fc_ilog(fc::logger::get("sync"),
"chain pushing block #${block_num} ${block_hash}, head is ${head}",
("block_num", blk_msg.block.block_num())
("block_hash", blk_msg.block_id)
("head", head_block_num));

try {
// TODO: in the case where this block is valid but on a fork that's too old for us to switch to,
// you can help the network code out by throwing a block_older_than_undo_history exception.
// when the net code sees that, it will stop trying to push blocks from that chain, but
// leave that peer connected so that they can get sync blocks from us
bool result = chain.accept_block( blk_msg.block, sync_mode, ( block_producer | force_validate ) ? chain::database::skip_nothing : chain::database::skip_transaction_signatures );

if( !sync_mode )
uint32_t head_block_num;
chain.db().with_read_lock( [&]()
{
fc::microseconds latency = fc::time_point::now() - blk_msg.block.timestamp;
ilog( "Got ${t} transactions on block ${b} by ${w} -- latency: ${l} ms",
("t", blk_msg.block.transactions.size())
("b", blk_msg.block.block_num())
("w", blk_msg.block.witness)
("l", latency.count() / 1000) );
}
head_block_num = chain.db().head_block_num();
});
if (sync_mode)
fc_ilog(fc::logger::get("sync"),
"chain pushing sync block #${block_num} ${block_hash}, head is ${head}",
("block_num", blk_msg.block.block_num())
("block_hash", blk_msg.block_id)
("head", head_block_num));
else
fc_ilog(fc::logger::get("sync"),
"chain pushing block #${block_num} ${block_hash}, head is ${head}",
("block_num", blk_msg.block.block_num())
("block_hash", blk_msg.block_id)
("head", head_block_num));

try {
// TODO: in the case where this block is valid but on a fork that's too old for us to switch to,
// you can help the network code out by throwing a block_older_than_undo_history exception.
// when the net code sees that, it will stop trying to push blocks from that chain, but
// leave that peer connected so that they can get sync blocks from us
bool result = chain.accept_block( blk_msg.block, sync_mode, ( block_producer | force_validate ) ? chain::database::skip_nothing : chain::database::skip_transaction_signatures );

if( !sync_mode )
{
fc::microseconds latency = fc::time_point::now() - blk_msg.block.timestamp;
ilog( "Got ${t} transactions on block ${b} by ${w} -- latency: ${l} ms",
("t", blk_msg.block.transactions.size())
("b", blk_msg.block.block_num())
("w", blk_msg.block.witness)
("l", latency.count() / 1000) );
}

return result;
} catch ( const chain::unlinkable_block_exception& e ) {
// translate to a graphene::net exception
fc_elog(fc::logger::get("sync"),
"Error when pushing block, current head block is ${head}:\n${e}",
("e", e.to_detail_string())
("head", head_block_num));
elog("Error when pushing block:\n${e}", ("e", e.to_detail_string()));
FC_THROW_EXCEPTION(graphene::net::unlinkable_block_exception, "Error when pushing block:\n${e}", ("e", e.to_detail_string()));
} catch( const fc::exception& e ) {
fc_elog(fc::logger::get("sync"),
"Error when pushing block, current head block is ${head}:\n${e}",
("e", e.to_detail_string())
("head", head_block_num));
elog("Error when pushing block:\n${e}", ("e", e.to_detail_string()));
throw;
return result;
} catch ( const chain::unlinkable_block_exception& e ) {
// translate to a graphene::net exception
fc_elog(fc::logger::get("sync"),
"Error when pushing block, current head block is ${head}:\n${e}",
("e", e.to_detail_string())
("head", head_block_num));
elog("Error when pushing block:\n${e}", ("e", e.to_detail_string()));
FC_THROW_EXCEPTION(graphene::net::unlinkable_block_exception, "Error when pushing block:\n${e}", ("e", e.to_detail_string()));
} catch( const fc::exception& e ) {
fc_elog(fc::logger::get("sync"),
"Error when pushing block, current head block is ${head}:\n${e}",
("e", e.to_detail_string())
("head", head_block_num));
elog("Error when pushing block:\n${e}", ("e", e.to_detail_string()));
throw;
}
}

return false;
} FC_CAPTURE_AND_RETHROW( (blk_msg)(sync_mode) ) }

Expand Down Expand Up @@ -590,6 +593,11 @@ void p2p_plugin::plugin_startup()

void p2p_plugin::plugin_shutdown() {
ilog("Shutting down P2P Plugin");
my->running = false;

// Wait for outstanding calls to `handle_block` to be resolved
boost::this_thread::sleep_for( boost::chrono::milliseconds(200) );

my->node->close();
my->p2p_thread.quit();
my->node.reset();
Expand Down
5 changes: 4 additions & 1 deletion libraries/protocol/smt_operations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ void smt_create_operation::validate()const
FC_ASSERT( smt_creation_fee.amount >= 0, "fee cannot be negative" );
FC_ASSERT( smt_creation_fee.amount <= STEEM_MAX_SHARE_SUPPLY, "Fee must be smaller than STEEM_MAX_SHARE_SUPPLY" );
FC_ASSERT( is_asset_type( smt_creation_fee, STEEM_SYMBOL ) || is_asset_type( smt_creation_fee, SBD_SYMBOL ), "Fee must be STEEM or SBD" );
FC_ASSERT( symbol.space() == asset_symbol_type::smt_nai_space, "legacy symbol used instead of NAI" );
symbol.validate();
FC_ASSERT( symbol.space() == asset_symbol_type::smt_nai_space, "legacy symbol used instead of NAI" );
FC_ASSERT( symbol.is_vesting() == false, "liquid variant of NAI expected");
FC_ASSERT( symbol.decimals() == precision, "Mismatch between redundantly provided precision ${prec1} vs ${prec2}",
("prec1",symbol.decimals())("prec2",precision) );
}
Expand Down Expand Up @@ -188,6 +189,8 @@ void smt_setup_emissions_operation::validate()const
FC_ASSERT( schedule_time <= lep_time || lep_time == rep_time );
// ^ lep_time is either later or non-important

FC_ASSERT( (lep_abs_amount.symbol.is_vesting() == false),
"Use liquid variant of SMT symbol to specify emission amounts" );
FC_ASSERT( lep_abs_amount.symbol == rep_abs_amount.symbol );
FC_ASSERT( lep_abs_amount.amount >= 0 && rep_abs_amount.amount >= 0 );
FC_ASSERT( lep_abs_amount.amount != rep_abs_amount.amount || lep_abs_amount.amount > 0 );
Expand Down
34 changes: 19 additions & 15 deletions tests/db_fixture/database_fixture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,18 @@ asset_symbol_type database_fixture::name_to_asset_symbol( const std::string& nam
return asset_symbol_type::from_asset_num( asset_num );
}

#ifdef STEEM_ENABLE_SMT
asset_symbol_type database_fixture::get_new_smt_symbol( uint8_t token_decimal_places, chain::database* db )
{
// The list of available nais is not dependent on SMT desired precision (token_decimal_places).
auto available_nais = db->get_smt_next_identifier();
FC_ASSERT( available_nais.size() > 0, "No available nai returned by get_smt_next_identifier." );
const asset_symbol_type& new_nai = available_nais[0];
// Note that token's precision is needed now, when creating actual symbol.
return asset_symbol_type::from_nai( new_nai.to_nai(), token_decimal_places );
}
#endif

string database_fixture::generate_anon_acct_name()
{
// names of the form "anon-acct-x123" ; the "x" is necessary
Expand Down Expand Up @@ -599,7 +611,6 @@ void database_fixture::validate_database( void )

template< typename T >
asset_symbol_type t_smt_database_fixture< T >::create_smt( const string& account_name, const fc::ecc::private_key& key,

uint8_t token_decimal_places )
{
smt_create_operation op;
Expand All @@ -612,12 +623,7 @@ asset_symbol_type t_smt_database_fixture< T >::create_smt( const string& account
set_price_feed( price( ASSET( "1.000 TBD" ), ASSET( "1.000 TESTS" ) ) );
convert( account_name, ASSET( "5000.000 TESTS" ) );

// The list of available nais is not dependent on SMT desired precision (token_decimal_places).
auto available_nais = this->db->get_smt_next_identifier();
FC_ASSERT( available_nais.size() > 0, "No available nai returned by get_smt_next_identifier." );
const asset_symbol_type& new_nai = available_nais[0];
// Note that token's precision is needed now, when creating actual symbol.
op.symbol = asset_symbol_type::from_nai( new_nai.to_nai(), token_decimal_places );
op.symbol = this->get_new_smt_symbol( token_decimal_places, this->db );
op.precision = op.symbol.decimals();
op.smt_creation_fee = ASSET( "1000.000 TBD" );
op.control_account = account_name;
Expand All @@ -642,9 +648,9 @@ void sub_set_create_op(smt_create_operation* op, account_name_type control_acoun
op->control_account = control_acount;
}

void set_create_op(smt_create_operation* op, account_name_type control_account, std::string token_name, uint8_t token_decimal_places)
void set_create_op(chain::database* db, smt_create_operation* op, account_name_type control_account, uint8_t token_decimal_places)
{
op->symbol = database_fixture::name_to_asset_symbol(token_name, token_decimal_places);
op->symbol = database_fixture::get_new_smt_symbol( token_decimal_places, db );
sub_set_create_op(op, control_account);
}

Expand All @@ -660,8 +666,6 @@ std::array<asset_symbol_type, 3> t_smt_database_fixture< T >::create_smt_3(const
smt_create_operation op0;
smt_create_operation op1;
smt_create_operation op2;
std::string token_name(control_account_name);
token_name.resize(2);

try
{
Expand All @@ -671,9 +675,9 @@ std::array<asset_symbol_type, 3> t_smt_database_fixture< T >::create_smt_3(const
set_price_feed( price( ASSET( "1.000 TBD" ), ASSET( "1.000 TESTS" ) ) );
convert( control_account_name, ASSET( "5000.000 TESTS" ) );

set_create_op(&op0, control_account_name, token_name + "0", 0);
set_create_op(&op1, control_account_name, token_name + "1", 1);
set_create_op(&op2, control_account_name, token_name + "2", 1);
set_create_op(this->db, &op0, control_account_name, 0);
set_create_op(this->db, &op1, control_account_name, 1);
set_create_op(this->db, &op2, control_account_name, 1);

signed_transaction tx;
tx.operations.push_back( op0 );
Expand Down Expand Up @@ -708,7 +712,7 @@ void t_smt_database_fixture< T >::create_invalid_smt( const char* control_accoun
{
// Fail due to precision too big.
smt_create_operation op_precision;
STEEM_REQUIRE_THROW( set_create_op(&op_precision, control_account_name, "smt", STEEM_ASSET_MAX_DECIMALS + 1), fc::assert_exception );
STEEM_REQUIRE_THROW( set_create_op(this->db, &op_precision, control_account_name, STEEM_ASSET_MAX_DECIMALS + 1), fc::assert_exception );
}

template< typename T >
Expand Down
3 changes: 3 additions & 0 deletions tests/db_fixture/database_fixture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@ struct database_fixture {

static fc::ecc::private_key generate_private_key( string seed = "init_key" );
static asset_symbol_type name_to_asset_symbol( const std::string& name, uint8_t decimal_places );
#ifdef STEEM_ENABLE_SMT
static asset_symbol_type get_new_smt_symbol( uint8_t token_decimal_places, chain::database* db );
#endif
string generate_anon_acct_name();
void open_database();
void generate_block(uint32_t skip = 0,
Expand Down
Loading

0 comments on commit eb81ae3

Please sign in to comment.