void release_escrow_operation::evaluate( transaction_evaluation_state& eval_state )const { try { auto escrow_balance_record = eval_state.pending_state()->get_balance_record( this->escrow_id ); FC_ASSERT( escrow_balance_record.valid() ); if( this->amount_to_receiver < 0 ) FC_CAPTURE_AND_THROW( negative_withdraw, (amount_to_receiver) ); if( this->amount_to_sender < 0 ) FC_CAPTURE_AND_THROW( negative_withdraw, (amount_to_sender) ); if( !eval_state.check_signature( this->released_by ) ) FC_ASSERT( false, "transaction not signed by releasor" ); auto escrow_condition = escrow_balance_record->condition.as<withdraw_with_escrow>(); auto total_released = uint64_t(amount_to_sender) + uint64_t(amount_to_receiver); FC_ASSERT( total_released <= escrow_balance_record->balance ); FC_ASSERT( total_released >= amount_to_sender ); // check for addition overflow FC_ASSERT( total_released >= amount_to_receiver ); // check for addition overflow escrow_balance_record->balance -= total_released; auto asset_rec = eval_state.pending_state()->get_asset_record( escrow_balance_record->condition.asset_id ); if( amount_to_sender > 0 ) FC_ASSERT( asset_rec->address_is_whitelisted( escrow_condition.sender ) ); if( amount_to_receiver > 0 ) FC_ASSERT( asset_rec->address_is_whitelisted( escrow_condition.receiver ) ); const bool authority_is_retracting = asset_rec->flag_is_active( asset_record::retractable_balances ) && eval_state.verify_authority( asset_rec->authority ); if( escrow_condition.sender == this->released_by ) { FC_ASSERT( amount_to_sender == 0 ); FC_ASSERT( amount_to_receiver <= escrow_balance_record->balance ); if( !eval_state.check_signature( escrow_condition.sender ) && !authority_is_retracting) FC_CAPTURE_AND_THROW( missing_signature, (escrow_condition.sender) ); balance_record new_balance_record( escrow_condition.receiver, asset( amount_to_receiver, escrow_balance_record->asset_id() ), escrow_balance_record->slate_id() ); auto current_receiver_balance = eval_state.pending_state()->get_balance_record( new_balance_record.id()); if( current_receiver_balance ) current_receiver_balance->balance += amount_to_receiver; else current_receiver_balance = new_balance_record; eval_state.pending_state()->store_balance_record( *current_receiver_balance ); } else if( escrow_condition.receiver == this->released_by ) { FC_ASSERT( amount_to_receiver == 0 ); FC_ASSERT( amount_to_sender <= escrow_balance_record->balance ); if( !eval_state.check_signature( escrow_condition.receiver ) && !authority_is_retracting) FC_CAPTURE_AND_THROW( missing_signature, (escrow_condition.receiver) ); balance_record new_balance_record( escrow_condition.sender, asset( amount_to_sender, escrow_balance_record->asset_id() ), escrow_balance_record->slate_id() ); auto current_sender_balance = eval_state.pending_state()->get_balance_record( new_balance_record.id()); if( current_sender_balance ) current_sender_balance->balance += amount_to_sender; else current_sender_balance = new_balance_record; eval_state.pending_state()->store_balance_record( *current_sender_balance ); } else if( escrow_condition.escrow == this->released_by ) { if( !eval_state.check_signature( escrow_condition.escrow ) && !authority_is_retracting ) FC_CAPTURE_AND_THROW( missing_signature, (escrow_condition.escrow) ); // get a balance record for the receiver, create it if necessary and deposit funds { balance_record new_balance_record( escrow_condition.receiver, asset( amount_to_receiver, escrow_balance_record->asset_id() ), escrow_balance_record->slate_id() ); auto current_receiver_balance = eval_state.pending_state()->get_balance_record( new_balance_record.id()); if( current_receiver_balance ) current_receiver_balance->balance += amount_to_receiver; else current_receiver_balance = new_balance_record; eval_state.pending_state()->store_balance_record( *current_receiver_balance ); } // get a balance record for the sender, create it if necessary and deposit funds { balance_record new_balance_record( escrow_condition.sender, asset( amount_to_sender, escrow_balance_record->asset_id() ), escrow_balance_record->slate_id() ); auto current_sender_balance = eval_state.pending_state()->get_balance_record( new_balance_record.id()); if( current_sender_balance ) current_sender_balance->balance += amount_to_sender; else current_sender_balance = new_balance_record; eval_state.pending_state()->store_balance_record( *current_sender_balance ); } } else if( address() == this->released_by ) { if( !eval_state.check_signature( escrow_condition.sender ) && !authority_is_retracting) FC_CAPTURE_AND_THROW( missing_signature, (escrow_condition.sender) ); if( !eval_state.check_signature( escrow_condition.receiver ) && !authority_is_retracting) FC_CAPTURE_AND_THROW( missing_signature, (escrow_condition.receiver) ); // get a balance record for the receiver, create it if necessary and deposit funds { balance_record new_balance_record( escrow_condition.receiver, asset( amount_to_receiver, escrow_balance_record->asset_id() ), escrow_balance_record->slate_id() ); auto current_receiver_balance = eval_state.pending_state()->get_balance_record( new_balance_record.id()); if( current_receiver_balance ) current_receiver_balance->balance += amount_to_receiver; else current_receiver_balance = new_balance_record; eval_state.pending_state()->store_balance_record( *current_receiver_balance ); } // get a balance record for the sender, create it if necessary and deposit funds { balance_record new_balance_record( escrow_condition.sender, asset( amount_to_sender, escrow_balance_record->asset_id() ), escrow_balance_record->slate_id() ); auto current_sender_balance = eval_state.pending_state()->get_balance_record( new_balance_record.id()); if( current_sender_balance ) current_sender_balance->balance += amount_to_sender; else current_sender_balance = new_balance_record; eval_state.pending_state()->store_balance_record( *current_sender_balance ); } } else { FC_ASSERT( false, "not released by a party to the escrow transaction" ); } eval_state.pending_state()->store_balance_record( *escrow_balance_record ); } FC_CAPTURE_AND_RETHROW( (*this) ) }
void release_escrow_operation::evaluate( transaction_evaluation_state& eval_state ) { try { FC_ASSERT( !"This operation is not enabled yet!" ); auto escrow_balance_record = eval_state._current_state->get_balance_record( this->escrow_id ); FC_ASSERT( escrow_balance_record.valid() ); if( !eval_state.check_signature( this->released_by ) ) FC_ASSERT( !"transaction not signed by releasor" ); auto escrow_condition = escrow_balance_record->condition.as<withdraw_with_escrow>(); auto total_released = amount_to_sender + amount_to_receiver; FC_ASSERT( total_released <= escrow_balance_record->balance ); FC_ASSERT( total_released >= amount_to_sender ); // check for addition overflow escrow_balance_record->balance -= total_released; auto asset_rec = eval_state._current_state->get_asset_record( escrow_balance_record->condition.asset_id ); if( asset_rec->is_restricted() ) { FC_ASSERT( eval_state._current_state->get_authorization( escrow_balance_record->condition.asset_id, escrow_condition.receiver ) ); } if( asset_rec->is_retractable() ) { if( eval_state.verify_authority( asset_rec->authority ) ) { // } } if( escrow_condition.sender == this->released_by ) { FC_ASSERT( amount_to_sender == 0 ); FC_ASSERT( amount_to_receiver <= escrow_balance_record->balance ); if( !eval_state.check_signature( escrow_condition.sender ) ) FC_CAPTURE_AND_THROW( missing_signature, (escrow_condition.sender) ); balance_record new_balance_record( escrow_condition.receiver, asset( amount_to_receiver, escrow_balance_record->asset_id() ), escrow_balance_record->slate_id() ); auto current_receiver_balance = eval_state._current_state->get_balance_record( new_balance_record.id()); if( current_receiver_balance ) current_receiver_balance->balance += amount_to_receiver; else current_receiver_balance = new_balance_record; eval_state._current_state->store_balance_record( *current_receiver_balance ); } else if( escrow_condition.receiver == this->released_by ) { FC_ASSERT( amount_to_receiver == 0 ); FC_ASSERT( amount_to_sender <= escrow_balance_record->balance ); if( !eval_state.check_signature( escrow_condition.receiver ) ) FC_CAPTURE_AND_THROW( missing_signature, (escrow_condition.receiver) ); balance_record new_balance_record( escrow_condition.sender, asset( amount_to_sender, escrow_balance_record->asset_id() ), escrow_balance_record->slate_id() ); auto current_sender_balance = eval_state._current_state->get_balance_record( new_balance_record.id()); if( current_sender_balance ) current_sender_balance->balance += amount_to_sender; else current_sender_balance = new_balance_record; eval_state._current_state->store_balance_record( *current_sender_balance ); } else if( escrow_condition.escrow == this->released_by ) { if( !eval_state.check_signature( escrow_condition.escrow ) ) FC_CAPTURE_AND_THROW( missing_signature, (escrow_condition.escrow) ); // get a balance record for the receiver, create it if necessary and deposit funds { balance_record new_balance_record( escrow_condition.receiver, asset( amount_to_receiver, escrow_balance_record->asset_id() ), escrow_balance_record->slate_id() ); auto current_receiver_balance = eval_state._current_state->get_balance_record( new_balance_record.id()); if( current_receiver_balance ) current_receiver_balance->balance += amount_to_receiver; else current_receiver_balance = new_balance_record; eval_state._current_state->store_balance_record( *current_receiver_balance ); } // get a balance record for the sender, create it if necessary and deposit funds { balance_record new_balance_record( escrow_condition.sender, asset( amount_to_sender, escrow_balance_record->asset_id() ), escrow_balance_record->slate_id() ); auto current_sender_balance = eval_state._current_state->get_balance_record( new_balance_record.id()); if( current_sender_balance ) current_sender_balance->balance += amount_to_sender; else current_sender_balance = new_balance_record; eval_state._current_state->store_balance_record( *current_sender_balance ); } } else if( address() == this->released_by ) { if( !eval_state.check_signature( escrow_condition.sender ) ) FC_CAPTURE_AND_THROW( missing_signature, (escrow_condition.sender) ); if( !eval_state.check_signature( escrow_condition.receiver ) ) FC_CAPTURE_AND_THROW( missing_signature, (escrow_condition.receiver) ); // get a balance record for the receiver, create it if necessary and deposit funds { balance_record new_balance_record( escrow_condition.receiver, asset( amount_to_receiver, escrow_balance_record->asset_id() ), escrow_balance_record->slate_id() ); auto current_receiver_balance = eval_state._current_state->get_balance_record( new_balance_record.id()); if( current_receiver_balance ) current_receiver_balance->balance += amount_to_receiver; else current_receiver_balance = new_balance_record; eval_state._current_state->store_balance_record( *current_receiver_balance ); } // get a balance record for the sender, create it if necessary and deposit funds { balance_record new_balance_record( escrow_condition.sender, asset( amount_to_sender, escrow_balance_record->asset_id() ), escrow_balance_record->slate_id() ); auto current_sender_balance = eval_state._current_state->get_balance_record( new_balance_record.id()); if( current_sender_balance ) current_sender_balance->balance += amount_to_sender; else current_sender_balance = new_balance_record; eval_state._current_state->store_balance_record( *current_sender_balance ); } } else { FC_ASSERT( !"not released by a party to the escrow transaction" ); } eval_state._current_state->store_balance_record( *escrow_balance_record ); } FC_CAPTURE_AND_RETHROW( (*this) ) }