Skip to content

Commit

Permalink
Merge hardfork branch into bsip38 branch
Browse files Browse the repository at this point in the history
  • Loading branch information
abitmore committed Apr 26, 2018
2 parents d1c3448 + b4efcd1 commit e2f33f5
Show file tree
Hide file tree
Showing 13 changed files with 225 additions and 24 deletions.
14 changes: 10 additions & 4 deletions libraries/app/api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,10 @@ namespace graphene { namespace app {
{
auto block_num = b.block_num();
auto& callback = _callbacks.find(id)->second;
fc::async( [capture_this,this,id,block_num,trx_num,trx,callback](){ callback( fc::variant(transaction_confirmation{ id, block_num, trx_num, trx}, 5) ); } );
fc::async( [capture_this,this,id,block_num,trx_num,trx,callback]() {
callback( fc::variant( transaction_confirmation{ id, block_num, trx_num, trx },
GRAPHENE_MAX_NESTED_OBJECTS ) );
} );
}
}
}
Expand All @@ -161,7 +164,8 @@ namespace graphene { namespace app {
{
trx.validate();
_app.chain_database()->push_transaction(trx);
_app.p2p_node()->broadcast_transaction(trx);
if( _app.p2p_node() != nullptr )
_app.p2p_node()->broadcast_transaction(trx);
}

fc::variant network_broadcast_api::broadcast_transaction_synchronous(const signed_transaction& trx)
Expand All @@ -177,15 +181,17 @@ namespace graphene { namespace app {
void network_broadcast_api::broadcast_block( const signed_block& b )
{
_app.chain_database()->push_block(b);
_app.p2p_node()->broadcast( net::block_message( b ));
if( _app.p2p_node() != nullptr )
_app.p2p_node()->broadcast( net::block_message( b ));
}

void network_broadcast_api::broadcast_transaction_with_callback(confirmation_callback cb, const signed_transaction& trx)
{
trx.validate();
_callbacks[trx.id()] = cb;
_app.chain_database()->push_transaction(trx);
_app.p2p_node()->broadcast_transaction(trx);
if( _app.p2p_node() != nullptr )
_app.p2p_node()->broadcast_transaction(trx);
}

network_node_api::network_node_api( application& a ) : _app( a )
Expand Down
18 changes: 13 additions & 5 deletions libraries/chain/db_market.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,9 +590,17 @@ int database::match( const limit_order_object& bid, const call_order_object& ask

auto maint_time = get_dynamic_global_properties().next_maintenance_time;
// TODO remove when we're sure it's always false
bool before_core_hardfork_184 = ( maint_time <= HARDFORK_CORE_184_TIME ); // something-for-nothing
// TODO remove when we're sure it's always false
bool before_core_hardfork_342 = ( maint_time <= HARDFORK_CORE_342_TIME ); // better rounding
// TODO remove when we're sure it's always false
bool before_core_hardfork_834 = ( maint_time <= HARDFORK_CORE_834_TIME ); // target collateral ratio option
if( before_core_hardfork_184 )
ilog( "match(limit,call) is called before hardfork core-184 at block #${block}", ("block",head_block_num()) );
if( before_core_hardfork_342 )
ilog( "match(limit,call) is called before hardfork core-342 at block #${block}", ("block",head_block_num()) );
if( before_core_hardfork_834 )
ilog( "match(limit,call) is called before hardfork core-834 at block #${block}", ("block",head_block_num()) );

bool cull_taker = false;

Expand All @@ -610,8 +618,8 @@ int database::match( const limit_order_object& bid, const call_order_object& ask

// Be here, it's possible that taker is paying something for nothing due to partially filled in last loop.
// In this case, we see it as filled and cancel it later
// TODO remove hardfork check when we're sure it's always true (but keep the zero amount check)
if( order_receives.amount == 0 && maint_time > HARDFORK_CORE_184_TIME )
// TODO remove hardfork check when we're sure it's always after hard fork (but keep the zero amount check)
if( order_receives.amount == 0 && !before_core_hardfork_184 )
return 1;

if( before_core_hardfork_342 ) // TODO remove this "if" when we're sure it's always false (keep the code in else)
Expand All @@ -632,8 +640,8 @@ int database::match( const limit_order_object& bid, const call_order_object& ask
if( before_core_hardfork_342 ) // TODO remove this "if" when we're sure it's always false (keep the code in else)
{
order_receives = usd_to_buy * match_price; // round down here, in favor of call order
// TODO remove hardfork check when we're sure it's always true (but keep the zero amount check)
if( order_receives.amount == 0 && maint_time > HARDFORK_CORE_184_TIME )
// TODO remove hardfork check when we're sure it's always after hard fork (but keep the zero amount check)
if( order_receives.amount == 0 && !before_core_hardfork_184 )
return 1;
}
else // has hardfork core-342
Expand Down Expand Up @@ -851,7 +859,7 @@ bool database::fill_call_order( const call_order_object& order, const asset& pay
adjust_balance(borrower.get_id(), *collateral_freed);

modify( borrower_statistics, [&]( account_statistics_object& b ){
if( collateral_freed.valid() && collateral_freed->amount > 0 )
if( collateral_freed.valid() && collateral_freed->amount > 0 && collateral_freed->asset_id == asset_id_type() )
b.total_core_in_orders -= collateral_freed->amount;
if( pays.asset_id == asset_id_type() )
b.total_core_in_orders -= pays.amount;
Expand Down
4 changes: 4 additions & 0 deletions libraries/chain/hardfork.d/CORE_214.hf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// bitshares-core #214 Proposal cannot contain proposal_update_operation
#ifndef HARDFORK_CORE_214_TIME
#define HARDFORK_CORE_214_TIME (fc::time_point_sec( 1600000000 ))
#endif
2 changes: 1 addition & 1 deletion libraries/chain/include/graphene/chain/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
#define GRAPHENE_RECENTLY_MISSED_COUNT_INCREMENT 4
#define GRAPHENE_RECENTLY_MISSED_COUNT_DECREMENT 3

#define GRAPHENE_CURRENT_DB_VERSION "BTS2.12"
#define GRAPHENE_CURRENT_DB_VERSION "BTS2.13"

#define GRAPHENE_IRREVERSIBLE_THRESHOLD (70 * GRAPHENE_1_PERCENT)

Expand Down
16 changes: 10 additions & 6 deletions libraries/chain/market_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ void_result call_order_update_evaluator::do_apply(const call_order_update_operat
const call_order_object* call_obj = nullptr;

optional<price> old_collateralization;
optional<share_type> old_debt;

optional<uint16_t> new_target_cr = o.extensions.value.target_collateral_ratio;

Expand All @@ -246,6 +247,7 @@ void_result call_order_update_evaluator::do_apply(const call_order_update_operat
{
call_obj = &*itr;
old_collateralization = call_obj->collateralization();
old_debt = call_obj->debt;

d.modify( *call_obj, [&]( call_order_object& call ){
call.collateral += o.delta_collateral.amount;
Expand All @@ -259,8 +261,7 @@ void_result call_order_update_evaluator::do_apply(const call_order_update_operat
});
}

auto debt = call_obj->get_debt();
if( debt.amount == 0 )
if( call_obj->debt == 0 )
{
FC_ASSERT( call_obj->collateral == 0 );
d.remove( *call_obj );
Expand Down Expand Up @@ -310,19 +311,22 @@ void_result call_order_update_evaluator::do_apply(const call_order_update_operat
("a", ~call_obj->call_price )("b", _bitasset_data->current_feed.settlement_price)
);
}
else // after hard fork, always allow call order to be updated if collateral ratio is increased
else // after hard fork, always allow call order to be updated if collateral ratio is increased and debt is not increased
{
// We didn't fill any call orders. This may be because we
// aren't in margin call territory, or it may be because there
// were no matching orders. In the latter case,
// if collateral ratio is not increased, we throw.
// if collateral ratio is not increased or debt is increased, we throw.
// be here, we know no margin call was executed,
// so call_obj's collateral ratio should be set only by op
FC_ASSERT( ( old_collateralization.valid() && call_obj->collateralization() > *old_collateralization )
FC_ASSERT( ( old_collateralization.valid() && call_obj->debt <= *old_debt
&& call_obj->collateralization() > *old_collateralization )
|| ~call_obj->call_price < _bitasset_data->current_feed.settlement_price,
"Can only update to higher collateral ratio if it would trigger a margin call that cannot be fully filled",
"Can only increase collateral ratio without increasing debt if would trigger a margin call that cannot be fully filled",
("new_call_price", ~call_obj->call_price )
("settlement_price", _bitasset_data->current_feed.settlement_price)
("old_debt", old_debt)
("new_debt", call_obj->debt)
("old_collateralization", old_collateralization)
("new_collateralization", call_obj->collateralization() )
);
Expand Down
18 changes: 18 additions & 0 deletions libraries/chain/proposal_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,18 @@ struct proposal_operation_hardfork_visitor
}
};

struct hardfork_visitor_214 // non-recursive proposal visitor
{
typedef void result_type;

template<typename T>
void operator()(const T &v) const {}

void operator()(const proposal_update_operation &v) const {
FC_ASSERT(false, "Not allowed until hardfork 214");
}
};

void_result proposal_create_evaluator::do_evaluate(const proposal_create_operation& o)
{ try {
const database& d = db();
Expand All @@ -108,6 +120,12 @@ void_result proposal_create_evaluator::do_evaluate(const proposal_create_operati
const fc::time_point_sec next_maint_time = d.get_dynamic_global_properties().next_maintenance_time;
proposal_operation_hardfork_visitor vtor( block_time, next_maint_time );
vtor( o );
if( block_time < HARDFORK_CORE_214_TIME )
{ // cannot be removed after hf, unfortunately
hardfork_visitor_214 hf214;
for (const op_wrapper &op : o.proposed_ops)
op.op.visit( hf214 );
}

const auto& global_parameters = d.get_global_properties().parameters;

Expand Down
3 changes: 2 additions & 1 deletion libraries/chain/protocol/proposal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ void proposal_update_operation::get_required_authorities( vector<authority>& o )
auth.key_auths[k] = 1;
auth.weight_threshold = auth.key_auths.size();

o.emplace_back( std::move(auth) );
if( auth.weight_threshold > 0 )
o.emplace_back( std::move(auth) );
}

void proposal_update_operation::get_required_active_authorities( flat_set<account_id_type>& a )const
Expand Down
2 changes: 1 addition & 1 deletion libraries/fc
Submodule fc updated 1 files
+13 −13 CMakeLists.txt
6 changes: 6 additions & 0 deletions libraries/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#include <fc/crypto/hex.hpp>
#include <fc/thread/mutex.hpp>
#include <fc/thread/scoped_lock.hpp>
#include <fc/rpc/api_connection.hpp>

#include <graphene/app/api.hpp>
#include <graphene/chain/asset_object.hpp>
Expand All @@ -78,6 +79,11 @@
# include <sys/stat.h>
#endif

// explicit instantiation for later use
namespace fc {
template class api<graphene::wallet::wallet_api, identity_member>;
}

#define BRAIN_KEY_WORD_COUNT 16

namespace graphene { namespace wallet {
Expand Down
2 changes: 1 addition & 1 deletion tests/cli/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ int get_available_port()
sin.sin_family = AF_INET;
sin.sin_port = 0;
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
if (bind(socket_fd, (struct sockaddr*)&sin, sizeof(struct sockaddr_in)) == -1)
if (::bind(socket_fd, (struct sockaddr*)&sin, sizeof(struct sockaddr_in)) == -1)
return -1;
socklen_t len = sizeof(sin);
if (getsockname(socket_fd, (struct sockaddr *)&sin, &len) == -1)
Expand Down
82 changes: 82 additions & 0 deletions tests/tests/authority_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <graphene/chain/asset_object.hpp>
#include <graphene/chain/committee_member_object.hpp>
#include <graphene/chain/proposal_object.hpp>
#include <graphene/chain/hardfork.hpp>

#include <graphene/db/simple_index.hpp>

Expand Down Expand Up @@ -1403,4 +1404,85 @@ BOOST_FIXTURE_TEST_CASE( parent_owner_test, database_fixture )
}
}

BOOST_AUTO_TEST_CASE( issue_214 )
{ try {
ACTORS( (alice)(bob) );
fund( alice );

generate_blocks( HARDFORK_CORE_214_TIME - fc::hours(1) );
set_expiration( db, trx );

// Bob proposes that Alice transfer 500 CORE to himself
transfer_operation top;
top.from = alice_id;
top.to = bob_id;
top.amount = asset( 500 );
proposal_create_operation pop;
pop.proposed_ops.emplace_back(top);
pop.fee_paying_account = bob_id;
pop.expiration_time = db.head_block_time() + fc::days(1);
trx.operations.push_back(pop);
sign( trx, bob_private_key );
const proposal_id_type pid1 = PUSH_TX( db, trx ).operation_results[0].get<object_id_type>();
trx.clear();

// Bob wants to propose that Alice confirm the first proposal
proposal_update_operation pup;
pup.fee_paying_account = alice_id;
pup.proposal = pid1;
pup.active_approvals_to_add.insert( alice_id );
pop.proposed_ops.clear();
pop.proposed_ops.emplace_back( pup );
trx.operations.push_back(pop);
sign( trx, bob_private_key );
// before HF_CORE_214, Bob can't do that
BOOST_REQUIRE_THROW( PUSH_TX( db, trx ), fc::assert_exception );
trx.signatures.clear();

{ // Bob can create a proposal nesting the one containing the proposal_update
proposal_create_operation npop;
npop.proposed_ops.emplace_back(pop);
npop.fee_paying_account = bob_id;
npop.expiration_time = db.head_block_time() + fc::days(2);
signed_transaction ntx;
set_expiration( db, ntx );
ntx.operations.push_back(npop);
sign( ntx, bob_private_key );
const proposal_id_type pid1a = PUSH_TX( db, ntx ).operation_results[0].get<object_id_type>();
ntx.clear();

// But execution after confirming it fails
proposal_update_operation npup;
npup.fee_paying_account = bob_id;
npup.proposal = pid1a;
npup.active_approvals_to_add.insert( bob_id );
ntx.operations.push_back(npup);
sign( ntx, bob_private_key );
PUSH_TX( db, ntx );
ntx.clear();

db.get<proposal_object>( pid1a ); // still exists
}

generate_blocks( HARDFORK_CORE_214_TIME + fc::hours(1) );
set_expiration( db, trx );
sign( trx, bob_private_key );
// after the HF the previously failed tx works too
const proposal_id_type pid2 = PUSH_TX( db, trx ).operation_results[0].get<object_id_type>();
trx.clear();

// For completeness, Alice confirms Bob's second proposal
pup.proposal = pid2;
trx.operations.push_back(pup);
sign( trx, alice_private_key );
PUSH_TX( db, trx );
trx.clear();

// Execution of the second proposal should have confirmed the first,
// which should have been executed by now.
BOOST_CHECK_THROW( db.get<proposal_object>(pid1), fc::assert_exception );
BOOST_CHECK_THROW( db.get<proposal_object>(pid2), fc::assert_exception );
BOOST_CHECK_EQUAL( top.amount.amount.value, get_balance( bob_id, top.amount.asset_id ) );
} FC_LOG_AND_RETHROW() }

BOOST_AUTO_TEST_SUITE_END()
Loading

0 comments on commit e2f33f5

Please sign in to comment.