limit_order_id_type trigger_swan(share_type amount1, share_type amount2) { set_expiration( db, trx ); // starting out with price 1:1 set_feed( 1, 1 ); // start out with 2:1 collateral borrow(borrower(), swan().amount(amount1), back().amount(2*amount1)); borrow(borrower2(), swan().amount(amount2), back().amount(4*amount2)); FC_ASSERT( get_balance(borrower(), swan()) == amount1 ); FC_ASSERT( get_balance(borrower2(), swan()) == amount2 ); FC_ASSERT( get_balance(borrower() , back()) == init_balance - 2*amount1 ); FC_ASSERT( get_balance(borrower2(), back()) == init_balance - 4*amount2 ); set_feed( 1, 2 ); // this sell order is designed to trigger a black swan limit_order_id_type oid = create_sell_order( borrower2(), swan().amount(1), back().amount(3) )->id; FC_ASSERT( get_balance(borrower(), swan()) == amount1 ); FC_ASSERT( get_balance(borrower2(), swan()) == amount2 - 1 ); FC_ASSERT( get_balance(borrower() , back()) == init_balance - 2*amount1 ); FC_ASSERT( get_balance(borrower2(), back()) == init_balance - 2*amount2 ); BOOST_CHECK( swan().bitasset_data(db).has_settlement() ); return oid; }
void pending_chain_state::get_undo_state( const chain_interface_ptr& undo_state_arg )const { auto undo_state = std::dynamic_pointer_cast<pending_chain_state>( undo_state_arg ); chain_interface_ptr prev_state = _prev_state.lock(); FC_ASSERT( prev_state ); for( const auto& item : properties ) { auto prev_value = prev_state->get_property( (chain_property_enum)item.first ); undo_state->set_property( (chain_property_enum)item.first, prev_value ); } for( const auto& item : assets ) { auto prev_value = prev_state->get_asset_record( item.first ); if( !!prev_value ) undo_state->store_asset_record( *prev_value ); else undo_state->store_asset_record( item.second.make_null() ); } for( const auto& item : slates ) { auto prev_value = prev_state->get_delegate_slate( item.first ); if( prev_value ) undo_state->store_delegate_slate( item.first, *prev_value ); else undo_state->store_delegate_slate( item.first, delegate_slate() ); } for( const auto& item : accounts ) { auto prev_value = prev_state->get_account_record( item.first ); if( !!prev_value ) undo_state->store_account_record( *prev_value ); else undo_state->store_account_record( item.second.make_null() ); } #if 0 for( const auto& item : proposals ) { auto prev_value = prev_state->get_proposal_record( item.first ); if( !!prev_value ) undo_state->store_proposal_record( *prev_value ); else undo_state->store_proposal_record( item.second.make_null() ); } for( const auto& item : proposal_votes ) { auto prev_value = prev_state->get_proposal_vote( item.first ); if( !!prev_value ) undo_state->store_proposal_vote( *prev_value ); else { undo_state->store_proposal_vote( item.second.make_null() ); } } #endif for( const auto& item : balances ) { auto prev_value = prev_state->get_balance_record( item.first ); if( !!prev_value ) undo_state->store_balance_record( *prev_value ); else undo_state->store_balance_record( item.second.make_null() ); } for( const auto& item : transactions ) { auto prev_value = prev_state->get_transaction( item.first ); if( !!prev_value ) undo_state->store_transaction( item.first, *prev_value ); else undo_state->store_transaction( item.first, transaction_record() ); } for( const auto& item : bids ) { auto prev_value = prev_state->get_bid_record( item.first ); if( prev_value.valid() ) undo_state->store_bid_record( item.first, *prev_value ); else undo_state->store_bid_record( item.first, order_record() ); } for( const auto& item : asks ) { auto prev_value = prev_state->get_ask_record( item.first ); if( prev_value.valid() ) undo_state->store_ask_record( item.first, *prev_value ); else undo_state->store_ask_record( item.first, order_record() ); } for( const auto& item : shorts ) { auto prev_value = prev_state->get_short_record( item.first ); if( prev_value.valid() ) undo_state->store_short_record( item.first, *prev_value ); else undo_state->store_short_record( item.first, order_record() ); } for( const auto& item : collateral ) { auto prev_value = prev_state->get_collateral_record( item.first ); if( prev_value.valid() ) undo_state->store_collateral_record( item.first, *prev_value ); else undo_state->store_collateral_record( item.first, collateral_record() ); } for( const auto& item : slots ) { auto prev_value = prev_state->get_slot_record( item.first ); if( prev_value ) undo_state->store_slot_record( *prev_value ); else { slot_record invalid_slot_record; invalid_slot_record.start_time = item.first; invalid_slot_record.block_produced = true; invalid_slot_record.block_id = block_id_type(); undo_state->store_slot_record( invalid_slot_record ); } } for( const auto& item : market_statuses ) { auto prev_value = prev_state->get_market_status( item.first.first, item.first.second ); if( prev_value ) undo_state->store_market_status( *prev_value ); else { undo_state->store_market_status( market_status() ); } } for( const auto& item : feeds ) { auto prev_value = prev_state->get_feed( item.first ); if( prev_value ) undo_state->set_feed( *prev_value ); else undo_state->set_feed( feed_record{item.first} ); } for( const auto& item : burns ) { undo_state->store_burn_record( burn_record( item.first ) ); } const auto dirty_markets = prev_state->get_dirty_markets(); undo_state->set_dirty_markets(dirty_markets); /* NOTE: Recent operations are currently not rewound on undo */ }