tests: Set expirations with helper function instead of ad hoc in each test

This commit is contained in:
theoreticalbts 2015-07-23 15:11:55 -04:00
parent 430bbe42ab
commit 86456ba6e0
7 changed files with 69 additions and 58 deletions

View file

@ -41,6 +41,8 @@
#include "database_fixture.hpp"
using namespace graphene::chain::test;
namespace graphene { namespace chain {
using std::cout;
@ -92,7 +94,7 @@ database_fixture::database_fixture()
generate_block();
trx.set_expiration(db.head_block_time() + fc::minutes(1));
set_expiration( db, trx );
} catch ( const fc::exception& e )
{
edump( (e.to_detail_string()) );
@ -598,7 +600,6 @@ const witness_object& database_fixture::create_witness( const account_object& ow
return db.get<witness_object>(ptx.operation_results[0].get<object_id_type>());
} FC_CAPTURE_AND_RETHROW() }
uint64_t database_fixture::fund(
const account_object& account,
const asset& amount /* = asset(500000) */
@ -651,7 +652,6 @@ asset database_fixture::cancel_limit_order( const limit_order_object& order )
return processed.operation_results[0].get<asset>();
}
void database_fixture::transfer(
account_id_type from,
account_id_type to,
@ -670,7 +670,7 @@ void database_fixture::transfer(
{
try
{
trx.set_expiration(db.head_block_time() + fc::minutes(1));
set_expiration( db, trx );
transfer_operation trans;
trans.from = from.id;
trans.to = to.id;
@ -690,7 +690,7 @@ void database_fixture::transfer(
void database_fixture::update_feed_producers( const asset_object& mia, flat_set<account_id_type> producers )
{ try {
trx.set_expiration(db.head_block_time() + fc::minutes(1));
set_expiration( db, trx );
trx.operations.clear();
asset_update_feed_producers_operation op;
op.asset_to_update = mia.id;
@ -705,10 +705,9 @@ void database_fixture::update_feed_producers( const asset_object& mia, flat_set<
verify_asset_supplies(db);
} FC_CAPTURE_AND_RETHROW( (mia)(producers) ) }
void database_fixture::publish_feed( const asset_object& mia, const account_object& by, const price_feed& f )
void database_fixture::publish_feed( const asset_object& mia, const account_object& by, const price_feed& f )
{
trx.set_expiration(db.head_block_time() + fc::minutes(1));
set_expiration( db, trx );
trx.operations.clear();
asset_publish_feed_operation op;
@ -726,7 +725,7 @@ void database_fixture::publish_feed( const asset_object& mia, const account_obj
void database_fixture::force_global_settle( const asset_object& what, const price& p )
{ try {
trx.set_expiration(db.head_block_time() + fc::minutes(1));
set_expiration( db, trx );
trx.operations.clear();
asset_global_settle_operation sop;
sop.issuer = what.issuer;
@ -742,7 +741,7 @@ void database_fixture::force_global_settle( const asset_object& what, const pric
operation_result database_fixture::force_settle( const account_object& who, asset what )
{ try {
trx.set_expiration(db.head_block_time() + fc::minutes(1));
set_expiration( db, trx );
trx.operations.clear();
asset_settle_operation sop;
sop.account = who.id;
@ -759,7 +758,7 @@ operation_result database_fixture::force_settle( const account_object& who, asse
const call_order_object* database_fixture::borrow(const account_object& who, asset what, asset collateral)
{ try {
trx.set_expiration(db.head_block_time() + fc::minutes(1));
set_expiration( db, trx );
trx.operations.clear();
call_order_update_operation update;
update.funding_account = who.id;
@ -781,9 +780,9 @@ const call_order_object* database_fixture::borrow(const account_object& who, ass
return call_obj;
} FC_CAPTURE_AND_RETHROW( (who.name)(what)(collateral) ) }
void database_fixture::cover(const account_object& who, asset what, asset collateral)
void database_fixture::cover(const account_object& who, asset what, asset collateral)
{ try {
trx.set_expiration(db.head_block_time() + fc::minutes(1));
set_expiration( db, trx );
trx.operations.clear();
call_order_update_operation update;
update.funding_account = who.id;
@ -958,7 +957,6 @@ void database_fixture::print_joint_market( const string& syma, const string& sym
}
}
int64_t database_fixture::get_balance( account_id_type account, asset_id_type a )const
{
return db.get_balance(account, a).amount.value;
@ -971,6 +969,14 @@ int64_t database_fixture::get_balance( const account_object& account, const asse
namespace test {
void set_expiration( const database& db, transaction& tx )
{
const chain_parameters& params = db.get_global_properties().parameters;
tx.set_reference_block(db.head_block_id());
tx.set_expiration( db.head_block_time() + fc::seconds( params.block_interval * 3 ) );
return;
}
bool _push_block( database& db, const signed_block& b, uint32_t skip_flags /* = 0 */ )
{
return db.push_block( b, skip_flags);

View file

@ -273,6 +273,9 @@ struct database_fixture {
};
namespace test {
/// set a reasonable expiration time for the transaction
void set_expiration( const database& db, transaction& tx );
bool _push_block( database& db, const signed_block& b, uint32_t skip_flags = 0 );
processed_transaction _push_transaction( database& db, const signed_transaction& tx, uint32_t skip_flags = 0 );
}

View file

@ -33,6 +33,7 @@
#include "../common/database_fixture.hpp"
using namespace graphene::chain;
using namespace graphene::chain::test;
BOOST_FIXTURE_TEST_SUITE( authority_tests, database_fixture )
@ -337,8 +338,7 @@ BOOST_AUTO_TEST_CASE( proposed_single_account )
}
trx.operations.push_back(op);
trx.set_expiration( db.head_block_time() + fc::seconds( 3 * db.get_global_properties().parameters.block_interval ));
trx.set_reference_block( db.head_block_id() );
set_expiration( db, trx );
trx.sign( init_account_priv_key );
const proposal_object& proposal = db.get<proposal_object>(PUSH_TX( db, trx ).operation_results.front().get<object_id_type>());
@ -552,7 +552,7 @@ BOOST_FIXTURE_TEST_CASE( fired_committee_members, database_fixture )
op.new_options = nathan->options;
op.new_options->votes = committee_members;
trx.operations.push_back(op);
trx.set_expiration(db.head_block_time() + GRAPHENE_DEFAULT_MAX_TIME_UNTIL_EXPIRATION);
set_expiration( db, trx );
PUSH_TX( db, trx, ~0 );
trx.operations.clear();
}
@ -850,7 +850,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_complete, database_fixture )
std::swap(uop.key_approvals_to_add, uop.key_approvals_to_remove);
// Survive trx dupe check
trx.set_expiration( db.head_block_time() + fc::seconds( 5 * db.get_global_properties().parameters.block_interval ));
set_expiration( db, trx );
trx.set_reference_block( db.head_block_id() );
trx.operations.push_back(uop);
trx.sign(nathan_key);
@ -909,7 +909,7 @@ BOOST_FIXTURE_TEST_CASE( max_authority_membership, database_fixture )
private_key_type privkey = generate_private_key( seed );
private_keys.push_back( privkey );
}
tx.set_expiration( db.head_block_time() + fc::minutes(5) );
set_expiration( db, tx );
ptx = PUSH_TX( db, tx, ~0 );
vector<public_key_type> key_ids;
@ -947,7 +947,7 @@ BOOST_FIXTURE_TEST_CASE( max_authority_membership, database_fixture )
anon_create_op.name = generate_anon_acct_name();
tx.operations.push_back( anon_create_op );
tx.set_expiration( db.head_block_time() + fc::minutes(5) );
set_expiration( db, tx );
if( num_keys > max_authority_membership )
{
@ -1122,7 +1122,7 @@ BOOST_FIXTURE_TEST_CASE( get_required_signatures_test, database_fixture )
op.active = auth;
op.owner = auth;
tx.operations.push_back( op );
tx.set_expiration( db.head_block_time() + fc::minutes( 5 ) );
set_expiration( db, tx );
PUSH_TX( db, tx, database::skip_transaction_signatures | database::skip_authority_check );
} ;
@ -1236,7 +1236,7 @@ BOOST_FIXTURE_TEST_CASE( nonminimal_sig_test, database_fixture )
op.active = auth;
op.owner = auth;
tx.operations.push_back( op );
tx.set_expiration( db.head_block_time() + fc::minutes( 5 ) );
set_expiration( db, tx );
PUSH_TX( db, tx, database::skip_transaction_signatures | database::skip_authority_check );
} ;

View file

@ -33,6 +33,7 @@
#include "../common/database_fixture.hpp"
using namespace graphene::chain;
using namespace graphene::chain::test;
genesis_state_type make_genesis() {
genesis_state_type genesis_state;
@ -287,7 +288,7 @@ BOOST_AUTO_TEST_CASE( undo_pending )
t.amount = asset( 10000000 );
{
signed_transaction trx;
trx.set_expiration(db.head_block_time() + fc::minutes(1));
set_expiration( db, trx );
trx.operations.push_back(t);
PUSH_TX( db, trx, ~0 );
@ -297,7 +298,7 @@ BOOST_AUTO_TEST_CASE( undo_pending )
}
signed_transaction trx;
trx.set_expiration( now + db.get_global_properties().parameters.maximum_time_until_expiration );
set_expiration( db, trx );
account_id_type nathan_id = account_idx.get_next_id();
account_create_operation cop;
cop.registrar = GRAPHENE_TEMP_ACCOUNT;
@ -314,7 +315,7 @@ BOOST_AUTO_TEST_CASE( undo_pending )
BOOST_CHECK(nathan_id(db).name == "nathan");
trx.clear();
trx.set_expiration(db.head_block_time() + db.get_global_properties().parameters.maximum_time_until_expiration-1);
set_expiration( db, trx );
t.fee = asset(1);
t.from = account_id_type(1);
t.to = nathan_id;
@ -322,7 +323,7 @@ BOOST_AUTO_TEST_CASE( undo_pending )
trx.operations.push_back(t);
db.push_transaction(trx, ~0);
trx.clear();
trx.set_expiration(db.head_block_time() + db.get_global_properties().parameters.maximum_time_until_expiration-2);
set_expiration( db, trx );
trx.operations.push_back(t);
db.push_transaction(trx, ~0);
@ -352,7 +353,7 @@ BOOST_AUTO_TEST_CASE( switch_forks_undo_create )
const graphene::db::index& account_idx = db1.get_index(protocol_ids, account_object_type);
signed_transaction trx;
trx.set_expiration(now + db1.get_global_properties().parameters.maximum_time_until_expiration);
set_expiration( db1, trx );
account_id_type nathan_id = account_idx.get_next_id();
account_create_operation cop;
cop.registrar = GRAPHENE_TEMP_ACCOUNT;
@ -412,7 +413,7 @@ BOOST_AUTO_TEST_CASE( duplicate_transactions )
const graphene::db::index& account_idx = db1.get_index(protocol_ids, account_object_type);
signed_transaction trx;
trx.set_expiration(db1.head_block_time() + fc::minutes(1));
set_expiration( db1, trx );
account_id_type nathan_id = account_idx.get_next_id();
account_create_operation cop;
cop.name = "nathan";
@ -423,7 +424,7 @@ BOOST_AUTO_TEST_CASE( duplicate_transactions )
PUSH_TX( db1, trx, skip_sigs );
trx = decltype(trx)();
trx.set_expiration(db1.head_block_time() + fc::minutes(1));
set_expiration( db1, trx );
transfer_operation t;
t.to = nathan_id;
t.amount = asset(500);
@ -492,8 +493,7 @@ BOOST_AUTO_TEST_CASE( tapos )
trx.sign(init_account_priv_key);
//relative_expiration is 1, but ref block is 2 blocks old, so this should fail.
GRAPHENE_REQUIRE_THROW(PUSH_TX( db1, trx, database::skip_transaction_signatures | database::skip_authority_check ), fc::exception);
trx.set_expiration( db1.head_block_time() + fc::seconds( 2 * db1.get_global_properties().parameters.block_interval ));
trx.set_reference_block( db1.head_block_id() );
set_expiration( db1, trx );
trx.signatures.clear();
trx.sign(init_account_priv_key);
db1.push_transaction(trx, database::skip_transaction_signatures | database::skip_authority_check);
@ -604,7 +604,7 @@ BOOST_FIXTURE_TEST_CASE( double_sign_check, database_fixture )
ACTOR(bob);
asset amount(1000);
trx.set_expiration(db.head_block_time() + fc::minutes(1));
set_expiration( db, trx );
transfer_operation t;
t.from = alice.id;
t.to = bob.id;

View file

@ -34,6 +34,7 @@
#include "../common/database_fixture.hpp"
using namespace graphene::chain;
using namespace graphene::chain::test;
BOOST_FIXTURE_TEST_SUITE( operation_tests, database_fixture )
@ -441,7 +442,7 @@ BOOST_AUTO_TEST_CASE( transfer_core_asset )
for( auto& op : trx.operations ) db.current_fee_schedule().set_fee(op);
fee = trx.operations.front().get<transfer_operation>().fee;
trx.set_expiration( db.head_block_time() + fc::minutes(5) );
set_expiration( db, trx );
trx.validate();
PUSH_TX( db, trx, ~0 );
@ -1174,8 +1175,7 @@ BOOST_AUTO_TEST_CASE( witness_pay_test )
account_upgrade_operation uop;
uop.account_to_upgrade = nathan->get_id();
uop.upgrade_to_lifetime_member = true;
trx.set_expiration( db.head_block_time() + fc::seconds( 3 * db.get_global_properties().parameters.block_interval ));
trx.set_reference_block( db.head_block_id() );
set_expiration( db, trx );
trx.operations.push_back(uop);
for( auto& op : trx.operations ) db.current_fee_schedule().set_fee(op);
trx.validate();
@ -1258,7 +1258,7 @@ BOOST_AUTO_TEST_CASE( reserve_asset_test )
op.amount_to_reserve = amount_to_reserve;
transaction tx;
tx.operations.push_back( op );
tx.set_expiration( db.head_block_time() + fc::minutes(5) );
set_expiration( db, tx );
db.push_transaction( tx, database::skip_authority_check | database::skip_tapos_check | database::skip_transaction_signatures );
} ;
@ -1270,7 +1270,7 @@ BOOST_AUTO_TEST_CASE( reserve_asset_test )
op.issue_to_account = recipient.id;
transaction tx;
tx.operations.push_back( op );
tx.set_expiration( db.head_block_time() + fc::minutes(5) );
set_expiration( db, tx );
db.push_transaction( tx, database::skip_authority_check | database::skip_tapos_check | database::skip_transaction_signatures );
} ;
@ -1360,7 +1360,7 @@ BOOST_AUTO_TEST_CASE( cover_with_collateral_test )
op.delta_debt = delta_debt;
transaction tx;
tx.operations.push_back( op );
tx.set_expiration( db.head_block_time() + fc::minutes(5) );
set_expiration( db, tx );
db.push_transaction( tx, database::skip_authority_check | database::skip_tapos_check | database::skip_transaction_signatures );
} ;
@ -1509,7 +1509,7 @@ BOOST_AUTO_TEST_CASE( vesting_balance_withdraw_test )
create_op.amount = amount;
create_op.policy = cdd_vesting_policy_initializer(vesting_seconds);
tx.operations.push_back( create_op );
tx.set_expiration( db.head_block_time() + fc::minutes(5) );
set_expiration( db, tx );
processed_transaction ptx = PUSH_TX( db, tx, ~0 );
const vesting_balance_object& vbo = vesting_balance_id_type(

View file

@ -38,6 +38,7 @@
#include "../common/database_fixture.hpp"
using namespace graphene::chain;
using namespace graphene::chain::test;
BOOST_FIXTURE_TEST_SUITE( operation_tests, database_fixture )
@ -50,7 +51,7 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_create )
transfer(account_id_type(), nathan_id, asset(1000));
generate_block();
trx.set_expiration(db.head_block_time() + GRAPHENE_DEFAULT_MAX_TIME_UNTIL_EXPIRATION / 2);
set_expiration( db, trx );
{
withdraw_permission_create_operation op;
@ -85,7 +86,7 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_test )
account_id_type nathan_id = get_account("nathan").id;
account_id_type dan_id = get_account("dan").id;
withdraw_permission_id_type permit;
trx.set_expiration(db.head_block_time() + GRAPHENE_DEFAULT_MAX_TIME_UNTIL_EXPIRATION/2);
set_expiration( db, trx );
fc::time_point_sec first_start_time;
{
@ -214,7 +215,7 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_nominal_case )
account_id_type nathan_id = get_account("nathan").id;
account_id_type dan_id = get_account("dan").id;
withdraw_permission_id_type permit;
trx.set_expiration(db.head_block_time() + GRAPHENE_DEFAULT_MAX_TIME_UNTIL_EXPIRATION/2);
set_expiration( db, trx );
while(true)
{
@ -255,7 +256,7 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_update )
account_id_type nathan_id = get_account("nathan").id;
account_id_type dan_id = get_account("dan").id;
withdraw_permission_id_type permit;
trx.set_expiration(db.head_block_time() + GRAPHENE_DEFAULT_MAX_TIME_UNTIL_EXPIRATION/2);
set_expiration( db, trx );
{
withdraw_permission_update_operation op;
@ -297,7 +298,7 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_delete )
withdraw_permission_delete_operation op;
op.authorized_account = get_account("dan").id;
op.withdraw_from_account = get_account("nathan").id;
trx.set_reference_block(db.head_block_id()); trx.set_expiration( db.head_block_time() + fc::seconds( 3 * db.get_global_properties().parameters.block_interval ) );
set_expiration( db, trx );
trx.operations.push_back(op);
trx.sign(generate_private_key("nathan"));
PUSH_TX( db, trx );
@ -415,7 +416,7 @@ BOOST_AUTO_TEST_CASE( witness_create )
// Give nathan some voting stake
transfer(committee_account, nathan_id, asset(10000000));
generate_block();
trx.set_reference_block(db.head_block_id()); trx.set_expiration( db.head_block_time() + fc::seconds( 3 * db.get_global_properties().parameters.block_interval ) );
set_expiration( db, trx );
{
account_update_operation op;
@ -627,7 +628,7 @@ BOOST_AUTO_TEST_CASE( worker_pay_test )
op.vesting_balance = worker_id_type()(db).worker.get<vesting_balance_worker_type>().balance;
op.amount = asset(500);
op.owner = nathan_id;
trx.set_reference_block(db.head_block_id()); trx.set_expiration( db.head_block_time() + fc::seconds( 3 * db.get_global_properties().parameters.block_interval ) );
set_expiration( db, trx );
trx.operations.push_back(op);
trx.sign( nathan_private_key);
PUSH_TX( db, trx );
@ -657,11 +658,11 @@ BOOST_AUTO_TEST_CASE( worker_pay_test )
op.vesting_balance = worker_id_type()(db).worker.get<vesting_balance_worker_type>().balance;
op.amount = asset(500);
op.owner = nathan_id;
trx.set_reference_block(db.head_block_id()); trx.set_expiration( db.head_block_time() + fc::seconds( 3 * db.get_global_properties().parameters.block_interval ) );
set_expiration( db, trx );
trx.operations.push_back(op);
REQUIRE_THROW_WITH_VALUE(op, amount, asset(500));
generate_blocks(db.head_block_time() + fc::hours(12));
trx.set_reference_block(db.head_block_id()); trx.set_expiration( db.head_block_time() + fc::seconds( 3 * db.get_global_properties().parameters.block_interval ) );
set_expiration( db, trx );
REQUIRE_THROW_WITH_VALUE(op, amount, asset(501));
trx.operations.back() = op;
trx.sign( nathan_private_key);
@ -680,7 +681,7 @@ BOOST_AUTO_TEST_CASE( refund_worker_test )
upgrade_to_lifetime_member(nathan_id);
generate_block();
generate_blocks(db.get_dynamic_global_properties().next_maintenance_time);
trx.set_reference_block(db.head_block_id()); trx.set_expiration( db.head_block_time() + fc::seconds( 3 * db.get_global_properties().parameters.block_interval ) );
set_expiration( db, trx );
{
worker_create_operation op;
@ -753,7 +754,7 @@ BOOST_AUTO_TEST_CASE( burn_worker_test )
upgrade_to_lifetime_member(nathan_id);
generate_block();
generate_blocks(db.get_dynamic_global_properties().next_maintenance_time);
trx.set_reference_block(db.head_block_id()); trx.set_expiration( db.head_block_time() + fc::seconds( 3 * db.get_global_properties().parameters.block_interval ) );
set_expiration( db, trx );
{
worker_create_operation op;
@ -854,7 +855,7 @@ BOOST_AUTO_TEST_CASE( force_settle_test )
update_function( op.new_options );
signed_transaction tx;
tx.operations.push_back( op );
tx.set_expiration( db.head_block_time() + fc::minutes(5) );
set_expiration( db, tx );
PUSH_TX( db, tx, ~0 );
} ;
@ -869,7 +870,7 @@ BOOST_AUTO_TEST_CASE( force_settle_test )
update_function( op.new_options );
signed_transaction tx;
tx.operations.push_back( op );
tx.set_expiration( db.head_block_time() + fc::minutes(5) );
set_expiration( db, tx );
PUSH_TX( db, tx, ~0 );
} ;
@ -1091,7 +1092,7 @@ BOOST_AUTO_TEST_CASE( balance_object_test )
auto slot = db.get_slot_at_time(starting_time);
db.generate_block(starting_time, db.get_scheduled_witness(slot).first, init_account_priv_key, skip_flags);
trx.set_reference_block(db.head_block_id()); trx.set_expiration( db.head_block_time() + fc::seconds( 3 * db.get_global_properties().parameters.block_interval ) );
set_expiration( db, trx );
const balance_object& vesting_balance_1 = balance_id_type(2)(db);
const balance_object& vesting_balance_2 = balance_id_type(3)(db);
@ -1144,7 +1145,7 @@ BOOST_AUTO_TEST_CASE( balance_object_test )
db.generate_block(db.get_slot_time(1), db.get_scheduled_witness(1).first, init_account_priv_key, skip_flags);
slot = db.get_slot_at_time(vesting_balance_1.vesting_policy->begin_timestamp + 60);
db.generate_block(db.get_slot_time(slot), db.get_scheduled_witness(slot).first, init_account_priv_key, skip_flags);
trx.set_reference_block(db.head_block_id()); trx.set_expiration( db.head_block_time() + fc::seconds( 3 * db.get_global_properties().parameters.block_interval ) );
set_expiration( db, trx );
op.balance_to_claim = vesting_balance_1.id;
op.total_claimed.amount = 500;
@ -1170,7 +1171,7 @@ BOOST_AUTO_TEST_CASE( balance_object_test )
db.generate_block(db.get_slot_time(1), db.get_scheduled_witness(1).first, init_account_priv_key, skip_flags);
slot = db.get_slot_at_time(db.head_block_time() + fc::days(1));
db.generate_block(db.get_slot_time(slot), db.get_scheduled_witness(slot).first, init_account_priv_key, skip_flags);
trx.set_reference_block(db.head_block_id()); trx.set_expiration( db.head_block_time() + fc::seconds( 3 * db.get_global_properties().parameters.block_interval ) );
set_expiration( db, trx );
op.total_claimed = vesting_balance_2.balance;
trx.operations = {op};

View file

@ -29,6 +29,7 @@
#include "../common/database_fixture.hpp"
using namespace graphene::chain;
using namespace graphene::chain::test;
BOOST_FIXTURE_TEST_SUITE( uia_tests, database_fixture )
@ -305,7 +306,7 @@ BOOST_AUTO_TEST_CASE( transfer_restricted_test )
op.issue_to_account = recipient.id;
transaction tx;
tx.operations.push_back( op );
tx.set_expiration( db.head_block_time() + fc::minutes(5) );
set_expiration( db, tx );
PUSH_TX( db, tx, database::skip_authority_check | database::skip_tapos_check | database::skip_transaction_signatures );
} ;
@ -324,7 +325,7 @@ BOOST_AUTO_TEST_CASE( transfer_restricted_test )
op.new_options.flags &= ~transfer_restricted;
transaction tx;
tx.operations.push_back( op );
tx.set_expiration( db.head_block_time() + fc::minutes(5) );
set_expiration( db, tx );
PUSH_TX( db, tx, database::skip_authority_check | database::skip_tapos_check | database::skip_transaction_signatures );
} ;
@ -336,7 +337,7 @@ BOOST_AUTO_TEST_CASE( transfer_restricted_test )
xfer_op.amount = uia.amount(100);
signed_transaction xfer_tx;
xfer_tx.operations.push_back( xfer_op );
xfer_tx.set_expiration( db.head_block_time() + fc::minutes(5) );
set_expiration( db, xfer_tx );
sign( xfer_tx, alice_private_key );
_restrict_xfer( true );