Skip to content

Commit

Permalink
Merge pull request #2172 from christophersanborn/cjs-bsip87
Browse files Browse the repository at this point in the history
BSIP87 Tests
  • Loading branch information
abitmore authored May 12, 2020
2 parents 784af1b + da81ded commit 2fa51be
Show file tree
Hide file tree
Showing 3 changed files with 1,685 additions and 6 deletions.
17 changes: 12 additions & 5 deletions libraries/chain/asset_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -995,11 +995,18 @@ void_result asset_claim_fees_evaluator::do_evaluate( const asset_claim_fees_oper

container_ddo = &container_asset->dynamic_asset_data_id(d);

FC_ASSERT( o.amount_to_claim.amount <= ((container_asset->get_id() == o.amount_to_claim.asset_id) ?
container_ddo->accumulated_fees :
container_ddo->accumulated_collateral_fees),
"Attempt to claim more fees than have accumulated within asset ${a} (${id})",
("a",container_asset->symbol)("id",container_asset->id)("ddo",*container_ddo) );
if (container_asset->get_id() == o.amount_to_claim.asset_id) {
FC_ASSERT( o.amount_to_claim.amount <= container_ddo->accumulated_fees,
"Attempt to claim more fees than have accumulated within asset ${a} (${id}). "
"Asset DDO: ${ddo}. Fee claim: ${claim}.", ("a",container_asset->symbol)
("id",container_asset->id)("ddo",*container_ddo)("claim",o.amount_to_claim) );
} else {
FC_ASSERT( o.amount_to_claim.amount <= container_ddo->accumulated_collateral_fees,
"Attempt to claim more backing-asset fees than have accumulated within asset ${a} (${id}) "
"backed by (${fid}). Asset DDO: ${ddo}. Fee claim: ${claim}.", ("a",container_asset->symbol)
("id",container_asset->id)("fid",o.amount_to_claim.asset_id)("ddo",*container_ddo)
("claim",o.amount_to_claim) );
}

return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }
Expand Down
191 changes: 190 additions & 1 deletion tests/tests/bitasset_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ void change_backing_asset(database_fixture& fixture, const fc::ecc::private_key&
}
catch (fc::exception& ex)
{
BOOST_FAIL( "Exception thrown in chainge_backing_asset. Exception was: " +
BOOST_FAIL( "Exception thrown in change_backing_asset. Exception was: " +
ex.to_string(fc::log_level(fc::log_level::all)) );
}
}
Expand Down Expand Up @@ -1407,4 +1407,193 @@ BOOST_AUTO_TEST_CASE(hf_890_test_hf1270)

} FC_LOG_AND_RETHROW() }


/**
* Test the claiming of collateral asset fees before HARDFORK_CORE_BSIP_87_74_COLLATFEE_TIME.
*
* Test prohibitions against changing of the backing/collateral asset for a smart asset
* if any collateral asset fees are available to be claimed.
*/
BOOST_AUTO_TEST_CASE(change_backing_asset_prohibitions) {
try {
/**
* Initialize
*/
// Initialize for the current time
trx.clear();
set_expiration(db, trx);

// Initialize actors
ACTORS((smartissuer)(feedproducer)); // Actors for smart asset
ACTORS((jill)(izzy)); // Actors for user-issued assets
ACTORS((alice)); // Actors who hold balances

price price(asset(1, asset_id_type(1)), asset(1));
uint16_t market_fee_percent = 20 * GRAPHENE_1_PERCENT;
create_user_issued_asset("JCOIN", jill, charge_market_fee, price, 2, market_fee_percent);
generate_block(); trx.clear(); set_expiration(db, trx);
const asset_object jillcoin = get_asset("JCOIN");
const int64_t jillcoin_unit = 100; // 100 satoshi JILLCOIN in 1 JILLCOIN

create_user_issued_asset("ICOIN", izzy_id(db), charge_market_fee, price, 2, market_fee_percent);
generate_block();
const asset_object izzycoin = get_asset("ICOIN");

// Create the smart asset backed by JCOIN
const uint16_t smartbit_market_fee_percent = 2 * GRAPHENE_1_PERCENT;
create_bitasset("SMARTBIT", smartissuer_id, smartbit_market_fee_percent,
charge_market_fee, 2, jillcoin.id);

// Obtain asset object after a block is generated to obtain the final object that is commited to the database
generate_block(); trx.clear(); set_expiration(db, trx);
const asset_object &smartbit = get_asset("SMARTBIT");
const asset_bitasset_data_object& smartbit_bitasset_data = (*smartbit.bitasset_data_id)(db);
// Confirm that the asset is to be backed by JCOIN
BOOST_CHECK(smartbit_bitasset_data.options.short_backing_asset == jillcoin.id);

// Fund balances of the actors
issue_uia(alice, jillcoin.amount(5000 * jillcoin_unit));
BOOST_REQUIRE_EQUAL(get_balance(alice, jillcoin), 5000 * jillcoin_unit);
BOOST_REQUIRE_EQUAL(get_balance(alice, smartbit), 0);


/**
* Claim any amount of collateral asset fees. This should fail because claiming such fees are prohibited
* before the HARDFORK_CORE_BSIP_87_74_COLLATFEE_TIME.
*/
trx.clear();
asset_claim_fees_operation claim_op;
claim_op.issuer = smartissuer_id;
claim_op.extensions.value.claim_from_asset_id = smartbit.id;
claim_op.amount_to_claim = jillcoin.amount(5 * jillcoin_unit);
trx.operations.push_back(claim_op);
sign(trx, smartissuer_private_key);
REQUIRE_EXCEPTION_WITH_TEXT(PUSH_TX(db, trx), "Collateral-denominated fees are not yet active");


/**
* Propose to claim any amount of collateral asset fees.
* This should fail because claiming such fees are prohibited before HARDFORK_CORE_BSIP_87_74_COLLATFEE_TIME.
*/
proposal_create_operation cop;
cop.review_period_seconds = 86400;
uint32_t buffer_seconds = 60 * 60;
cop.expiration_time = db.head_block_time() + *cop.review_period_seconds + buffer_seconds;
cop.fee_paying_account = GRAPHENE_TEMP_ACCOUNT;
cop.proposed_ops.emplace_back(claim_op);

trx.clear();
trx.operations.push_back(cop);
// sign(trx, smartissuer_private_key);
REQUIRE_EXCEPTION_WITH_TEXT(PUSH_TX(db, trx), "Collateral-denominated fees are not yet active");


/**
* Advance to when the collateral fee container is activated
*/
generate_blocks(HARDFORK_CORE_BSIP_87_74_COLLATFEE_TIME);
generate_block(); trx.clear(); set_expiration(db, trx);


/**
* Cause some collateral of JCOIN to be accumulated as collateral fee within the SMARTBIT asset type
*/
// HACK: Before BSIP74 or BSIP87 are introduced, it is not formally possible to accumulate collateral fees.
// Therefore, the accumulation for this test will be informally induced by direct manipulation of the database.
// More formal tests will be provided with the PR for either BSIP74 or BSIP87.
// IMPORTANT: The use of this hack requires that no additional blocks are subsequently generated!
asset accumulation_amount = jillcoin.amount(40 * jillcoin_unit); // JCOIN
db.adjust_balance(alice_id, -accumulation_amount); // Deduct 40 JCOIN from alice as a "collateral fee"
smartbit.accumulate_fee(db, accumulation_amount); // Add 40 JCOIN from alice as a "collateral fee"
BOOST_REQUIRE_EQUAL(get_balance(alice, jillcoin), (5000 * jillcoin_unit) - (40 * jillcoin_unit));
BOOST_CHECK(smartbit.dynamic_asset_data_id(db).accumulated_collateral_fees == accumulation_amount.amount);


/**
* Attempt to change the backing asset. This should fail because there are unclaimed collateral fees.
*/
trx.clear();
asset_update_bitasset_operation change_backing_asset_op;
change_backing_asset_op.asset_to_update = smartbit.id;
change_backing_asset_op.issuer = smartissuer_id;
change_backing_asset_op.new_options.short_backing_asset = izzycoin.id;
trx.operations.push_back(change_backing_asset_op);
sign(trx, smartissuer_private_key);
REQUIRE_EXCEPTION_WITH_TEXT(PUSH_TX(db, trx), "Must claim collateral-denominated fees");


/**
* Attempt to claim a negative amount of the collateral asset fees.
* This should fail because positive amounts are required.
*/
trx.clear();
claim_op.amount_to_claim = jillcoin.amount(-9 * jillcoin_unit);
trx.operations.push_back(claim_op);
sign(trx, smartissuer_private_key);
REQUIRE_EXCEPTION_WITH_TEXT(PUSH_TX(db, trx), "amount_to_claim.amount > 0");


/**
* Attempt to claim 0 amount of the collateral asset fees.
* This should fail because positive amounts are required.
*/
trx.clear();
claim_op.amount_to_claim = jillcoin.amount(0 * jillcoin_unit);
trx.operations.push_back(claim_op);
sign(trx, smartissuer_private_key);
REQUIRE_EXCEPTION_WITH_TEXT(PUSH_TX(db, trx), "amount_to_claim.amount > 0");


/**
* Attempt to claim excessive amount of collateral asset fees.
* This should fail because there are insufficient collateral fees.
*/
trx.clear();
claim_op.amount_to_claim = accumulation_amount + jillcoin.amount(1);
trx.operations.push_back(claim_op);
sign(trx, smartissuer_private_key);
REQUIRE_EXCEPTION_WITH_TEXT(PUSH_TX(db, trx), "Attempt to claim more backing-asset fees");


/**
* Claim some of the collateral asset fees
*/
share_type part_of_accumulated_fees = accumulation_amount.amount / 4;
FC_ASSERT(part_of_accumulated_fees.value > 0); // Partial claim should be positive
share_type remainder_accumulated_fees = accumulation_amount.amount - part_of_accumulated_fees;
FC_ASSERT(remainder_accumulated_fees.value > 0); // Planned remainder should be positive
trx.clear();
claim_op.amount_to_claim = jillcoin.amount(part_of_accumulated_fees);
trx.operations.push_back(claim_op);
sign(trx, smartissuer_private_key);
PUSH_TX(db, trx);
BOOST_CHECK(smartbit.dynamic_asset_data_id(db).accumulated_collateral_fees == remainder_accumulated_fees);


/**
* Claim all the remaining collateral asset fees
*/
trx.clear();
claim_op.amount_to_claim = jillcoin.amount(remainder_accumulated_fees);
trx.operations.push_back(claim_op);
sign(trx, smartissuer_private_key);
PUSH_TX(db, trx);
BOOST_CHECK(smartbit.dynamic_asset_data_id(db).accumulated_collateral_fees == 0); // 0 remainder


/**
* Attempt to change the backing asset.
* This should succeed because there are no collateral asset fees are waiting to be claimed.
*/
trx.clear();
trx.operations.push_back(change_backing_asset_op);
sign(trx, smartissuer_private_key);
PUSH_TX(db, trx);

// Confirm the change to the backing asset
BOOST_CHECK(smartbit_bitasset_data.options.short_backing_asset == izzycoin.id);

} FC_LOG_AND_RETHROW()
}

BOOST_AUTO_TEST_SUITE_END()
Loading

0 comments on commit 2fa51be

Please sign in to comment.