transaction_builder& transaction_builder::cancel_market_order( const order_id_type& order_id ) { try { const auto order = _wimpl->_blockchain->get_market_order( order_id ); if( !order.valid() ) FC_THROW_EXCEPTION( unknown_market_order, "Cannot find that market order!" ); const auto owner_address = order->get_owner(); const auto owner_key_record = _wimpl->_wallet_db.lookup_key( owner_address ); if( !owner_key_record.valid() || !owner_key_record->has_private_key() ) FC_THROW_EXCEPTION( private_key_not_found, "Cannot find the private key for that market order!" ); const auto account_record = _wimpl->_wallet_db.lookup_account( owner_key_record->account_address ); FC_ASSERT( account_record.valid() ); asset balance = order->get_balance(); if( balance.amount == 0 ) FC_CAPTURE_AND_THROW( zero_amount, (order) ); switch( order_type_enum( order->type ) ) { case ask_order: trx.ask( -balance, order->market_index.order_price, owner_address ); break; case bid_order: trx.bid( -balance, order->market_index.order_price, owner_address ); break; case short_order: trx.short_sell( -balance, order->market_index.order_price, owner_address ); break; default: FC_THROW_EXCEPTION( invalid_cancel, "You cannot cancel this type of order!" ); break; } //Credit this account the cancel proceeds credit_balance(account_record->owner_address(), balance); //Set order key for this account if not already set if( order_keys.find(account_record->owner_address()) == order_keys.end() ) { const oasset_record asset_record = _wimpl->_blockchain->get_asset_record( balance.asset_id ); FC_ASSERT( asset_record.valid() ); if( asset_record->flag_is_active( asset_record::restricted_accounts ) ) order_keys[ account_record->owner_address() ] = account_record->active_key(); else order_keys[ account_record->owner_address() ] = owner_key_record->public_key; } auto entry = ledger_entry(); entry.from_account = owner_key_record->public_key; entry.to_account = account_record->owner_key; entry.amount = balance; entry.memo = "cancel " + order->get_small_id(); transaction_record.is_market = true; transaction_record.ledger_entries.push_back( entry ); required_signatures.insert( owner_address ); return *this; } FC_CAPTURE_AND_RETHROW( (order_id) ) }
transaction_builder& transaction_builder::update_asset( const string& symbol, const optional<string>& name, const optional<string>& description, const optional<variant>& public_data, const optional<double>& maximum_share_supply, const optional<uint64_t>& precision ) { try { const oasset_record asset_record = _wimpl->_blockchain->get_asset_record( symbol ); FC_ASSERT( asset_record.valid() ); const oaccount_record issuer_account_record = _wimpl->_blockchain->get_account_record( asset_record->issuer_account_id ); if( !issuer_account_record.valid() ) FC_THROW_EXCEPTION( unknown_account, "Unknown issuer account id!" ); trx.update_asset( asset_record->id, name, description, public_data, maximum_share_supply, precision ); deduct_balance( issuer_account_record->active_key(), asset() ); ledger_entry entry; entry.from_account = issuer_account_record->active_key(); entry.to_account = issuer_account_record->active_key(); entry.memo = "update " + symbol + " asset"; transaction_record.ledger_entries.push_back( entry ); required_signatures.insert( issuer_account_record->active_key() ); return *this; } FC_CAPTURE_AND_RETHROW( (symbol)(name)(description)(public_data)(maximum_share_supply)(precision) ) }
transaction_builder& transaction_builder::submit_bid(const wallet_account_record& from_account, const asset& real_quantity, const price& quote_price) { try { validate_market(quote_price.quote_asset_id, quote_price.base_asset_id); asset cost; if( real_quantity.asset_id == quote_price.quote_asset_id ) cost = real_quantity; else { cost = real_quantity * quote_price; FC_ASSERT(cost.asset_id == quote_price.quote_asset_id); } const oasset_record base_asset_record = _wimpl->_blockchain->get_asset_record( quote_price.base_asset_id ); FC_ASSERT( base_asset_record.valid() ); public_key_type order_key; if( base_asset_record->flag_is_active( asset_record::restricted_accounts ) ) order_key = from_account.active_key(); else order_key = order_key_for_account( from_account.owner_address(), from_account.name ); order_keys[ from_account.owner_address() ] = order_key; //Charge this account for the bid deduct_balance(from_account.owner_address(), cost); trx.bid(cost, quote_price, order_key); if( trx.expiration == time_point_sec() ) trx.expiration = blockchain::now() + WALLET_DEFAULT_MARKET_TRANSACTION_EXPIRATION_SEC; auto entry = ledger_entry(); entry.from_account = from_account.owner_key; entry.to_account = order_key; entry.amount = cost; entry.memo = "buy " + _wimpl->_blockchain->get_asset_symbol(quote_price.base_asset_id) + " @ " + _wimpl->_blockchain->to_pretty_price(quote_price); transaction_record.is_market = true; transaction_record.ledger_entries.push_back(entry); required_signatures.insert(order_key); return *this; } FC_CAPTURE_AND_RETHROW( (from_account.name)(real_quantity)(quote_price) ) }
void deposit_operation::evaluate( transaction_evaluation_state& eval_state )const { try { if( this->amount <= 0 ) FC_CAPTURE_AND_THROW( negative_deposit, (amount) ); switch( withdraw_condition_types( this->condition.type ) ) { case withdraw_signature_type: case withdraw_multisig_type: case withdraw_escrow_type: break; default: FC_CAPTURE_AND_THROW( invalid_withdraw_condition, (*this) ); } const balance_id_type deposit_balance_id = this->balance_id(); obalance_record cur_record = eval_state.pending_state()->get_balance_record( deposit_balance_id ); if( !cur_record.valid() ) { cur_record = balance_record( this->condition ); if( this->condition.type == withdraw_escrow_type ) cur_record->meta_data = variant_object("creating_transaction_id", eval_state.trx.id() ); } if( cur_record->balance == 0 ) { cur_record->deposit_date = eval_state.pending_state()->now(); } else { fc::uint128 old_sec_since_epoch( cur_record->deposit_date.sec_since_epoch() ); fc::uint128 new_sec_since_epoch( eval_state.pending_state()->now().sec_since_epoch() ); fc::uint128 avg = (old_sec_since_epoch * cur_record->balance) + (new_sec_since_epoch * this->amount); avg /= (cur_record->balance + this->amount); cur_record->deposit_date = time_point_sec( avg.to_integer() ); } cur_record->balance += this->amount; eval_state.sub_balance( asset( this->amount, cur_record->asset_id() ) ); if( cur_record->condition.asset_id == 0 && cur_record->condition.slate_id ) eval_state.adjust_vote( cur_record->condition.slate_id, this->amount ); cur_record->last_update = eval_state.pending_state()->now(); const oasset_record asset_rec = eval_state.pending_state()->get_asset_record( cur_record->condition.asset_id ); FC_ASSERT( asset_rec.valid() ); if( asset_rec->is_market_issued() ) { FC_ASSERT( cur_record->condition.slate_id == 0 ); } const auto& owners = cur_record->owners(); for( const address& owner : owners ) { FC_ASSERT( asset_rec->address_is_whitelisted( owner ) ); } eval_state.pending_state()->store_balance_record( *cur_record ); } FC_CAPTURE_AND_RETHROW( (*this) ) }