Skip to content

Commit

Permalink
Merge branch '143-escrow' into develop #143
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Vandeberg committed Aug 18, 2016
2 parents 676d9cd + 319eb38 commit aa3d002
Show file tree
Hide file tree
Showing 7 changed files with 243 additions and 18 deletions.
13 changes: 13 additions & 0 deletions libraries/app/database_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,19 @@ optional< account_recovery_request_object > database_api::get_recovery_request(
return result;
}

optional< escrow_object > database_api::get_escrow( string from, uint32_t escrow_id )const
{
optional< escrow_object > result;

try
{
result = my->_db.get_escrow( from, escrow_id );
}
catch ( ... ) {}

return result;
}

//////////////////////////////////////////////////////////////////////
// //
// Witnesses //
Expand Down
3 changes: 3 additions & 0 deletions libraries/app/include/steemit/app/database_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ class database_api

optional< account_recovery_request_object > get_recovery_request( string account ) const;

optional< escrow_object > get_escrow( string from, uint32_t escrow_id )const;

///////////////
// Witnesses //
///////////////
Expand Down Expand Up @@ -449,6 +451,7 @@ FC_API(steemit::app::database_api,
(get_account_history)
(get_owner_history)
(get_recovery_request)
(get_escrow)

// Market
(get_order_book)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,16 +251,18 @@ namespace steemit { namespace chain {
{
string from;
string to;
string agent;
uint32_t escrow_id = 0;

asset sbd_amount = asset( 0, SBD_SYMBOL );
asset steem_amount = asset( 0, STEEM_SYMBOL );

uint32_t escrow_id = 0;
string agent;
asset fee;
string json_meta;

time_point_sec ratification_deadline;
time_point_sec escrow_expiration;

string json_meta;

void validate()const;
void get_required_active_authorities( flat_set<string>& a )const{ a.insert(from); }
};
Expand Down Expand Up @@ -292,8 +294,8 @@ namespace steemit { namespace chain {
{
string from;
string to;
uint32_t escrow_id = 0;
string who;
uint32_t escrow_id = 0;

void validate()const;
void get_required_active_authorities( flat_set<string>& a )const{ a.insert(who); }
Expand All @@ -312,9 +314,9 @@ namespace steemit { namespace chain {
struct escrow_release_operation : public base_operation
{
string from;
uint32_t escrow_id = 0;
string to; ///< the account that should receive funds (might be from, might be to
string who; ///< the account that is attempting to release the funds, determines valid 'to'
uint32_t escrow_id = 0;
asset sbd_amount = asset( 0, SBD_SYMBOL ); ///< the amount of sbd to release
asset steem_amount = asset( 0, STEEM_SYMBOL ); ///< the amount of steem to release

Expand Down Expand Up @@ -876,8 +878,8 @@ FC_REFLECT( steemit::chain::comment_options_operation, (author)(permlink)(max_ac

FC_REFLECT( steemit::chain::escrow_transfer_operation, (from)(to)(sbd_amount)(steem_amount)(escrow_id)(agent)(fee)(json_meta)(ratification_deadline)(escrow_expiration) );
FC_REFLECT( steemit::chain::escrow_approve_operation, (from)(to)(agent)(who)(escrow_id)(approve) );
FC_REFLECT( steemit::chain::escrow_dispute_operation, (from)(to)(escrow_id)(who) );
FC_REFLECT( steemit::chain::escrow_release_operation, (from)(to)(escrow_id)(who)(sbd_amount)(steem_amount) );
FC_REFLECT( steemit::chain::escrow_dispute_operation, (from)(to)(who)(escrow_id) );
FC_REFLECT( steemit::chain::escrow_release_operation, (from)(to)(who)(escrow_id)(sbd_amount)(steem_amount) );
FC_REFLECT( steemit::chain::challenge_authority_operation, (challenger)(challenged)(require_owner) );
FC_REFLECT( steemit::chain::prove_authority_operation, (challenged)(require_owner) );
FC_REFLECT( steemit::chain::request_account_recovery_operation, (recovery_account)(account_to_recover)(new_owner_authority)(extensions) );
Expand Down
1 change: 1 addition & 0 deletions libraries/chain/steem_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,7 @@ void escrow_release_evaluator::do_apply( const escrow_release_operation& o )
FC_ASSERT( e.steem_balance >= o.steem_amount, "Release amount exceeds escrow balance" );
FC_ASSERT( e.sbd_balance >= o.sbd_amount, "Release amount exceeds escrow balance" );
FC_ASSERT( o.to == e.from || o.to == e.to, "Funds must be released to 'from' or 'to'" );
FC_ASSERT( e.to_approved && e.agent_approved, "Funds cannot be released prior to escrow approval" );

// If there is a dispute regardless of expiration, the agent can release funds to either party
if( e.disputed )
Expand Down
89 changes: 89 additions & 0 deletions libraries/wallet/include/steemit/wallet/wallet.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,95 @@ class wallet_api
*/
annotated_signed_transaction transfer(string from, string to, asset amount, string memo, bool broadcast = false);

/**
* Transfer funds from one account to another using escrow. STEEM and SBD can be transferred.
*
* @param from The account the funds are coming from
* @param to The account the funds are going to
* @param agent The account acting as the agent in case of dispute
* @param escrow_id A unique id for the escrow transfer. (from, escrow_id) must be a unique pair
* @param sbd_amount The amount of SBD to transfer
* @param steem_amount The amount of STEEM to transfer
* @param fee The fee paid to the agent
* @param ratification_deadline The deadline for 'to' and 'agent' to approve the escrow transfer
* @param escrow_expiration The expiration of the escrow transfer, after which either party can claim the funds
* @param json_meta JSON encoded meta data
* @param broadcast true if you wish to broadcast the transaction
*/
annotated_signed_transaction escrow_transfer(
string from,
string to,
string agent,
uint32_t escrow_id,
asset sbd_amount,
asset steem_amount,
asset fee,
time_point_sec ratification_deadline,
time_point_sec escrow_expiration,
string json_meta,
bool broadcast = false
);

/**
* Approve a proposed escrow transfer. Funds cannot be released until after approval. This is in lieu of requiring
* multi-sig on escrow_transfer
*
* @param from The account that funded the escrow
* @param to The destination of the escrow
* @param agent The account acting as the agent in case of dispute
* @param who The account approving the escrow transfer (either 'to' or 'agent)
* @param escrow_id A unique id for the escrow transfer
* @param approve true to approve the escrow transfer, otherwise cancels it and refunds 'from'
* @param broadcast true if you wish to broadcast the transaction
*/
annotated_signed_transaction escrow_approve(
string from,
string to,
string agent,
string who,
uint32_t escrow_id,
bool approve,
bool broadcast = false
);

/**
* Raise a dispute on the escrow transfer before it expires
*
* @param from The account that funded the escrow
* @param to The destination of the escrow
* @param who The account raising the dispute (either 'from' or 'to')
* @param escrow_id A unique id for the escrow transfer
* @param broadcast true if you wish to broadcast the transaction
*/
annotated_signed_transaction escrow_dispute(
string from,
string to,
string who,
uint32_t escrow_id,
bool broadcast = false
);

/**
* Release funds help in escrow
*
* @param from The account that funded the escrow
* @param to The account that will receive funds being released
* @param who The account authorizing the release
* @param escrow_id A unique id for the escrow transfer
* @param sbd_amount The amount of SBD that will be released
* @param steem_amount The amount of STEEM that will be released
* @param broadcast true if you wish to broadcast the transaction
*/
annotated_signed_transaction escrow_release(
string from,
string to,
string who,
uint32_t escrow_id,
asset sbd_amount,
asset steem_amount,
bool broadcast = false
);

/**
* Transfer STEEM into a vesting fund represented by vesting shares (VESTS). VESTS are required to vesting
* for a minimum of one coin year and can be withdrawn once a week over a two year withdraw period.
Expand Down
106 changes: 106 additions & 0 deletions libraries/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1662,6 +1662,112 @@ annotated_signed_transaction wallet_api::transfer(string from, string to, asset
return my->sign_transaction( tx, broadcast );
} FC_CAPTURE_AND_RETHROW( (from)(to)(amount)(memo)(broadcast) ) }

annotated_signed_transaction wallet_api::escrow_transfer(
string from,
string to,
string agent,
uint32_t escrow_id,
asset sbd_amount,
asset steem_amount,
asset fee,
time_point_sec ratification_deadline,
time_point_sec escrow_expiration,
string json_meta,
bool broadcast
)
{
FC_ASSERT( !is_locked() );
escrow_transfer_operation op;
op.from = from;
op.to = to;
op.agent = agent;
op.escrow_id = escrow_id;
op.sbd_amount = sbd_amount;
op.steem_amount = steem_amount;
op.fee = fee;
op.ratification_deadline = ratification_deadline;
op.escrow_expiration = escrow_expiration;
op.json_meta = json_meta;

signed_transaction tx;
tx.operations.push_back( op );
tx.validate();

return my->sign_transaction( tx, broadcast );
}

annotated_signed_transaction wallet_api::escrow_approve(
string from,
string to,
string agent,
string who,
uint32_t escrow_id,
bool approve,
bool broadcast
)
{
FC_ASSERT( !is_locked() );
escrow_approve_operation op;
op.from = from;
op.to = to;
op.agent = agent;
op.who = who;
op.escrow_id = escrow_id;
op.approve = approve;

signed_transaction tx;
tx.operations.push_back( op );
tx.validate();

return my->sign_transaction( tx, broadcast );
}

annotated_signed_transaction wallet_api::escrow_dispute(
string from,
string to,
string who,
uint32_t escrow_id,
bool broadcast
)
{
escrow_dispute_operation op;
op.from = from;
op.to = to;
op.who = who;
op.escrow_id = escrow_id;

signed_transaction tx;
tx.operations.push_back( op );
tx.validate();

return my->sign_transaction( tx, broadcast );
}

annotated_signed_transaction wallet_api::escrow_release(
string from,
string to,
string who,
uint32_t escrow_id,
asset sbd_amount,
asset steem_amount,
bool broadcast
)
{
escrow_release_operation op;
op.from = from;
op.to = to;
op.who = who;
op.escrow_id = escrow_id;
op.sbd_amount = sbd_amount;
op.steem_amount = steem_amount;

signed_transaction tx;
tx.operations.push_back( op );
tx.validate();

return my->sign_transaction( tx, broadcast );
}

annotated_signed_transaction wallet_api::transfer_to_vesting(string from, string to, asset amount, bool broadcast )
{
FC_ASSERT( !is_locked() );
Expand Down
31 changes: 21 additions & 10 deletions tests/tests/operation_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4299,6 +4299,26 @@ BOOST_AUTO_TEST_CASE( escrow_release_apply )
et_op.ratification_deadline = db.head_block_time() + STEEMIT_BLOCK_INTERVAL;
et_op.escrow_expiration = db.head_block_time() + 2 * STEEMIT_BLOCK_INTERVAL;

signed_transaction tx;
tx.operations.push_back( et_op );

tx.set_expiration( db.head_block_time() + STEEMIT_MAX_TIME_UNTIL_EXPIRATION );
tx.sign( alice_private_key, db.get_chain_id() );
db.push_transaction( tx, 0 );


BOOST_TEST_MESSAGE( "--- failure releasing funds prior to approval" );
escrow_release_operation op;
op.from = et_op.from;
op.to = et_op.to;
op.who = et_op.from;
op.steem_amount = ASSET( "0.100 TESTS" );

tx.clear();
tx.operations.push_back( op );
tx.sign( alice_private_key, db.get_chain_id() );
STEEMIT_REQUIRE_THROW( db.push_transaction( tx, 0 ), fc::assert_exception );

escrow_approve_operation ea_b_op;
ea_b_op.from = "alice";
ea_b_op.to = "bob";
Expand All @@ -4311,24 +4331,15 @@ BOOST_AUTO_TEST_CASE( escrow_release_apply )
ea_s_op.agent = "sam";
ea_s_op.who = "sam";

signed_transaction tx;
tx.operations.push_back( et_op );
tx.clear();
tx.operations.push_back( ea_b_op );
tx.operations.push_back( ea_s_op );
tx.set_expiration( db.head_block_time() + STEEMIT_MAX_TIME_UNTIL_EXPIRATION );
tx.sign( alice_private_key, db.get_chain_id() );
tx.sign( bob_private_key, db.get_chain_id() );
tx.sign( sam_private_key, db.get_chain_id() );
db.push_transaction( tx, 0 );


BOOST_TEST_MESSAGE( "--- failure when 'agent' attempts to release non-disputed escrow to 'to'" );
escrow_release_operation op;
op.from = "alice";
op.to = et_op.to;
op.who = et_op.agent;
op.steem_amount = ASSET( "0.100 TESTS" );

tx.clear();
tx.operations.push_back( op );
tx.sign( sam_private_key, db.get_chain_id() );
Expand Down

0 comments on commit aa3d002

Please sign in to comment.