static share_type scaled_precision( uint8_t precision ) { FC_ASSERT( precision < 19 ); return scaled_precision_lut[ precision ]; }
fc::microseconds ntp_error() { fc::optional<fc::time_point> current_ntp_time = ntp_time(); FC_ASSERT( current_ntp_time, "We don't have NTP time!" ); return *current_ntp_time - fc::time_point::now(); }
void match_orders( std::vector<signed_transaction>& matched, asset::type quote, asset::type base ) { try { ilog( "match orders.." ); auto bids = _market_db.get_bids( quote, base ); auto asks = _market_db.get_asks( quote, base ); wlog( "asks: ${asks}", ("asks",asks) ); wlog( "bids: ${bids}", ("bids",bids) ); fc::optional<trx_output> ask_change; fc::optional<trx_output> bid_change; fc::optional<trx_output> cover_change; address bid_payout_address; fc::optional<asset> bid_payout; asset cover_collat; fc::optional<claim_by_cover_output> cover_payout; signed_transaction market_trx; market_trx.timestamp = fc::time_point::now(); /** asks are sorted from low to high, so we start * with the lowest ask, and check to see if there are * any bids that are greaterthan or equal to the ask, if * there are then either the full bid or full ask will be * filled. If the full bid is filled, then move on to the * next bid, and save the leftover ask. If the left over * ask is filled, then move to the next ask. * * When there are no more pairs that can be matched, exit * the loop and any partial payouts are made. */ auto ask_itr = asks.begin(); auto bid_itr = bids.rbegin(); while( ask_itr != asks.end() && bid_itr != bids.rend() ) { trx_output working_ask; trx_output working_bid; if( ask_change ) { working_ask = *ask_change; } else { working_ask = get_output( ask_itr->location ); } if( bid_change ) { working_bid = *bid_change; } else { working_bid = get_output( bid_itr->location); } claim_by_bid_output bid_claim = working_bid.as<claim_by_bid_output>(); if( working_ask.claim_func == claim_by_long ) { auto long_claim = working_ask.as<claim_by_long_output>(); if( long_claim.ask_price > bid_claim.ask_price ) { break; // exit the while loop, no more trades can occur } asset bid_amount = working_bid.get_amount() * bid_claim.ask_price; asset ask_amount = working_ask.get_amount() * long_claim.ask_price; FC_ASSERT( bid_amount.unit == ask_amount.unit ); auto trade_amount = std::min(bid_amount,ask_amount); ilog( "bid amount: ${b} @ ${bp} ask amount: ${a} @ ${ap}", ("b",bid_amount)("a",ask_amount)("bp",bid_claim.ask_price)("ap",long_claim.ask_price) ); asset bid_change_amount = working_bid.get_amount(); bid_change_amount -= trade_amount * bid_claim.ask_price; ilog( "bid change.. ${c}", ("c",bid_change_amount) ); asset ask_change_amount = working_ask.get_amount(); ask_change_amount -= trade_amount * long_claim.ask_price; ilog( "ask change.. ${c}", ("c",ask_change_amount) ); if( ask_change_amount != bid_change_amount && ask_change_amount != asset(0,working_bid.unit) ) { FC_ASSERT( !"At least one of the bid or ask should be completely filled", "", ("ask_change_amount",ask_change_amount)("bid_change_amount",bid_change_amount) ); } bid_payout_address = bid_claim.pay_address; auto bid_payout_amount = bid_amount - (bid_change_amount * bid_claim.ask_price); if( bid_payout ) { *bid_payout += bid_payout_amount; } else { bid_payout = bid_payout_amount; } if( cover_payout ) { cover_payout->payoff_amount += trade_amount.get_rounded_amount(); cover_collat += (trade_amount * long_claim.ask_price)*2; } else { cover_payout = claim_by_cover_output(); cover_payout->owner = long_claim.pay_address; cover_payout->payoff_unit = trade_amount.unit; cover_payout->payoff_amount = trade_amount.get_rounded_amount(); cover_collat = (trade_amount * long_claim.ask_price)*2; } if( bid_change_amount != asset(0, working_bid.unit) ) { // TODO: accumulate fractional parts, round at the end?.... working_bid.amount = bid_change_amount.get_rounded_amount(); bid_change = working_bid; elog( "we DID NOT fill the bid..." ); } else // we have filled the bid! { elog( "we filled the bid..." ); market_trx.inputs.push_back( bid_itr->location ); market_trx.outputs.push_back( trx_output( claim_by_signature_output( bid_claim.pay_address ), bid_payout->get_rounded_asset() ) ); bid_change.reset(); bid_payout.reset(); ++bid_itr; } if( ask_change_amount != asset( 0, working_bid.unit ) ) { working_ask.amount = ask_change_amount.get_rounded_amount(); ask_change = working_ask; } else // we have filled the ask! { market_trx.inputs.push_back( ask_itr->location ); market_trx.outputs.push_back( trx_output( *cover_payout, cover_collat ) ); ask_change.reset(); cover_payout.reset(); ++ask_itr; } } else if( working_ask.claim_func == claim_by_bid ) { FC_ASSERT( !"Not Implemented" ); claim_by_bid_output ask_claim = working_ask.as<claim_by_bid_output>(); if( ask_claim.ask_price > bid_claim.ask_price ) { break; } // TODO: implement straight trades.. } else { FC_ASSERT( !"Ask must either be a claim by bid or claim by long", "", ("ask", working_ask) ); } } // while( ... ) if( ask_change && ask_itr != asks.end() ) market_trx.inputs.push_back( ask_itr->location ); if( bid_change && bid_itr != bids.rend() ) market_trx.inputs.push_back( bid_itr->location ); if( ask_change ) { ilog( "ask_change: ${ask_change}", ("ask_change",ask_change) ); market_trx.outputs.push_back( *ask_change ); } if( bid_change ) { ilog( "bid_change: ${bid_change}", ("bid_change",bid_change) ); market_trx.outputs.push_back( *bid_change ); } if( bid_payout ) { ilog( "bid_payout ${payout}", ("payout",bid_payout) ); market_trx.outputs.push_back( trx_output( claim_by_signature_output( bid_payout_address ), *bid_payout ) ); } else { wlog ( "NO BID PAYOUT" ); } if( cover_payout ) { ilog( "cover_payout ${payout}", ("payout",cover_payout) ); market_trx.outputs.push_back( trx_output( *cover_payout, cover_collat ) ); } wlog( "Market Transaction: ${trx}", ("trx", market_trx) ); if( market_trx.inputs.size() ) { FC_ASSERT( market_trx.outputs.size() ); matched.push_back(market_trx); } //ilog( "done match orders.." ); } FC_RETHROW_EXCEPTIONS( warn, "", ("quote",quote)("base",base) ) }
void committee_member_create_operation::validate()const { FC_ASSERT( fee.amount >= 0 ); FC_ASSERT(url.size() < GRAPHENE_MAX_URL_LENGTH ); }
void committee_member_update_global_parameters_operation::validate() const { FC_ASSERT( fee.amount >= 0 ); new_parameters.validate(); }
void domain_buy_operation::evaluate( transaction_evaluation_state& eval_state ) { FC_ASSERT( is_valid_domain( this->domain_name ), "Trying to buy an invalid domain name" ); auto now = eval_state._current_state->now().sec_since_epoch(); auto odomain_rec = eval_state._current_state->get_domain_record( this->domain_name ); /* If it already exists and hasn't expired and you offered enough */ if( odomain_rec.valid() && odomain_rec->get_true_state(now) == domain_record::in_sale && this->price >= odomain_rec->price ) { share_type paid_to_owner = 0; for (auto op : eval_state.trx.operations) { if (op.type == operation_type_enum::deposit_op_type) { auto deposit = op.as<deposit_operation>(); if (deposit.condition.type == withdraw_condition_types::withdraw_signature_type) { auto condition = deposit.condition.as<withdraw_with_signature>(); if (condition.owner == odomain_rec->owner) { paid_to_owner += deposit.amount; } } } } FC_ASSERT( this->price == paid_to_owner ); FC_ASSERT( paid_to_owner >= odomain_rec->price, "Did not pay enough to previous owner" ); odomain_rec->state = domain_record::owned; odomain_rec->owner = this->new_owner; odomain_rec->last_update = eval_state._current_state->now().sec_since_epoch(); eval_state._current_state->store_domain_record( *odomain_rec ); return; } /* Domain does not exist or is not for sale or is too expensive, so this is an offer */ else { auto balance = eval_state._current_state->get_domain_offer(this->new_owner); FC_ASSERT( !balance.valid(), "Trying to make an offer with an offer ID that already exists"); FC_ASSERT(this->price > 0, "Price must be greater than 0 when you offer" ); bool found_deposit = false; for ( auto op : eval_state.trx.operations ) { if (op.type == operation_type_enum::deposit_op_type) { auto deposit = op.as<deposit_operation>(); if( deposit.condition.type == withdraw_condition_types::withdraw_domain_offer_type ) { auto condition = deposit.condition.as<bts::blockchain::withdraw_domain_offer>(); FC_ASSERT( condition.domain_name == this->domain_name, "condition does not match offer op" ); FC_ASSERT( condition.price == this->price, "condition does not match offer op" ); FC_ASSERT( condition.owner == this->new_owner, "condition does not match offer op" ); found_deposit = true; } } } FC_ASSERT( found_deposit, "Did not find a deposit on this domain offer transaction" ); auto offer_key = offer_index_key(); offer_key.price = this->price; offer_key.domain_name = this->domain_name; offer_key.offer_address = this->new_owner; offer_key.offer_time = eval_state._current_state->now().sec_since_epoch(); ulog( "about to store offer\n" ); eval_state._current_state->store_domain_offer( offer_key ); } }
std::string asset::symbol_name() const { auto a = (const char *)&symbol; FC_ASSERT(a[7] == 0); return &a[1]; }
friend bool operator < ( const asset& a, const asset& b ) { FC_ASSERT( a.symbol == b.symbol ); return std::tie(a.amount,a.symbol) < std::tie(b.amount,b.symbol); }
friend asset operator + ( const asset& a, const asset& b ) { FC_ASSERT( a.symbol == b.symbol ); return asset( a.amount + b.amount, a.symbol ); }
WithdrawType as()const { FC_ASSERT( type == WithdrawType::type, "", ("type",type)("WithdrawType",WithdrawType::type) ); return fc::raw::unpack<WithdrawType>(data); }
asset& operator -= ( const asset& o ) { FC_ASSERT( symbol == o.symbol ); amount -= o.amount; return *this; }
optional<extended_private_key> wallet_db::get_master_key( const fc::sha512& password )const { FC_ASSERT( wallet_master_key ); return wallet_master_key->decrypt_key( password ); }
bool wallet_db::validate_password( const fc::sha512& password )const { FC_ASSERT( wallet_master_key ); return wallet_master_key->validate_password( password ); }
void wallet_db::store_generic_record( const generic_wallet_record& record, bool sync ) { FC_ASSERT( is_open() ); my->store_generic_record( record, sync ); }
void validate()const { FC_ASSERT( fee.amount >= 0 ); FC_ASSERT( amount.amount > 0 ); }
OperationType as()const { FC_ASSERT( (operation_type_enum)type == OperationType::type, "", ("type",type)("OperationType",OperationType::type) ); return fc::raw::unpack<OperationType>(data); }
void validate()const { FC_ASSERT( fee.amount >= 0 ); FC_ASSERT(new_listing < 0x4); }
price market_order::get_highest_cover_price()const { try { FC_ASSERT( type == cover_order ); return asset( state.balance, market_index.order_price.quote_asset_id ) / asset( *collateral ); } FC_CAPTURE_AND_RETHROW() }
memo_data domain_transfer_operation::decrypt_memo_data( const fc::sha512& secret ) const { try { FC_ASSERT( memo.valid() ); return fc::raw::unpack<memo_data>( fc::aes_decrypt( secret, memo->encrypted_memo_data ) ); } FC_RETHROW_EXCEPTIONS( warn, "" ) }
fc::api<network_broadcast_api> login_api::network_broadcast()const { FC_ASSERT(_network_broadcast_api); return *_network_broadcast_api; }
void message_oriented_connection_impl::read_loop() { VERIFY_CORRECT_THREAD(); const unsigned int BUFFER_SIZE = 16; static_assert(BUFFER_SIZE >= sizeof(message_header), "insufficient buffer"); const int LEFTOVER = BUFFER_SIZE - sizeof(message_header); _connected_time = fc::time_point::now(); fc::oexception exception_to_rethrow; bool call_on_connection_closed = false; try { message m; while( true ) { char buffer[BUFFER_SIZE]; _sock.read(buffer, BUFFER_SIZE); _bytes_received += BUFFER_SIZE; memcpy((char*)&m, buffer, sizeof(message_header)); FC_ASSERT( m.size <= MAX_MESSAGE_SIZE, "", ("m.size",m.size)("MAX_MESSAGE_SIZE",MAX_MESSAGE_SIZE) ); size_t remaining_bytes_with_padding = 16 * ((m.size - LEFTOVER + 15) / 16); m.data.resize(LEFTOVER + remaining_bytes_with_padding); //give extra 16 bytes to allow for padding added in send call std::copy(buffer + sizeof(message_header), buffer + sizeof(buffer), m.data.begin()); if (remaining_bytes_with_padding) { _sock.read(&m.data[LEFTOVER], remaining_bytes_with_padding); _bytes_received += remaining_bytes_with_padding; } m.data.resize(m.size); // truncate off the padding bytes _last_message_received_time = fc::time_point::now(); try { // message handling errors are warnings... _delegate->on_message(_self, m); } /// Dedicated catches needed to distinguish from general fc::exception catch ( const fc::canceled_exception& e ) { throw e; } catch ( const fc::eof_exception& e ) { throw e; } catch ( const fc::exception& e) { /// Here loop should be continued so exception should be just caught locally. wlog( "message transmission failed ${er}", ("er", e.to_detail_string() ) ); throw; } } } catch ( const fc::canceled_exception& e ) { wlog( "caught a canceled_exception in read_loop. this should mean we're in the process of deleting this object already, so there's no need to notify the delegate: ${e}", ("e", e.to_detail_string() ) ); throw; } catch ( const fc::eof_exception& e ) { wlog( "disconnected ${e}", ("e", e.to_detail_string() ) ); call_on_connection_closed = true; } catch ( const fc::exception& e ) { elog( "disconnected ${er}", ("er", e.to_detail_string() ) ); call_on_connection_closed = true; exception_to_rethrow = fc::unhandled_exception(FC_LOG_MESSAGE(warn, "disconnected: ${e}", ("e", e.to_detail_string()))); } catch ( const std::exception& e ) { elog( "disconnected ${er}", ("er", e.what() ) ); call_on_connection_closed = true; exception_to_rethrow = fc::unhandled_exception(FC_LOG_MESSAGE(warn, "disconnected: ${e}", ("e", e.what()))); } catch ( ... ) { elog( "unexpected exception" ); call_on_connection_closed = true; exception_to_rethrow = fc::unhandled_exception(FC_LOG_MESSAGE(warn, "disconnected: ${e}", ("e", fc::except_str()))); } if (call_on_connection_closed) _delegate->on_connection_closed(_self); if (exception_to_rethrow) throw *exception_to_rethrow; }
fc::api<network_node_api> login_api::network_node()const { FC_ASSERT(_network_node_api); return *_network_node_api; }
void committee_member_update_operation::validate()const { FC_ASSERT( fee.amount >= 0 ); if( new_url.valid() ) FC_ASSERT(new_url->size() < GRAPHENE_MAX_URL_LENGTH ); }
fc::api<database_api> login_api::database()const { FC_ASSERT(_database_api); return *_database_api; }
void chain_parameters::validate()const { current_fees->validate(); FC_ASSERT( reserve_percent_of_fee <= GRAPHENE_100_PERCENT ); FC_ASSERT( network_percent_of_fee <= GRAPHENE_100_PERCENT ); FC_ASSERT( lifetime_referrer_percent_of_fee <= GRAPHENE_100_PERCENT ); FC_ASSERT( network_percent_of_fee + lifetime_referrer_percent_of_fee <= GRAPHENE_100_PERCENT ); FC_ASSERT( block_interval >= GRAPHENE_MIN_BLOCK_INTERVAL ); FC_ASSERT( block_interval <= GRAPHENE_MAX_BLOCK_INTERVAL ); FC_ASSERT( block_interval > 0 ); FC_ASSERT( maintenance_interval > block_interval, "Maintenance interval must be longer than block interval" ); FC_ASSERT( maintenance_interval % block_interval == 0, "Maintenance interval must be a multiple of block interval" ); FC_ASSERT( maximum_transaction_size >= GRAPHENE_MIN_TRANSACTION_SIZE_LIMIT, "Transaction size limit is too low" ); FC_ASSERT( maximum_block_size >= GRAPHENE_MIN_BLOCK_SIZE_LIMIT, "Block size limit is too low" ); FC_ASSERT( maximum_time_until_expiration > block_interval, "Maximum transaction expiration time must be greater than a block interval" ); FC_ASSERT( maximum_proposal_lifetime - committee_proposal_review_period > block_interval, "Committee proposal review period must be less than the maximum proposal lifetime" ); }
fc::api<history_api> login_api::history() const { FC_ASSERT(_history_api); return *_history_api; }
bigint::bigint( const std::vector<char>& bige ) { n = BN_bin2bn( (const unsigned char*)bige.data(), bige.size(), NULL ); FC_ASSERT( n != nullptr ); }
flat_set<uint32_t> history_api::get_market_history_buckets()const { auto hist = _app.get_plugin<market_history_plugin>( "market_history" ); FC_ASSERT( hist ); return hist->tracked_buckets(); }
asset& operator += ( const asset& o ) { FC_ASSERT( asset_id == o.asset_id ); amount += o.amount; return *this; }
friend asset operator + ( const asset& a, const asset& b ) { FC_ASSERT( a.asset_id == b.asset_id ); return asset( a.amount + b.amount, a.asset_id ); }