Skip to content

Commit

Permalink
Merge pull request #1655 from bitshares/jmj_htlc_blacklist
Browse files Browse the repository at this point in the history
Pay attention to blacklist when creating HTLCs
  • Loading branch information
jmjatlanta authored Mar 18, 2019
2 parents e373cd2 + 5b5e6ad commit 2f84da6
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 1 deletion.
13 changes: 12 additions & 1 deletion libraries/chain/htlc_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <graphene/chain/htlc_evaluator.hpp>
#include <graphene/chain/htlc_object.hpp>
#include <graphene/chain/hardfork.hpp>
#include <graphene/chain/is_authorized_asset.hpp>

namespace graphene {
namespace chain {
Expand All @@ -36,6 +37,7 @@ namespace graphene {

void_result htlc_create_evaluator::do_evaluate(const htlc_create_operation& o)
{
graphene::chain::database& d = db();
optional<htlc_options> htlc_options = get_committee_htlc_options(db());

FC_ASSERT(htlc_options, "HTLC Committee options are not set.");
Expand All @@ -45,7 +47,16 @@ namespace graphene {
// make sure the preimage length is reasonable
FC_ASSERT( o.preimage_size <= htlc_options->max_preimage_size, "HTLC preimage length exceeds allowed length" );
// make sure the sender has the funds for the HTLC
FC_ASSERT( db().get_balance( o.from, o.amount.asset_id) >= (o.amount), "Insufficient funds") ;
FC_ASSERT( d.get_balance( o.from, o.amount.asset_id) >= (o.amount), "Insufficient funds") ;
const auto& asset_to_transfer = o.amount.asset_id( d );
const auto& from_account = o.from( d );
const auto& to_account = o.to( d );
FC_ASSERT( is_authorized_asset( d, from_account, asset_to_transfer ),
"Asset ${asset} is not authorized for account ${acct}.",
( "asset", asset_to_transfer.id )( "acct", from_account.id ) );
FC_ASSERT( is_authorized_asset( d, to_account, asset_to_transfer ),
"Asset ${asset} is not authorized for account ${acct}.",
( "asset", asset_to_transfer.id )( "acct", to_account.id ) );
return void_result();
}

Expand Down
135 changes: 135 additions & 0 deletions tests/tests/htlc_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -633,4 +633,139 @@ BOOST_AUTO_TEST_CASE( fee_calculations )
}
}

BOOST_AUTO_TEST_CASE( htlc_blacklist )
{
try {
ACTORS((nathan)(alice)(bob));

upgrade_to_lifetime_member( nathan );

// create a UIA
const asset_id_type uia_id = create_user_issued_asset( "NATHANCOIN", nathan, white_list ).id;
// Make a whitelist authority
{
BOOST_TEST_MESSAGE( "Changing the whitelist authority" );
asset_update_operation uop;
uop.issuer = nathan_id;
uop.asset_to_update = uia_id;
uop.new_options = uia_id(db).options;
uop.new_options.blacklist_authorities.insert(nathan_id);
trx.operations.push_back(uop);
PUSH_TX( db, trx, ~0 );
trx.operations.clear();
}


int64_t init_balance(100 * GRAPHENE_BLOCKCHAIN_PRECISION);
fund( alice, graphene::chain::asset(init_balance) );
fund( bob, graphene::chain::asset(init_balance) );

advance_past_hardfork(this);

// blacklist bob
{
graphene::chain::account_whitelist_operation op;
op.authorizing_account = nathan_id;
op.account_to_list = bob_id;
op.new_listing = graphene::chain::account_whitelist_operation::account_listing::black_listed;
op.fee = db.current_fee_schedule().calculate_fee( op );
trx.operations.push_back( op );
sign( trx, nathan_private_key );
PUSH_TX( db, trx, ~0 );
trx.clear();
generate_block();
}

issue_uia( alice_id, asset( init_balance, uia_id ) );

uint16_t preimage_size = 256;
std::vector<char> pre_image(preimage_size);
generate_random_preimage(preimage_size, pre_image);

// Alice attempts to put a contract on the blockchain
{
graphene::chain::htlc_create_operation create_operation;

create_operation.amount = graphene::chain::asset( 20 * GRAPHENE_BLOCKCHAIN_PRECISION, uia_id );
create_operation.to = bob_id;
create_operation.claim_period_seconds = 86400;
create_operation.preimage_hash = hash_it<fc::sha1>( pre_image );
create_operation.preimage_size = preimage_size;
create_operation.from = alice_id;
create_operation.fee = db.current_fee_schedule().calculate_fee( create_operation );
trx.operations.push_back( create_operation );
sign(trx, alice_private_key);
// bob cannot accept it, so it fails
GRAPHENE_CHECK_THROW( PUSH_TX( db, trx, ~0 ), fc::exception );
trx.clear();
}

// unblacklist Bob
{
graphene::chain::account_whitelist_operation op;
op.authorizing_account = nathan_id;
op.account_to_list = bob_id;
op.new_listing = graphene::chain::account_whitelist_operation::account_listing::no_listing;
op.fee = db.current_fee_schedule().calculate_fee( op );
trx.operations.push_back( op );
sign( trx, nathan_private_key );
PUSH_TX( db, trx, ~0 );
trx.clear();
generate_block();
}

graphene::chain::htlc_id_type alice_htlc_id;

// Alice again attempts to put a contract on the blockchain
{
graphene::chain::htlc_create_operation create_operation;

create_operation.amount = graphene::chain::asset( 20 * GRAPHENE_BLOCKCHAIN_PRECISION, uia_id );
create_operation.to = bob_id;
create_operation.claim_period_seconds = 86400;
create_operation.preimage_hash = hash_it<fc::sha1>( pre_image );
create_operation.preimage_size = preimage_size;
create_operation.from = alice_id;
create_operation.fee = db.current_fee_schedule().calculate_fee( create_operation );
trx.operations.push_back( create_operation );
sign(trx, alice_private_key);
// bob can now accept it, so it works
PUSH_TX( db, trx, ~0 );
trx.clear();
graphene::chain::signed_block blk = generate_block();
processed_transaction alice_trx = blk.transactions[0];
alice_htlc_id = alice_trx.operation_results[0].get<object_id_type>();
}

// blacklist bob
{
graphene::chain::account_whitelist_operation op;
op.authorizing_account = nathan_id;
op.account_to_list = bob_id;
op.new_listing = graphene::chain::account_whitelist_operation::account_listing::black_listed;
op.fee = db.current_fee_schedule().calculate_fee( op );
trx.operations.push_back( op );
sign( trx, nathan_private_key );
PUSH_TX( db, trx, ~0 );
trx.clear();
generate_block();
}

// bob can redeem even though he's blacklisted
{
graphene::chain::htlc_redeem_operation update_operation;
update_operation.redeemer = bob_id;
update_operation.htlc_id = alice_htlc_id;
update_operation.preimage = pre_image;
update_operation.fee = db.current_fee_schedule().calculate_fee( update_operation );
trx.operations.push_back( update_operation );
sign(trx, bob_private_key);
PUSH_TX( db, trx, ~0 );
generate_block();
trx.clear();
}

} FC_LOG_AND_RETHROW()
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit 2f84da6

Please sign in to comment.