Merge branch 'github_master'
Conflicts: libraries/fc
This commit is contained in:
commit
39cd21c11e
36 changed files with 83 additions and 1057 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -1,11 +1,11 @@
|
|||
*.a
|
||||
*.sw*
|
||||
|
||||
*.cmake
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
Makefile
|
||||
compile_commands.json
|
||||
*.cmake
|
||||
|
||||
libraries/utilities/git_revision.cpp
|
||||
|
||||
|
|
@ -19,7 +19,7 @@ tests/chain_test
|
|||
tests/intense_test
|
||||
tests/performance_test
|
||||
|
||||
/doxygen
|
||||
doxygen
|
||||
|
||||
witness_node_data_dir
|
||||
wallet.json
|
||||
witness_node_data_dir
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ add_library( graphene_chain
|
|||
proposal_evaluator.cpp
|
||||
short_order_evaluator.cpp
|
||||
limit_order_evaluator.cpp
|
||||
bond_evaluator.cpp
|
||||
vesting_balance_evaluator.cpp
|
||||
withdraw_permission_evaluator.cpp
|
||||
worker_evaluator.cpp
|
||||
|
|
@ -55,5 +54,5 @@ target_include_directories( graphene_chain
|
|||
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )
|
||||
|
||||
if(MSVC)
|
||||
set_source_files_properties( db_init.cpp PROPERTIES COMPILE_FLAGS "/bigobj" )
|
||||
set_source_files_properties( db_init.cpp db_block.cpp PROPERTIES COMPILE_FLAGS "/bigobj" )
|
||||
endif(MSVC)
|
||||
|
|
|
|||
|
|
@ -1,218 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Cryptonomex, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is provided for evaluation in private test networks only, until September 8, 2015. After this date, this license expires and
|
||||
* the code may not be used, modified or distributed for any purpose. Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted until September 8, 2015, provided that the following conditions are met:
|
||||
*
|
||||
* 1. The code and/or derivative works are used only for private test networks consisting of no more than 10 P2P nodes.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <graphene/chain/account_object.hpp>
|
||||
#include <graphene/chain/bond_evaluator.hpp>
|
||||
#include <graphene/chain/bond_object.hpp>
|
||||
#include <graphene/chain/database.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
object_id_type bond_create_offer_evaluator::do_evaluate( const bond_create_offer_operation& op )
|
||||
{
|
||||
const auto& d = db();
|
||||
|
||||
const auto& creator_account = op.creator( d );
|
||||
const auto& base_asset = op.collateral_rate.base.asset_id( d );
|
||||
const auto& quote_asset = op.collateral_rate.quote.asset_id( d );
|
||||
|
||||
// TODO: Check asset authorizations and withdrawals
|
||||
|
||||
const auto& amount_asset = (op.amount.asset_id == op.collateral_rate.base.asset_id) ? base_asset : quote_asset;
|
||||
|
||||
FC_ASSERT( !base_asset.is_transfer_restricted() && !quote_asset.is_transfer_restricted() );
|
||||
|
||||
if( base_asset.options.whitelist_markets.size() )
|
||||
FC_ASSERT( base_asset.options.whitelist_markets.find( quote_asset.id ) != base_asset.options.whitelist_markets.end() );
|
||||
if( base_asset.options.blacklist_markets.size() )
|
||||
FC_ASSERT( base_asset.options.blacklist_markets.find( quote_asset.id ) == base_asset.options.blacklist_markets.end() );
|
||||
|
||||
FC_ASSERT( d.get_balance( creator_account, amount_asset ) >= op.amount );
|
||||
|
||||
return object_id_type();
|
||||
}
|
||||
|
||||
object_id_type bond_create_offer_evaluator::do_apply( const bond_create_offer_operation& op )
|
||||
{
|
||||
db().adjust_balance( op.creator, -op.amount );
|
||||
db().adjust_core_in_orders( op.creator(db()), op.amount );
|
||||
|
||||
const auto& offer = db().create<bond_offer_object>( [&]( bond_offer_object& obj )
|
||||
{
|
||||
obj.offered_by_account = op.creator;
|
||||
obj.offer_to_borrow = op.offer_to_borrow;
|
||||
obj.amount = op.amount;
|
||||
obj.min_match = op.min_match;
|
||||
obj.collateral_rate = op.collateral_rate;
|
||||
obj.min_loan_period_sec = op.min_loan_period_sec;
|
||||
obj.loan_period_sec = op.loan_period_sec;
|
||||
obj.interest_apr = op.interest_apr;
|
||||
} );
|
||||
|
||||
return offer.id;
|
||||
}
|
||||
|
||||
|
||||
object_id_type bond_cancel_offer_evaluator::do_evaluate( const bond_cancel_offer_operation& op )
|
||||
{
|
||||
_offer = &op.offer_id(db());
|
||||
FC_ASSERT( op.creator == _offer->offered_by_account );
|
||||
FC_ASSERT( _offer->amount == op.refund );
|
||||
return object_id_type();
|
||||
}
|
||||
|
||||
object_id_type bond_cancel_offer_evaluator::do_apply( const bond_cancel_offer_operation& op )
|
||||
{
|
||||
assert( _offer != nullptr );
|
||||
db().adjust_balance( op.creator, op.refund );
|
||||
db().adjust_core_in_orders( op.creator(db()), -op.refund );
|
||||
db().remove( *_offer );
|
||||
return object_id_type();
|
||||
}
|
||||
|
||||
object_id_type bond_accept_offer_evaluator::do_evaluate( const bond_accept_offer_operation& op )
|
||||
{ try {
|
||||
_offer = &op.offer_id(db());
|
||||
|
||||
if( _offer->offer_to_borrow )
|
||||
FC_ASSERT( op.amount_borrowed.amount >= _offer->min_match );
|
||||
else
|
||||
FC_ASSERT( op.amount_collateral.amount >= _offer->min_match );
|
||||
|
||||
FC_ASSERT( (op.amount_borrowed / op.amount_collateral == _offer->collateral_rate) ||
|
||||
(op.amount_collateral / op.amount_borrowed == _offer->collateral_rate) );
|
||||
|
||||
return object_id_type();
|
||||
} FC_CAPTURE_AND_RETHROW((op)) }
|
||||
|
||||
object_id_type bond_accept_offer_evaluator::do_apply( const bond_accept_offer_operation& op )
|
||||
{ try {
|
||||
|
||||
if( op.claimer == op.lender )
|
||||
{
|
||||
db().adjust_balance( op.lender, -op.amount_borrowed );
|
||||
}
|
||||
else // claimer == borrower
|
||||
{
|
||||
db().adjust_balance( op.borrower, -op.amount_collateral );
|
||||
db().adjust_core_in_orders( op.borrower(db()), op.amount_collateral );
|
||||
}
|
||||
db().adjust_balance( op.borrower, op.amount_borrowed );
|
||||
|
||||
const auto& bond = db().create<bond_object>( [&]( bond_object& obj )
|
||||
{
|
||||
obj.borrowed = op.amount_borrowed;
|
||||
obj.collateral = op.amount_collateral;
|
||||
obj.borrower = op.borrower;
|
||||
obj.lender = op.lender;
|
||||
|
||||
auto head_time = db().get_dynamic_global_properties().time;
|
||||
obj.interest_apr = _offer->interest_apr;
|
||||
obj.start_date = head_time;
|
||||
obj.due_date = head_time + fc::seconds( _offer->loan_period_sec );
|
||||
obj.earliest_payoff_date = head_time + fc::seconds( _offer->min_loan_period_sec );
|
||||
} );
|
||||
|
||||
if( _offer->offer_to_borrow && op.amount_borrowed < _offer->amount )
|
||||
{
|
||||
db().modify( *_offer, [&]( bond_offer_object& offer ){
|
||||
offer.amount -= op.amount_borrowed;
|
||||
});
|
||||
}
|
||||
else if( !_offer->offer_to_borrow && op.amount_collateral < _offer->amount )
|
||||
{
|
||||
db().modify( *_offer, [&]( bond_offer_object& offer ){
|
||||
offer.amount -= op.amount_collateral;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
db().remove( *_offer );
|
||||
}
|
||||
return bond.id;
|
||||
} FC_CAPTURE_AND_RETHROW((op)) }
|
||||
|
||||
|
||||
|
||||
object_id_type bond_claim_collateral_evaluator::do_evaluate( const bond_claim_collateral_operation& op )
|
||||
{
|
||||
_bond = &op.bond_id(db());
|
||||
auto head_time = db().get_dynamic_global_properties().time;
|
||||
FC_ASSERT( head_time > _bond->earliest_payoff_date );
|
||||
|
||||
|
||||
FC_ASSERT( op.collateral_claimed <= _bond->collateral );
|
||||
if( _bond->borrower == op.claimer )
|
||||
{
|
||||
auto elapsed_time = head_time - _bond->start_date;
|
||||
auto elapsed_days = 1 + elapsed_time.to_seconds() / (60*60*24);
|
||||
|
||||
fc::uint128 tmp = _bond->borrowed.amount.value;
|
||||
tmp *= elapsed_days;
|
||||
tmp *= _bond->interest_apr;
|
||||
tmp /= (365 * GRAPHENE_100_PERCENT);
|
||||
FC_ASSERT( tmp < GRAPHENE_MAX_SHARE_SUPPLY );
|
||||
_interest_due = asset(tmp.to_uint64(), _bond->borrowed.asset_id);
|
||||
|
||||
FC_ASSERT( _interest_due + _bond->borrowed <= op.payoff_amount );
|
||||
|
||||
auto total_debt = _interest_due + _bond->borrowed;
|
||||
|
||||
fc::uint128 max_claim = _bond->collateral.amount.value;
|
||||
max_claim *= op.payoff_amount.amount.value;
|
||||
max_claim /= total_debt.amount.value;
|
||||
|
||||
FC_ASSERT( op.collateral_claimed.amount.value == max_claim.to_uint64() );
|
||||
}
|
||||
else
|
||||
{
|
||||
FC_ASSERT( _bond->lender == op.claimer );
|
||||
FC_ASSERT( head_time > _bond->due_date );
|
||||
FC_ASSERT( _bond->collateral == op.collateral_claimed );
|
||||
FC_ASSERT( op.payoff_amount == asset(0,_bond->borrowed.asset_id ) );
|
||||
}
|
||||
return object_id_type();
|
||||
}
|
||||
|
||||
object_id_type bond_claim_collateral_evaluator::do_apply( const bond_claim_collateral_operation& op )
|
||||
{
|
||||
assert( _bond != nullptr );
|
||||
|
||||
const account_object& claimer = op.claimer(db());
|
||||
|
||||
db().adjust_core_in_orders( _bond->borrower(db()), -op.collateral_claimed );
|
||||
|
||||
if( op.payoff_amount.amount > 0 )
|
||||
{
|
||||
db().adjust_balance( claimer, -op.payoff_amount );
|
||||
db().adjust_balance( op.lender, op.payoff_amount );
|
||||
}
|
||||
db().adjust_balance( claimer, op.collateral_claimed );
|
||||
|
||||
if( op.collateral_claimed == _bond->collateral )
|
||||
db().remove(*_bond);
|
||||
else
|
||||
db().modify( *_bond, [&]( bond_object& bond ){
|
||||
bond.borrowed -= op.payoff_amount + _interest_due;
|
||||
bond.collateral -= op.collateral_claimed;
|
||||
bond.start_date = db().get_dynamic_global_properties().time;
|
||||
});
|
||||
|
||||
return object_id_type();
|
||||
}
|
||||
|
||||
} } // graphene::chain
|
||||
|
|
@ -21,9 +21,7 @@
|
|||
#include <graphene/chain/account_object.hpp>
|
||||
#include <graphene/chain/asset_object.hpp>
|
||||
#include <graphene/chain/block_summary_object.hpp>
|
||||
#include <graphene/chain/bond_object.hpp>
|
||||
#include <graphene/chain/delegate_object.hpp>
|
||||
#include <graphene/chain/file_object.hpp>
|
||||
#include <graphene/chain/global_property_object.hpp>
|
||||
#include <graphene/chain/key_object.hpp>
|
||||
#include <graphene/chain/limit_order_object.hpp>
|
||||
|
|
@ -38,7 +36,6 @@
|
|||
|
||||
#include <graphene/chain/account_evaluator.hpp>
|
||||
#include <graphene/chain/asset_evaluator.hpp>
|
||||
#include <graphene/chain/bond_evaluator.hpp>
|
||||
#include <graphene/chain/custom_evaluator.hpp>
|
||||
#include <graphene/chain/delegate_evaluator.hpp>
|
||||
#include <graphene/chain/global_parameters_evaluator.hpp>
|
||||
|
|
@ -90,10 +87,6 @@ void database::initialize_evaluators()
|
|||
register_evaluator<global_parameters_update_evaluator>();
|
||||
register_evaluator<witness_create_evaluator>();
|
||||
register_evaluator<witness_withdraw_pay_evaluator>();
|
||||
register_evaluator<bond_create_offer_evaluator>();
|
||||
register_evaluator<bond_cancel_offer_evaluator>();
|
||||
register_evaluator<bond_accept_offer_evaluator>();
|
||||
register_evaluator<bond_claim_collateral_evaluator>();
|
||||
register_evaluator<vesting_balance_create_evaluator>();
|
||||
register_evaluator<vesting_balance_withdraw_evaluator>();
|
||||
register_evaluator<withdraw_permission_create_evaluator>();
|
||||
|
|
@ -119,9 +112,6 @@ void database::initialize_indexes()
|
|||
add_index< primary_index<call_order_index > >();
|
||||
add_index< primary_index<proposal_index > >();
|
||||
add_index< primary_index<withdraw_permission_index > >();
|
||||
add_index< primary_index<bond_index > >();
|
||||
add_index< primary_index<bond_offer_index > >();
|
||||
add_index< primary_index<file_object_index> >();
|
||||
add_index< primary_index<simple_index<vesting_balance_object> > >();
|
||||
add_index< primary_index<worker_index> >();
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
#include <graphene/chain/account_object.hpp>
|
||||
#include <graphene/chain/asset_object.hpp>
|
||||
#include <graphene/chain/bond_object.hpp>
|
||||
#include <graphene/chain/limit_order_object.hpp>
|
||||
#include <graphene/chain/short_order_object.hpp>
|
||||
|
||||
|
|
@ -33,7 +32,6 @@ namespace graphene { namespace chain {
|
|||
calculate the USD->CORE price and convert all USD balances to CORE at that price and subtract CORE from total
|
||||
- any fees accumulated by the issuer in the bitasset are forfeit / not redeemed
|
||||
- cancel all open orders with bitasset in it
|
||||
- any bonds with the bitasset as collateral get converted to CORE as collateral
|
||||
- any bitassets that use this bitasset as collateral are immediately settled at their feed price
|
||||
- convert all balances in bitasset to CORE and subtract from total
|
||||
- any prediction markets with usd as the backing get converted to CORE as the backing
|
||||
|
|
@ -111,38 +109,6 @@ void database::globally_settle_asset( const asset_object& mia, const price& sett
|
|||
// settle all balances
|
||||
asset total_mia_settled = mia.amount(0);
|
||||
|
||||
// convert collateral held in bonds
|
||||
const auto& bond_idx = get_index_type<bond_index>().indices().get<by_collateral>();
|
||||
auto bond_itr = bond_idx.find( bitasset.id );
|
||||
while( bond_itr != bond_idx.end() )
|
||||
{
|
||||
if( bond_itr->collateral.asset_id == bitasset.id )
|
||||
{
|
||||
auto settled_amount = bond_itr->collateral * settlement_price;
|
||||
total_mia_settled += bond_itr->collateral;
|
||||
collateral_gathered -= settled_amount;
|
||||
modify( *bond_itr, [&]( bond_object& obj ) {
|
||||
obj.collateral = settled_amount;
|
||||
});
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
// cancel all bond offers holding the bitasset and refund the offer
|
||||
const auto& bond_offer_idx = get_index_type<bond_offer_index>().indices().get<by_asset>();
|
||||
auto bond_offer_itr = bond_offer_idx.find( bitasset.id );
|
||||
while( bond_offer_itr != bond_offer_idx.end() )
|
||||
{
|
||||
if( bond_offer_itr->amount.asset_id == bitasset.id )
|
||||
{
|
||||
adjust_balance( bond_offer_itr->offered_by_account, bond_offer_itr->amount );
|
||||
auto old_itr = bond_offer_itr;
|
||||
bond_offer_itr++;
|
||||
remove( *old_itr );
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
const auto& index = get_index_type<account_balance_index>().indices().get<by_asset>();
|
||||
auto range = index.equal_range(mia.get_id());
|
||||
for( auto itr = range.first; itr != range.second; ++itr )
|
||||
|
|
|
|||
|
|
@ -21,20 +21,20 @@
|
|||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
object_id_type global_parameters_update_evaluator::do_evaluate(const global_parameters_update_operation& o)
|
||||
void_result global_parameters_update_evaluator::do_evaluate(const global_parameters_update_operation& o)
|
||||
{
|
||||
FC_ASSERT(trx_state->_is_proposed_trx);
|
||||
|
||||
return object_id_type();
|
||||
return void_result();
|
||||
}
|
||||
|
||||
object_id_type global_parameters_update_evaluator::do_apply(const global_parameters_update_operation& o)
|
||||
void_result global_parameters_update_evaluator::do_apply(const global_parameters_update_operation& o)
|
||||
{
|
||||
db().modify(db().get_global_properties(), [&o](global_property_object& p) {
|
||||
p.pending_parameters = o.new_parameters;
|
||||
});
|
||||
|
||||
return object_id_type();
|
||||
return void_result();
|
||||
}
|
||||
|
||||
} } // graphene::chain
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Cryptonomex, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is provided for evaluation in private test networks only, until September 8, 2015. After this date, this license expires and
|
||||
* the code may not be used, modified or distributed for any purpose. Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted until September 8, 2015, provided that the following conditions are met:
|
||||
*
|
||||
* 1. The code and/or derivative works are used only for private test networks consisting of no more than 10 P2P nodes.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
} } // graphene::chain
|
||||
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Cryptonomex, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is provided for evaluation in private test networks only, until September 8, 2015. After this date, this license expires and
|
||||
* the code may not be used, modified or distributed for any purpose. Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted until September 8, 2015, provided that the following conditions are met:
|
||||
*
|
||||
* 1. The code and/or derivative works are used only for private test networks consisting of no more than 10 P2P nodes.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <graphene/chain/evaluator.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
class bond_create_offer_evaluator : public evaluator<bond_create_offer_evaluator>
|
||||
{
|
||||
public:
|
||||
typedef bond_create_offer_operation operation_type;
|
||||
|
||||
object_id_type do_evaluate( const bond_create_offer_operation& op );
|
||||
object_id_type do_apply( const bond_create_offer_operation& op );
|
||||
};
|
||||
|
||||
class bond_cancel_offer_evaluator : public evaluator<bond_cancel_offer_evaluator>
|
||||
{
|
||||
public:
|
||||
typedef bond_cancel_offer_operation operation_type;
|
||||
|
||||
object_id_type do_evaluate( const bond_cancel_offer_operation& op );
|
||||
object_id_type do_apply( const bond_cancel_offer_operation& op );
|
||||
|
||||
const bond_offer_object* _offer = nullptr;
|
||||
};
|
||||
|
||||
class bond_accept_offer_evaluator : public evaluator<bond_accept_offer_evaluator>
|
||||
{
|
||||
public:
|
||||
typedef bond_accept_offer_operation operation_type;
|
||||
|
||||
object_id_type do_evaluate( const bond_accept_offer_operation& op );
|
||||
object_id_type do_apply( const bond_accept_offer_operation& op );
|
||||
|
||||
const bond_offer_object* _offer = nullptr;
|
||||
asset _fill_amount;
|
||||
};
|
||||
|
||||
class bond_claim_collateral_evaluator : public evaluator<bond_claim_collateral_evaluator>
|
||||
{
|
||||
public:
|
||||
typedef bond_claim_collateral_operation operation_type;
|
||||
|
||||
object_id_type do_evaluate( const bond_claim_collateral_operation& op );
|
||||
object_id_type do_apply( const bond_claim_collateral_operation& op );
|
||||
|
||||
const bond_object* _bond = nullptr;
|
||||
asset _interest_due;
|
||||
};
|
||||
|
||||
} } // graphene::chain
|
||||
|
|
@ -1,111 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Cryptonomex, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is provided for evaluation in private test networks only, until September 8, 2015. After this date, this license expires and
|
||||
* the code may not be used, modified or distributed for any purpose. Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted until September 8, 2015, provided that the following conditions are met:
|
||||
*
|
||||
* 1. The code and/or derivative works are used only for private test networks consisting of no more than 10 P2P nodes.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#pragma once
|
||||
#include <graphene/chain/authority.hpp>
|
||||
#include <graphene/chain/asset.hpp>
|
||||
#include <graphene/db/generic_index.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
/**
|
||||
* @ingroup object
|
||||
*/
|
||||
class bond_object : public graphene::db::abstract_object<bond_object>
|
||||
{
|
||||
public:
|
||||
static const uint8_t space_id = protocol_ids;
|
||||
static const uint8_t type_id = bond_object_type;
|
||||
|
||||
asset_id_type collateral_type()const { return collateral.asset_id; }
|
||||
|
||||
account_id_type borrower;
|
||||
account_id_type lender;
|
||||
asset borrowed;
|
||||
/** if collateral is the core asset, then voting rights belong to the borrower
|
||||
* because the borrower is owner of the collateral until they default
|
||||
*/
|
||||
asset collateral;
|
||||
uint16_t interest_apr = 0;
|
||||
time_point_sec start_date;
|
||||
/** after this date the lender can collect the collateral at will or let it float */
|
||||
time_point_sec due_date;
|
||||
/** the loan cannot be paid off before this date */
|
||||
time_point_sec earliest_payoff_date;
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup object
|
||||
*/
|
||||
class bond_offer_object : public graphene::db::abstract_object<bond_offer_object>
|
||||
{
|
||||
public:
|
||||
static const uint8_t space_id = protocol_ids;
|
||||
static const uint8_t type_id = bond_offer_object_type;
|
||||
|
||||
asset_id_type asset_type()const { return amount.asset_id; }
|
||||
|
||||
account_id_type offered_by_account;
|
||||
bool offer_to_borrow = false; // Offer to borrow if true, and offer to lend otherwise
|
||||
asset amount;
|
||||
share_type min_match; ///< asset type same as ammount.asset_id
|
||||
price collateral_rate;
|
||||
uint32_t min_loan_period_sec = 0;
|
||||
uint32_t loan_period_sec = 0;
|
||||
uint16_t interest_apr = 0;
|
||||
};
|
||||
|
||||
struct by_borrower;
|
||||
struct by_lender;
|
||||
struct by_offerer;
|
||||
struct by_collateral; /// needed for blackswan resolution
|
||||
struct by_asset; /// needed for blackswan resolution
|
||||
|
||||
typedef multi_index_container<
|
||||
bond_object,
|
||||
indexed_by<
|
||||
hashed_unique< tag<by_id>, member< object, object_id_type, &object::id > >,
|
||||
ordered_non_unique< tag<by_borrower>, member<bond_object, account_id_type, &bond_object::borrower> >,
|
||||
ordered_non_unique< tag<by_lender>, member<bond_object, account_id_type, &bond_object::lender> >,
|
||||
hashed_non_unique< tag<by_collateral>, const_mem_fun<bond_object, asset_id_type, &bond_object::collateral_type> >
|
||||
>
|
||||
> bond_object_multi_index_type;
|
||||
|
||||
typedef generic_index<bond_object, bond_object_multi_index_type> bond_index;
|
||||
|
||||
/**
|
||||
* Todo: consider adding index of tuple<collateral_type,loan_asset_type,interest_rate>
|
||||
* Todo: consider adding index of tuple<collateral_type,loan_asset_type,period>
|
||||
*/
|
||||
typedef multi_index_container<
|
||||
bond_offer_object,
|
||||
indexed_by<
|
||||
hashed_unique< tag<by_id>, member< object, object_id_type, &object::id > >,
|
||||
ordered_non_unique< tag<by_offerer>, member<bond_offer_object, account_id_type, &bond_offer_object::offered_by_account> >,
|
||||
hashed_non_unique< tag<by_asset>, const_mem_fun<bond_offer_object, asset_id_type, &bond_offer_object::asset_type> >
|
||||
>
|
||||
> bond_offer_object_multi_index_type;
|
||||
|
||||
typedef generic_index<bond_offer_object, bond_offer_object_multi_index_type> bond_offer_index;
|
||||
|
||||
}} // graphene::chain
|
||||
|
||||
FC_REFLECT_DERIVED( graphene::chain::bond_object, (graphene::db::object),
|
||||
(borrower)(lender)(borrowed)(collateral)(interest_apr)(start_date)(due_date)(earliest_payoff_date) )
|
||||
FC_REFLECT_DERIVED( graphene::chain::bond_offer_object, (graphene::db::object), (offered_by_account)(offer_to_borrow)(amount)(min_match)(collateral_rate)(min_loan_period_sec)(loan_period_sec)(interest_apr) )
|
||||
|
|
@ -114,3 +114,13 @@
|
|||
#define GRAPHENE_MAX_INTEREST_APR uint16_t( 10000 )
|
||||
#define GRAPHENE_LEGACY_NAME_IMPORT_PERIOD 3000000 /** 3 million blocks */
|
||||
|
||||
/**
|
||||
* Reserved Account IDs with special meaning
|
||||
*/
|
||||
///@{
|
||||
#define GRAPHENE_GENESIS_ACCOUNT (graphene::chain::account_id_type(0))
|
||||
#define GRAPHENE_WITNESS_ACCOUNT (graphene::chain::account_id_type(1))
|
||||
#define GRAPHENE_DELEGATE_ACCOUNT (graphene::chain::account_id_type(2))
|
||||
#define GRAPHENE_NULL_ACCOUNT (graphene::chain::account_id_type(3))
|
||||
#define GRAPHENE_TEMP_ACCOUNT (graphene::chain::account_id_type(4))
|
||||
///@}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace graphene { namespace chain {
|
|||
public:
|
||||
typedef custom_operation operation_type;
|
||||
|
||||
object_id_type do_evaluate( const custom_operation& o ){ return object_id_type(); }
|
||||
object_id_type do_apply( const custom_operation& o ){ return object_id_type(); }
|
||||
void_result do_evaluate( const custom_operation& o ){ return void_result(); }
|
||||
void_result do_apply( const custom_operation& o ){ return void_result(); }
|
||||
};
|
||||
} }
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ namespace graphene { namespace chain {
|
|||
class evaluator : public generic_evaluator
|
||||
{
|
||||
public:
|
||||
virtual int get_type()const { return operation::tag<typename DerivedEvaluator::operation_type>::value; }
|
||||
virtual int get_type()const override { return operation::tag<typename DerivedEvaluator::operation_type>::value; }
|
||||
|
||||
virtual operation_result evaluate( const operation& o ) final override
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Cryptonomex, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is provided for evaluation in private test networks only, until September 8, 2015. After this date, this license expires and
|
||||
* the code may not be used, modified or distributed for any purpose. Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted until September 8, 2015, provided that the following conditions are met:
|
||||
*
|
||||
* 1. The code and/or derivative works are used only for private test networks consisting of no more than 10 P2P nodes.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
|
||||
/**
|
||||
* @brief provides for persistant storage of arbitrary data
|
||||
*
|
||||
* Smart contracts need data to be stored persistantly that can be shared with
|
||||
* other smart contracts. There is a cost associated with storing data, especially if
|
||||
* that data will be kept in RAM.
|
||||
*
|
||||
* File objects allow smart contracts to interact with persistant storage much like
|
||||
* traditional programs interact with files on disk. The cost of accessing a file
|
||||
* object to modify it is much higher than the cost to simply read it because the
|
||||
* the database must make a backup of the file for the undo history in the event
|
||||
* of a blockchain reorganization or failure in evaluation. For this reason files
|
||||
* are limited to 2^16 bytes and smart contracts will have to use multiple files if
|
||||
* they need to store additional data.
|
||||
*
|
||||
* Every file has an automatic expiration date at which point in time it will be
|
||||
* deleted unless a fee is paid to extend its life time.
|
||||
*
|
||||
* The contents of all files are public, but not to scripts. A smart contract attempting
|
||||
* to access the contents of a file must have permission to read the file. The purpose
|
||||
* of this restriction is to help users monetize the trust associated with publishing
|
||||
* data. Anyone could re-publish the data under a new file, but the trust in the
|
||||
* quality of the data would not be the same as the original file.
|
||||
*/
|
||||
class file_object : public graphene::db::annotated_object<file_object>
|
||||
{
|
||||
public:
|
||||
static const uint8_t space_id = protocol_ids;
|
||||
static const uint8_t type_id = file_object_type;
|
||||
|
||||
/**
|
||||
* @brief sets bits that control the permissions granted to smart contracts regarding this data.
|
||||
*/
|
||||
enum permision_flags
|
||||
{
|
||||
owner_read = 0x01,
|
||||
owner_write = 0x02,
|
||||
group_read = 0x04,
|
||||
group_write = 0x08,
|
||||
all_read = 0x10,
|
||||
execute = 0x20 ///< set if data contains virtual machine instructions
|
||||
};
|
||||
|
||||
/**
|
||||
* The owner can access this file based upon the @ref permissions flags
|
||||
*
|
||||
* @note - if the owner removes write permission from himself then the file
|
||||
* will be imutable thereafter.
|
||||
*/
|
||||
account_id_type owner;
|
||||
/** any account that has been white listed by this group can read/write
|
||||
* @ref data based upon the @ref permissions flags.
|
||||
*/
|
||||
account_id_type group;
|
||||
/**
|
||||
* Bits set according to @ref permission_flags
|
||||
*/
|
||||
uint8_t permissions = owner_read | owner_write | all_read;
|
||||
|
||||
/**
|
||||
* Files consume memory and thus are cleaned up unless a fee is paid to
|
||||
* keep them alive.
|
||||
*/
|
||||
time_point_sec expiration;
|
||||
|
||||
/**
|
||||
* The maximum data size for a file is 2^16 bytes so that the
|
||||
* undo history doesn't have to backup larger files. If a smart contract
|
||||
* requires more data then it can create more file objects.
|
||||
*/
|
||||
vector<char> data;
|
||||
};
|
||||
|
||||
struct by_expiration;
|
||||
struct by_owner;
|
||||
struct by_group;
|
||||
/**
|
||||
* @ingroup object_index
|
||||
*/
|
||||
typedef multi_index_container<
|
||||
file_object,
|
||||
indexed_by<
|
||||
hashed_unique< tag<by_id>, member< object, object_id_type, &object::id > >,
|
||||
hashed_non_unique< tag<by_owner>, member< file_object, account_id_type, &file_object::owner > >,
|
||||
hashed_non_unique< tag<by_group>, member< file_object, account_id_type, &file_object::group > >,
|
||||
ordered_non_unique< tag<by_expiration>, member<file_object, time_point_sec, &file_object::expiration> >
|
||||
>
|
||||
> file_object_multi_index_type;
|
||||
|
||||
typedef generic_index<file_object, file_object_multi_index_type> file_object_index;
|
||||
|
||||
} }
|
||||
|
||||
FC_REFLECT_ENUM( graphene::chain::file_object::permision_flags, (owner_read)(owner_write)(group_read)(group_write)(all_read)(execute) )
|
||||
FC_REFLECT_DERIVED( graphene::chain::file_object, (graphene::db::object), (owner)(group)(permissions)(expiration)(data) )
|
||||
|
|
@ -26,8 +26,8 @@ class global_parameters_update_evaluator : public evaluator<global_parameters_up
|
|||
public:
|
||||
typedef global_parameters_update_operation operation_type;
|
||||
|
||||
object_id_type do_evaluate( const global_parameters_update_operation& o );
|
||||
object_id_type do_apply( const global_parameters_update_operation& o );
|
||||
void_result do_evaluate( const global_parameters_update_operation& o );
|
||||
void_result do_apply( const global_parameters_update_operation& o );
|
||||
};
|
||||
|
||||
} } // graphene::chain
|
||||
|
|
|
|||
|
|
@ -1248,198 +1248,6 @@ namespace graphene { namespace chain {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief create/update the contents of a file.
|
||||
*
|
||||
* Any account may pay a fee and write no data to extend the lease seconds
|
||||
* on a file.
|
||||
*
|
||||
* If the file size increasees, the current lease_seconds will be adjusted downward to maintain
|
||||
* the same byte-days-leased. Then any new leased seconds will be added based upon the
|
||||
* new file size.
|
||||
*
|
||||
* @see file_object
|
||||
*/
|
||||
struct file_write_operation
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* The fee charges is proportional to @ref file_size * @ref lease_seconds
|
||||
*/
|
||||
asset fee;
|
||||
/**
|
||||
* THe account that is paying the update fee
|
||||
*/
|
||||
account_id_type payer;
|
||||
|
||||
/** file_id 0 indicates a new file should be created */
|
||||
file_id_type file_id;
|
||||
|
||||
/** may read/write accoding to flags, write permission is required to change owner/group/flags */
|
||||
account_id_type owner;
|
||||
|
||||
/** may read/write according fo flags, but may not update flags or owner */
|
||||
account_id_type group;
|
||||
|
||||
/**
|
||||
* Must be less than or equal to 0x2f
|
||||
*/
|
||||
uint8_t flags = 0;
|
||||
|
||||
/**
|
||||
* If the file doesn't exist, it will be intialized to file_size with 0
|
||||
* before writing data.
|
||||
*
|
||||
* @pre data.size() + offset <= 2^16
|
||||
*/
|
||||
uint16_t offset = 0;
|
||||
vector<char> data;
|
||||
|
||||
/**
|
||||
* The length of time to extend the lease on the file, must be less
|
||||
* than 10 years.
|
||||
*/
|
||||
uint32_t lease_seconds = 0;
|
||||
|
||||
/**
|
||||
* File size must be greater than 0
|
||||
*/
|
||||
uint16_t file_size = 0;
|
||||
|
||||
/**
|
||||
* If file_id is not 0, then precondition checksum verifies that
|
||||
* the file contents are as expected prior to writing data.
|
||||
*/
|
||||
optional<checksum_type> precondition_checksum;
|
||||
|
||||
account_id_type fee_payer()const { return payer; }
|
||||
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const { active_auth_set.insert(fee_payer()); }
|
||||
void validate()const;
|
||||
share_type calculate_fee( const fee_schedule_type& k )const;
|
||||
|
||||
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const
|
||||
{
|
||||
acc.adjust( fee_payer(), -fee );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup operations
|
||||
*
|
||||
* Bond offers are objects that exist on the blockchain and can be
|
||||
* filled in full or in part by someone using the accept_bond_offer
|
||||
* operation. When the offer is accepted a new bond_object is
|
||||
* created that defines the terms of the loan.
|
||||
*
|
||||
* @return bond_offer_id
|
||||
*/
|
||||
struct bond_create_offer_operation
|
||||
{
|
||||
asset fee;
|
||||
account_id_type creator;
|
||||
bool offer_to_borrow = false; ///< Offer to borrow if true, and offer to lend otherwise
|
||||
asset amount; ///< Amount to lend or secure depending on above
|
||||
share_type min_match; ///< asset id same as amount.asset_id and sets the minimum match that will be accepted
|
||||
price collateral_rate; ///< To derive amount of collateral or principle based on above
|
||||
/** after this time the lender can let the loan float or collect the collateral at will */
|
||||
uint32_t min_loan_period_sec = 0; ///< the earliest the loan may be paid off
|
||||
uint32_t loan_period_sec = 0;
|
||||
uint16_t interest_apr = 0; ///< MAX_INTEREST_APR == 100% and is max value
|
||||
|
||||
account_id_type fee_payer()const { return creator; }
|
||||
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
|
||||
void validate()const;
|
||||
share_type calculate_fee( const fee_schedule_type& k )const;
|
||||
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const
|
||||
{
|
||||
acc.adjust( fee_payer(), -fee );
|
||||
acc.adjust( creator, -amount );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup operations
|
||||
* Subtracts refund from bond_offer.amount and frees bond_offer if refund == bond_offer.amount
|
||||
*/
|
||||
struct bond_cancel_offer_operation
|
||||
{
|
||||
asset fee;
|
||||
account_id_type creator;
|
||||
bond_offer_id_type offer_id;
|
||||
asset refund;
|
||||
|
||||
account_id_type fee_payer()const { return creator; }
|
||||
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
|
||||
void validate()const;
|
||||
share_type calculate_fee( const fee_schedule_type& k )const;
|
||||
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const
|
||||
{
|
||||
acc.adjust( fee_payer(), -fee );
|
||||
acc.adjust( creator, refund );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup operations
|
||||
* @return new bond_id
|
||||
*/
|
||||
struct bond_accept_offer_operation
|
||||
{
|
||||
asset fee;
|
||||
account_id_type claimer;
|
||||
account_id_type lender;
|
||||
account_id_type borrower; ///< included in case of offer to borrow, because borrower will receive funds
|
||||
bond_offer_id_type offer_id;
|
||||
asset amount_borrowed; ///< should equal amount_collateral * offer_id->collateral_rate
|
||||
asset amount_collateral; ///< should equal amount_borrowed * offer_id->collateral_rate
|
||||
|
||||
account_id_type fee_payer()const { return claimer; }
|
||||
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
|
||||
void validate()const;
|
||||
share_type calculate_fee( const fee_schedule_type& k )const;
|
||||
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const
|
||||
{
|
||||
acc.adjust( fee_payer(), -fee );
|
||||
if( claimer == lender )
|
||||
acc.adjust( claimer, -amount_borrowed );
|
||||
else // claimer == borrower
|
||||
acc.adjust( claimer, -amount_collateral );
|
||||
acc.adjust( borrower, amount_borrowed );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup operations
|
||||
* After the loan period the lender can claim
|
||||
* the collateral, prior to the loan period expiring
|
||||
* the borrower can claim it by paying off the loan
|
||||
*/
|
||||
struct bond_claim_collateral_operation
|
||||
{
|
||||
asset fee;
|
||||
account_id_type claimer; ///< must be bond_id->lender or bond_id->borrower
|
||||
account_id_type lender; ///< must be bond_id->lender
|
||||
bond_id_type bond_id;
|
||||
asset payoff_amount;
|
||||
|
||||
/** the borrower can claim a percentage of the collateral propotional to the
|
||||
* percentage of the debt+interest that was paid off
|
||||
*/
|
||||
asset collateral_claimed;
|
||||
|
||||
account_id_type fee_payer()const { return claimer; }
|
||||
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
|
||||
void validate()const;
|
||||
share_type calculate_fee( const fee_schedule_type& k )const;
|
||||
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const
|
||||
{
|
||||
acc.adjust( fee_payer(), -fee );
|
||||
acc.adjust( claimer, -payoff_amount );
|
||||
acc.adjust( claimer, collateral_claimed );
|
||||
acc.adjust( lender, payoff_amount );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a vesting balance.
|
||||
* @ingroup operations
|
||||
|
|
@ -1617,13 +1425,8 @@ namespace graphene { namespace chain {
|
|||
withdraw_permission_delete_operation,
|
||||
fill_order_operation,
|
||||
global_parameters_update_operation,
|
||||
file_write_operation,
|
||||
vesting_balance_create_operation,
|
||||
vesting_balance_withdraw_operation,
|
||||
bond_create_offer_operation,
|
||||
bond_cancel_offer_operation,
|
||||
bond_accept_offer_operation,
|
||||
bond_claim_collateral_operation,
|
||||
worker_create_operation,
|
||||
custom_operation
|
||||
> operation;
|
||||
|
|
@ -1852,13 +1655,6 @@ FC_REFLECT( graphene::chain::withdraw_permission_claim_operation, (fee)(withdraw
|
|||
FC_REFLECT( graphene::chain::withdraw_permission_delete_operation, (fee)(withdraw_from_account)(authorized_account)
|
||||
(withdrawal_permission) )
|
||||
|
||||
FC_REFLECT( graphene::chain::file_write_operation, (fee)(payer)(file_id)(owner)(group)(flags)(offset)(data)(lease_seconds)(file_size)(precondition_checksum) )
|
||||
|
||||
FC_REFLECT( graphene::chain::bond_create_offer_operation, (fee)(creator)(offer_to_borrow)(amount)(min_match)(collateral_rate)(min_loan_period_sec)(loan_period_sec)(interest_apr) )
|
||||
FC_REFLECT( graphene::chain::bond_cancel_offer_operation, (fee)(creator)(offer_id)(refund) )
|
||||
FC_REFLECT( graphene::chain::bond_accept_offer_operation, (fee)(claimer)(lender)(borrower)(offer_id)(amount_borrowed)(amount_collateral) )
|
||||
FC_REFLECT( graphene::chain::bond_claim_collateral_operation, (fee)(claimer)(lender)(bond_id)(payoff_amount)(collateral_claimed) )
|
||||
|
||||
FC_REFLECT( graphene::chain::vesting_balance_create_operation, (fee)(creator)(owner)(amount)(vesting_seconds) )
|
||||
FC_REFLECT( graphene::chain::vesting_balance_withdraw_operation, (fee)(vesting_balance)(owner)(amount) )
|
||||
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@ namespace graphene { namespace chain {
|
|||
public:
|
||||
typedef proposal_update_operation operation_type;
|
||||
|
||||
object_id_type do_evaluate( const proposal_update_operation& o );
|
||||
object_id_type do_apply( const proposal_update_operation& o );
|
||||
void_result do_evaluate( const proposal_update_operation& o );
|
||||
void_result do_apply( const proposal_update_operation& o );
|
||||
|
||||
const proposal_object* _proposal = nullptr;
|
||||
processed_transaction _processed_transaction;
|
||||
|
|
@ -54,8 +54,8 @@ namespace graphene { namespace chain {
|
|||
public:
|
||||
typedef proposal_delete_operation operation_type;
|
||||
|
||||
object_id_type do_evaluate( const proposal_delete_operation& o );
|
||||
object_id_type do_apply(const proposal_delete_operation&);
|
||||
void_result do_evaluate( const proposal_delete_operation& o );
|
||||
void_result do_apply(const proposal_delete_operation&);
|
||||
|
||||
const proposal_object* _proposal = nullptr;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -142,10 +142,17 @@ namespace graphene { namespace chain {
|
|||
: transaction(trx){}
|
||||
|
||||
void sign( key_id_type id, const private_key_type& key );
|
||||
|
||||
flat_map<key_id_type,signature_type> signatures;
|
||||
|
||||
/** some operations may depend only upon a signature and not
|
||||
* require account approval. This allows those extra signatures
|
||||
* to be added to the transaction.
|
||||
*/
|
||||
flat_map<address,signature_type> extra_signatures;
|
||||
|
||||
/// Removes all operations and signatures
|
||||
void clear() { operations.clear(); signatures.clear(); }
|
||||
void clear() { operations.clear(); signatures.clear(); extra_signatures.clear(); }
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -177,6 +184,5 @@ namespace graphene { namespace chain {
|
|||
} }
|
||||
|
||||
FC_REFLECT( graphene::chain::transaction, (ref_block_num)(ref_block_prefix)(relative_expiration)(operations) )
|
||||
FC_REFLECT_DERIVED( graphene::chain::signed_transaction, (graphene::chain::transaction), (signatures) )
|
||||
FC_REFLECT_DERIVED( graphene::chain::signed_transaction, (graphene::chain::transaction), (signatures)(extra_signatures) )
|
||||
FC_REFLECT_DERIVED( graphene::chain::processed_transaction, (graphene::chain::signed_transaction), (operation_results) )
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,9 @@ namespace graphene { namespace chain {
|
|||
using fc::flat_map;
|
||||
using fc::flat_set;
|
||||
using fc::static_variant;
|
||||
using fc::ecc::range_proof_type;
|
||||
using fc::ecc::range_proof_info;
|
||||
using fc::ecc::commitment_type;
|
||||
|
||||
typedef fc::ecc::private_key private_key_type;
|
||||
|
||||
|
|
@ -111,9 +114,6 @@ namespace graphene { namespace chain {
|
|||
proposal_object_type,
|
||||
operation_history_object_type,
|
||||
withdraw_permission_object_type,
|
||||
bond_offer_object_type,
|
||||
bond_object_type,
|
||||
file_object_type,
|
||||
vesting_balance_object_type,
|
||||
worker_object_type,
|
||||
OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types
|
||||
|
|
@ -158,9 +158,6 @@ namespace graphene { namespace chain {
|
|||
class proposal_object;
|
||||
class operation_history_object;
|
||||
class withdraw_permission_object;
|
||||
class bond_object;
|
||||
class bond_offer_object;
|
||||
class file_object;
|
||||
class vesting_balance_object;
|
||||
class witness_schedule_object;
|
||||
class worker_object;
|
||||
|
|
@ -178,9 +175,6 @@ namespace graphene { namespace chain {
|
|||
typedef object_id< protocol_ids, proposal_object_type, proposal_object> proposal_id_type;
|
||||
typedef object_id< protocol_ids, operation_history_object_type, operation_history_object> operation_history_id_type;
|
||||
typedef object_id< protocol_ids, withdraw_permission_object_type,withdraw_permission_object> withdraw_permission_id_type;
|
||||
typedef object_id< protocol_ids, bond_offer_object_type, bond_offer_object> bond_offer_id_type;
|
||||
typedef object_id< protocol_ids, bond_object_type, bond_object> bond_id_type;
|
||||
typedef object_id< protocol_ids, file_object_type, file_object> file_id_type;
|
||||
typedef object_id< protocol_ids, vesting_balance_object_type, vesting_balance_object> vesting_balance_id_type;
|
||||
typedef object_id< protocol_ids, worker_object_type, worker_object> worker_id_type;
|
||||
|
||||
|
|
@ -379,11 +373,6 @@ namespace graphene { namespace chain {
|
|||
uint32_t membership_annual_fee; ///< the annual cost of a membership subscription
|
||||
uint32_t membership_lifetime_fee; ///< the cost to upgrade to a lifetime member
|
||||
uint32_t withdraw_permission_update_fee; ///< the cost to create/update a withdraw permission
|
||||
uint32_t create_bond_offer_fee;
|
||||
uint32_t cancel_bond_offer_fee;
|
||||
uint32_t accept_bond_offer_fee;
|
||||
uint32_t claim_bond_collateral_fee;
|
||||
uint32_t file_storage_fee_per_day; ///< the cost of leasing a file with 2^16 bytes for 1 day
|
||||
uint32_t vesting_balance_create_fee;
|
||||
uint32_t vesting_balance_withdraw_fee;
|
||||
uint32_t global_settle_fee;
|
||||
|
|
@ -504,9 +493,6 @@ FC_REFLECT_ENUM( graphene::chain::object_type,
|
|||
(proposal_object_type)
|
||||
(operation_history_object_type)
|
||||
(withdraw_permission_object_type)
|
||||
(bond_offer_object_type)
|
||||
(bond_object_type)
|
||||
(file_object_type)
|
||||
(vesting_balance_object_type)
|
||||
(worker_object_type)
|
||||
(OBJECT_TYPE_COUNT)
|
||||
|
|
@ -561,11 +547,6 @@ FC_REFLECT( graphene::chain::fee_schedule_type,
|
|||
(membership_annual_fee)
|
||||
(membership_lifetime_fee)
|
||||
(withdraw_permission_update_fee)
|
||||
(create_bond_offer_fee)
|
||||
(cancel_bond_offer_fee)
|
||||
(accept_bond_offer_fee)
|
||||
(claim_bond_collateral_fee)
|
||||
(file_storage_fee_per_day)
|
||||
(vesting_balance_create_fee)
|
||||
(vesting_balance_withdraw_fee)
|
||||
(global_settle_fee)
|
||||
|
|
@ -612,9 +593,6 @@ FC_REFLECT_TYPENAME( graphene::chain::custom_id_type )
|
|||
FC_REFLECT_TYPENAME( graphene::chain::proposal_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::operation_history_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::withdraw_permission_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::bond_offer_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::bond_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::file_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::vesting_balance_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::worker_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::relative_key_id_type )
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@ class vesting_balance_withdraw_evaluator : public evaluator<vesting_balance_with
|
|||
public:
|
||||
typedef vesting_balance_withdraw_operation operation_type;
|
||||
|
||||
object_id_type do_evaluate( const vesting_balance_withdraw_operation& op );
|
||||
object_id_type do_apply( const vesting_balance_withdraw_operation& op );
|
||||
void_result do_evaluate( const vesting_balance_withdraw_operation& op );
|
||||
void_result do_apply( const vesting_balance_withdraw_operation& op );
|
||||
};
|
||||
|
||||
} } // graphene::chain
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ namespace graphene { namespace chain {
|
|||
public:
|
||||
typedef witness_withdraw_pay_operation operation_type;
|
||||
|
||||
object_id_type do_evaluate( const operation_type& o );
|
||||
object_id_type do_apply( const operation_type& o );
|
||||
void_result do_evaluate( const operation_type& o );
|
||||
void_result do_apply( const operation_type& o );
|
||||
|
||||
const witness_object* witness;
|
||||
const account_object* to_account;
|
||||
|
|
|
|||
|
|
@ -86,11 +86,7 @@ class hash_ctr_rng
|
|||
{
|
||||
if( bound <= 1 )
|
||||
return 0;
|
||||
#ifdef __GNUC__
|
||||
uint8_t bitcount( 64 - __builtin_clzll( bound ) );
|
||||
#else
|
||||
uint8_t bitcount( 64 - boost::multiprecision::detail::find_msb( bound ) );
|
||||
#endif
|
||||
uint8_t bitcount = boost::multiprecision::detail::find_msb( bound ) + 1;
|
||||
|
||||
// probability of loop exiting is >= 1/2, so probability of
|
||||
// running N times is bounded above by (1/2)^N
|
||||
|
|
|
|||
|
|
@ -717,20 +717,6 @@ void asset_update_feed_producers_operation::validate() const
|
|||
{
|
||||
FC_ASSERT( fee.amount >= 0 );
|
||||
}
|
||||
void file_write_operation::validate()const
|
||||
{
|
||||
FC_ASSERT( uint32_t(offset) + data.size() <= file_size );
|
||||
FC_ASSERT( flags <= 0x2f );
|
||||
FC_ASSERT( file_size > 0 );
|
||||
/** less than 10 years to prevent overflow of 64 bit numbers in the value*lease_seconds*file_size calculation */
|
||||
FC_ASSERT( lease_seconds < 60*60*24*365*10 );
|
||||
}
|
||||
|
||||
share_type file_write_operation::calculate_fee( const fee_schedule_type& k )const
|
||||
{
|
||||
return ((((k.file_storage_fee_per_day * lease_seconds)/(60*60*24))*file_size)/0xff) + ((data.size() * k.data_fee)/1024);
|
||||
}
|
||||
|
||||
|
||||
void vesting_balance_create_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const
|
||||
{
|
||||
|
|
@ -818,77 +804,6 @@ share_type custom_operation::calculate_fee( const fee_schedule_type& k )const
|
|||
return (data.size() * k.data_fee)/1024;
|
||||
}
|
||||
|
||||
void bond_create_offer_operation::get_required_auth( flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>& )const
|
||||
{
|
||||
active_auth_set.insert( creator );
|
||||
}
|
||||
|
||||
void bond_create_offer_operation::validate()const
|
||||
{ try {
|
||||
FC_ASSERT( fee.amount >= 0 );
|
||||
FC_ASSERT( amount.amount > 0 );
|
||||
collateral_rate.validate();
|
||||
FC_ASSERT( (amount * collateral_rate).amount > 0 );
|
||||
FC_ASSERT( min_loan_period_sec > 0 );
|
||||
FC_ASSERT( loan_period_sec >= min_loan_period_sec );
|
||||
FC_ASSERT( interest_apr <= GRAPHENE_MAX_INTEREST_APR );
|
||||
} FC_CAPTURE_AND_RETHROW((*this)) }
|
||||
|
||||
share_type bond_create_offer_operation::calculate_fee( const fee_schedule_type& schedule )const
|
||||
{
|
||||
return schedule.create_bond_offer_fee;
|
||||
}
|
||||
|
||||
|
||||
void bond_cancel_offer_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const
|
||||
{
|
||||
active_auth_set.insert( creator );
|
||||
}
|
||||
void bond_cancel_offer_operation::validate()const
|
||||
{
|
||||
FC_ASSERT( fee.amount > 0 );
|
||||
FC_ASSERT( refund.amount > 0 );
|
||||
}
|
||||
share_type bond_cancel_offer_operation::calculate_fee( const fee_schedule_type& k )const
|
||||
{
|
||||
return k.cancel_bond_offer_fee;
|
||||
}
|
||||
|
||||
void bond_accept_offer_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const
|
||||
{
|
||||
active_auth_set.insert( claimer );
|
||||
}
|
||||
|
||||
void bond_accept_offer_operation::validate()const
|
||||
{
|
||||
FC_ASSERT( fee.amount > 0 );
|
||||
(amount_collateral / amount_borrowed).validate();
|
||||
FC_ASSERT( claimer == borrower || claimer == lender );
|
||||
FC_ASSERT( borrower != lender );
|
||||
}
|
||||
|
||||
share_type bond_accept_offer_operation::calculate_fee( const fee_schedule_type& k )const
|
||||
{
|
||||
return k.accept_bond_offer_fee;
|
||||
}
|
||||
void bond_claim_collateral_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const
|
||||
{
|
||||
active_auth_set.insert( claimer );
|
||||
}
|
||||
|
||||
void bond_claim_collateral_operation::validate()const
|
||||
{
|
||||
FC_ASSERT( fee.amount > 0 );
|
||||
FC_ASSERT(payoff_amount.amount >= 0 );
|
||||
FC_ASSERT(collateral_claimed.amount >= 0 );
|
||||
FC_ASSERT( payoff_amount.asset_id != collateral_claimed.asset_id );
|
||||
}
|
||||
|
||||
share_type bond_claim_collateral_operation::calculate_fee( const fee_schedule_type& k )const
|
||||
{
|
||||
return k.claim_bond_collateral_fee;
|
||||
}
|
||||
|
||||
void worker_create_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&) const
|
||||
{
|
||||
active_auth_set.insert(owner);
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ object_id_type proposal_create_evaluator::do_apply(const proposal_create_operati
|
|||
return proposal.id;
|
||||
}
|
||||
|
||||
object_id_type proposal_update_evaluator::do_evaluate(const proposal_update_operation& o)
|
||||
void_result proposal_update_evaluator::do_evaluate(const proposal_update_operation& o)
|
||||
{
|
||||
database& d = db();
|
||||
|
||||
|
|
@ -102,10 +102,10 @@ object_id_type proposal_update_evaluator::do_evaluate(const proposal_update_oper
|
|||
FC_ASSERT( trx_state->signed_by(id) || trx_state->_skip_authority_check );
|
||||
}
|
||||
|
||||
return object_id_type();
|
||||
return void_result();
|
||||
}
|
||||
|
||||
object_id_type proposal_update_evaluator::do_apply(const proposal_update_operation& o)
|
||||
void_result proposal_update_evaluator::do_apply(const proposal_update_operation& o)
|
||||
{
|
||||
database& d = db();
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ object_id_type proposal_update_evaluator::do_apply(const proposal_update_operati
|
|||
// If the proposal has a review period, don't bother attempting to authorize/execute it.
|
||||
// Proposals with a review period may never be executed except at their expiration.
|
||||
if( _proposal->review_period_time )
|
||||
return object_id_type();
|
||||
return void_result();
|
||||
|
||||
if( _proposal->is_authorized_to_execute(&d) )
|
||||
{
|
||||
|
|
@ -143,10 +143,10 @@ object_id_type proposal_update_evaluator::do_apply(const proposal_update_operati
|
|||
}
|
||||
}
|
||||
|
||||
return object_id_type();
|
||||
return void_result();
|
||||
}
|
||||
|
||||
object_id_type proposal_delete_evaluator::do_evaluate(const proposal_delete_operation& o)
|
||||
void_result proposal_delete_evaluator::do_evaluate(const proposal_delete_operation& o)
|
||||
{
|
||||
database& d = db();
|
||||
|
||||
|
|
@ -158,14 +158,14 @@ object_id_type proposal_delete_evaluator::do_evaluate(const proposal_delete_oper
|
|||
"Provided authority is not authoritative for this proposal.",
|
||||
("provided", o.fee_paying_account)("required", *required_approvals));
|
||||
|
||||
return object_id_type();
|
||||
return void_result();
|
||||
}
|
||||
|
||||
object_id_type proposal_delete_evaluator::do_apply(const proposal_delete_operation&)
|
||||
void_result proposal_delete_evaluator::do_apply(const proposal_delete_operation&)
|
||||
{
|
||||
db().remove(*_proposal);
|
||||
|
||||
return object_id_type();
|
||||
return void_result();
|
||||
}
|
||||
|
||||
} } // graphene::chain
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ object_id_type vesting_balance_create_evaluator::do_apply( const vesting_balance
|
|||
return vbo.id;
|
||||
}
|
||||
|
||||
object_id_type vesting_balance_withdraw_evaluator::do_evaluate( const vesting_balance_withdraw_operation& op )
|
||||
void_result vesting_balance_withdraw_evaluator::do_evaluate( const vesting_balance_withdraw_operation& op )
|
||||
{
|
||||
const database& d = db();
|
||||
const time_point_sec now = d.head_block_time();
|
||||
|
|
@ -81,10 +81,10 @@ object_id_type vesting_balance_withdraw_evaluator::do_evaluate( const vesting_ba
|
|||
|
||||
/* const account_object& owner_account = */ op.owner( d );
|
||||
// TODO: Check asset authorizations and withdrawals
|
||||
return object_id_type();
|
||||
return void_result();
|
||||
}
|
||||
|
||||
object_id_type vesting_balance_withdraw_evaluator::do_apply( const vesting_balance_withdraw_operation& op )
|
||||
void_result vesting_balance_withdraw_evaluator::do_apply( const vesting_balance_withdraw_operation& op )
|
||||
{
|
||||
database& d = db();
|
||||
const time_point_sec now = d.head_block_time();
|
||||
|
|
@ -103,7 +103,7 @@ object_id_type vesting_balance_withdraw_evaluator::do_apply( const vesting_balan
|
|||
d.adjust_balance( op.owner, op.amount );
|
||||
|
||||
// TODO: Check asset authorizations and withdrawals
|
||||
return object_id_type();
|
||||
return void_result();
|
||||
}
|
||||
|
||||
} } // graphene::chain
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ object_id_type witness_create_evaluator::do_apply( const witness_create_operatio
|
|||
return new_witness_object.id;
|
||||
}
|
||||
|
||||
object_id_type witness_withdraw_pay_evaluator::do_evaluate(const witness_withdraw_pay_evaluator::operation_type& o)
|
||||
void_result witness_withdraw_pay_evaluator::do_evaluate(const witness_withdraw_pay_evaluator::operation_type& o)
|
||||
{
|
||||
database& d = db();
|
||||
|
||||
|
|
@ -55,10 +55,10 @@ object_id_type witness_withdraw_pay_evaluator::do_evaluate(const witness_withdra
|
|||
("w", o.amount)("e", witness->accumulated_income) );
|
||||
to_account = &d.get(o.to_account);
|
||||
|
||||
return object_id_type();
|
||||
return void_result();
|
||||
}
|
||||
|
||||
object_id_type witness_withdraw_pay_evaluator::do_apply(const witness_withdraw_pay_evaluator::operation_type& o)
|
||||
void_result witness_withdraw_pay_evaluator::do_apply(const witness_withdraw_pay_evaluator::operation_type& o)
|
||||
{
|
||||
database& d = db();
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ object_id_type witness_withdraw_pay_evaluator::do_apply(const witness_withdraw_p
|
|||
w.accumulated_income -= o.amount;
|
||||
});
|
||||
|
||||
return object_id_type();
|
||||
return void_result();
|
||||
}
|
||||
|
||||
} } // graphene::chain
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ namespace graphene { namespace db {
|
|||
modify_callback( _objects[obj.id.instance()] );
|
||||
}
|
||||
|
||||
virtual const object& insert( object&& obj )
|
||||
virtual const object& insert( object&& obj )override
|
||||
{
|
||||
auto instance = obj.id.instance();
|
||||
assert( nullptr != dynamic_cast<T*>(&obj) );
|
||||
|
|
@ -77,7 +77,7 @@ namespace graphene { namespace db {
|
|||
return &_objects[instance];
|
||||
}
|
||||
|
||||
void inspect_all_objects(std::function<void (const object&)> inspector)const
|
||||
virtual void inspect_all_objects(std::function<void (const object&)> inspector)const override
|
||||
{
|
||||
try {
|
||||
for( const auto& ptr : _objects )
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ namespace graphene { namespace chain {
|
|||
typedef MultiIndexType index_type;
|
||||
typedef ObjectType object_type;
|
||||
|
||||
virtual const object& insert( object&& obj )
|
||||
virtual const object& insert( object&& obj )override
|
||||
{
|
||||
assert( nullptr != dynamic_cast<ObjectType*>(&obj) );
|
||||
auto insert_result = _indices.insert( std::move( static_cast<ObjectType&>(obj) ) );
|
||||
|
|
@ -49,7 +49,7 @@ namespace graphene { namespace chain {
|
|||
return *insert_result.first;
|
||||
}
|
||||
|
||||
virtual const object& create(const std::function<void(object&)>& constructor )
|
||||
virtual const object& create(const std::function<void(object&)>& constructor )override
|
||||
{
|
||||
ObjectType item;
|
||||
item.id = get_next_id();
|
||||
|
|
|
|||
|
|
@ -166,16 +166,16 @@ namespace graphene { namespace db {
|
|||
virtual uint8_t object_type_id()const override
|
||||
{ return object_type::type_id; }
|
||||
|
||||
virtual object_id_type get_next_id()const { return _next_id; }
|
||||
virtual void use_next_id() { ++_next_id.number; }
|
||||
virtual void set_next_id( object_id_type id ) { _next_id = id; }
|
||||
virtual object_id_type get_next_id()const override { return _next_id; }
|
||||
virtual void use_next_id()override { ++_next_id.number; }
|
||||
virtual void set_next_id( object_id_type id )override { _next_id = id; }
|
||||
|
||||
virtual const object& load( const std::vector<char>& data )
|
||||
virtual const object& load( const std::vector<char>& data )override
|
||||
{
|
||||
return DerivedIndex::insert( fc::raw::unpack<object_type>( data ) );
|
||||
}
|
||||
|
||||
virtual void open( const shared_ptr<graphene::db::level_map<object_id_type, vector<char> >>& db )
|
||||
virtual void open( const shared_ptr<graphene::db::level_map<object_id_type, vector<char> >>& db )override
|
||||
{
|
||||
auto first = object_id_type( DerivedIndex::object_type::space_id, DerivedIndex::object_type::type_id, 0 );
|
||||
auto last = object_id_type( DerivedIndex::object_type::space_id, DerivedIndex::object_type::type_id+1, 0 );
|
||||
|
|
@ -186,7 +186,7 @@ namespace graphene { namespace db {
|
|||
++itr;
|
||||
}
|
||||
}
|
||||
virtual const object& create(const std::function<void(object&)>& constructor )
|
||||
virtual const object& create(const std::function<void(object&)>& constructor )override
|
||||
{
|
||||
const auto& result = DerivedIndex::create( constructor );
|
||||
on_add( result );
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ namespace graphene { namespace db {
|
|||
modify_callback( *_objects[obj.id.instance()] );
|
||||
}
|
||||
|
||||
virtual const object& insert( object&& obj )
|
||||
virtual const object& insert( object&& obj )override
|
||||
{
|
||||
auto instance = obj.id.instance();
|
||||
assert( nullptr != dynamic_cast<T*>(&obj) );
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 18e80eca239c5c2b0e349091d3d0894196b7b895
|
||||
Subproject commit c425a019cd9e6e2abced9c25628a29c98d9f66c1
|
||||
|
|
@ -173,9 +173,6 @@ struct operation_get_impacted_accounts
|
|||
}
|
||||
|
||||
void operator()( const asset_create_operation& o )const { }
|
||||
void operator()( const file_write_operation& o )const {
|
||||
_impacted.insert( o.owner );
|
||||
}
|
||||
|
||||
void operator()( const asset_update_operation& o )const {
|
||||
if( o.new_issuer )
|
||||
|
|
@ -235,18 +232,6 @@ struct operation_get_impacted_accounts
|
|||
_impacted.insert( account_id_type() );
|
||||
}
|
||||
|
||||
void operator()( const bond_create_offer_operation& o )const { }
|
||||
void operator()( const bond_cancel_offer_operation& o )const { }
|
||||
void operator()( const bond_accept_offer_operation& o )const {
|
||||
_impacted.insert( o.borrower );
|
||||
_impacted.insert( o.lender );
|
||||
}
|
||||
void operator()( const bond_claim_collateral_operation& o )const
|
||||
{
|
||||
_impacted.insert( o.lender );
|
||||
_impacted.insert( o.claimer );
|
||||
}
|
||||
|
||||
void operator()( const vesting_balance_create_operation& o )const
|
||||
{
|
||||
_impacted.insert( o.creator );
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
#include <graphene/chain/proposal_object.hpp>
|
||||
#include <graphene/chain/operation_history_object.hpp>
|
||||
#include <graphene/chain/withdraw_permission_object.hpp>
|
||||
#include <graphene/chain/bond_object.hpp>
|
||||
|
||||
using namespace fc;
|
||||
using namespace graphene::chain;
|
||||
|
|
@ -87,10 +86,6 @@ object* create_object( const variant& v )
|
|||
return create_object_of_type< operation_history_object >( v );
|
||||
case withdraw_permission_object_type:
|
||||
return create_object_of_type< withdraw_permission_object >( v );
|
||||
case bond_offer_object_type:
|
||||
return create_object_of_type< bond_offer_object >( v );
|
||||
case bond_object_type:
|
||||
return create_object_of_type< bond_object >( v );
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,7 @@
|
|||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <graphene/chain/operations.hpp>
|
||||
#include <graphene/chain/bond_object.hpp>
|
||||
#include <graphene/chain/vesting_balance_object.hpp>
|
||||
#include <graphene/chain/file_object.hpp>
|
||||
#include <graphene/chain/withdraw_permission_object.hpp>
|
||||
#include <graphene/chain/proposal_object.hpp>
|
||||
#include <graphene/chain/witness_object.hpp>
|
||||
|
|
@ -69,7 +67,7 @@ string remove_namespace( string str )
|
|||
|
||||
template<typename T>
|
||||
void generate_serializer();
|
||||
template<typename T>
|
||||
template<typename T>
|
||||
void register_serializer();
|
||||
|
||||
|
||||
|
|
@ -96,7 +94,7 @@ struct js_name<fc::array<T,N>>
|
|||
};
|
||||
template<size_t N> struct js_name<fc::array<char,N>> { static std::string name(){ return "bytes "+ fc::to_string(N); }; };
|
||||
template<size_t N> struct js_name<fc::array<uint8_t,N>> { static std::string name(){ return "bytes "+ fc::to_string(N); }; };
|
||||
template<typename T> struct js_name< fc::optional<T> > { static std::string name(){ return "optional " + js_name<T>::name(); } };
|
||||
template<typename T> struct js_name< fc::optional<T> > { static std::string name(){ return "optional " + js_name<T>::name(); } };
|
||||
template<> struct js_name< object_id_type > { static std::string name(){ return "object_id_type"; } };
|
||||
template<typename T> struct js_name< fc::flat_set<T> > { static std::string name(){ return "set " + js_name<T>::name(); } };
|
||||
template<typename T> struct js_name< std::vector<T> > { static std::string name(){ return "array " + js_name<T>::name(); } };
|
||||
|
|
@ -115,8 +113,8 @@ template<> struct js_name< time_point_sec > { static std::string name(){ retu
|
|||
template<uint8_t S, uint8_t T, typename O>
|
||||
struct js_name<graphene::db::object_id<S,T,O> >
|
||||
{
|
||||
static std::string name(){
|
||||
return "protocol_id_type \"" + remove_namespace(fc::get_typename<O>::name()) + "\"";
|
||||
static std::string name(){
|
||||
return "protocol_id_type \"" + remove_namespace(fc::get_typename<O>::name()) + "\"";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -132,7 +130,7 @@ struct js_name< fc::flat_map<K,V> > { static std::string name(){ return "map ("
|
|||
|
||||
template<typename... T> struct js_sv_name;
|
||||
|
||||
template<typename A> struct js_sv_name<A>
|
||||
template<typename A> struct js_sv_name<A>
|
||||
{ static std::string name(){ return "\n " + js_name<A>::name(); } };
|
||||
|
||||
template<typename A, typename... T>
|
||||
|
|
@ -142,10 +140,10 @@ struct js_sv_name<A,T...> { static std::string name(){ return "\n " + js_nam
|
|||
template<typename... T>
|
||||
struct js_name< fc::static_variant<T...> >
|
||||
{
|
||||
static std::string name( std::string n = ""){
|
||||
static std::string name( std::string n = ""){
|
||||
static const std::string name = n;
|
||||
if( name == "" )
|
||||
return "static_variant [" + js_sv_name<T...>::name() + "\n]";
|
||||
return "static_variant [" + js_sv_name<T...>::name() + "\n]";
|
||||
else return name;
|
||||
}
|
||||
};
|
||||
|
|
@ -290,7 +288,7 @@ class register_member_visitor
|
|||
}
|
||||
};
|
||||
|
||||
template<typename T, bool reflected>
|
||||
template<typename T, bool reflected>
|
||||
struct serializer
|
||||
{
|
||||
static_assert( fc::reflector<T>::is_defined::value == reflected, "invalid template arguments" );
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@ file(GLOB COMMON_SOURCES "common/*.cpp")
|
|||
|
||||
file(GLOB UNIT_TESTS "tests/*.cpp")
|
||||
add_executable( chain_test ${UNIT_TESTS} ${COMMON_SOURCES} )
|
||||
target_link_libraries( chain_test graphene_chain graphene_app graphene_account_history fc z)
|
||||
target_link_libraries( chain_test graphene_chain graphene_app graphene_account_history fc )
|
||||
|
||||
file(GLOB PERFORMANCE_TESTS "performance/*.cpp")
|
||||
add_executable( performance_test ${PERFORMANCE_TESTS} ${COMMON_SOURCES} )
|
||||
target_link_libraries( performance_test graphene_chain graphene_app graphene_account_history fc z)
|
||||
target_link_libraries( performance_test graphene_chain graphene_app graphene_account_history fc )
|
||||
|
||||
file(GLOB BENCH_MARKS "benchmarks/*.cpp")
|
||||
add_executable( chain_bench ${BENCH_MARKS} ${COMMON_SOURCES} )
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
#include <graphene/chain/account_object.hpp>
|
||||
#include <graphene/chain/asset_object.hpp>
|
||||
#include <graphene/chain/bond_object.hpp>
|
||||
#include <graphene/chain/delegate_object.hpp>
|
||||
#include <graphene/chain/limit_order_object.hpp>
|
||||
#include <graphene/chain/short_order_object.hpp>
|
||||
|
|
@ -151,12 +150,6 @@ void database_fixture::verify_asset_supplies( )const
|
|||
{
|
||||
total_balances[asset_id_type()] += witness_obj.accumulated_income;
|
||||
}
|
||||
for( const bond_offer_object& bond_offer : db.get_index_type<bond_offer_index>().indices() )
|
||||
{
|
||||
total_balances[ bond_offer.amount.asset_id ] += bond_offer.amount.amount;
|
||||
if( bond_offer.amount.asset_id == asset_id_type() )
|
||||
core_in_orders += bond_offer.amount.amount;
|
||||
}
|
||||
for( const vesting_balance_object& vbo : db.get_index_type< simple_index<vesting_balance_object> >() )
|
||||
total_balances[ vbo.balance.asset_id ] += vbo.balance.amount;
|
||||
|
||||
|
|
|
|||
|
|
@ -2080,7 +2080,6 @@ BOOST_AUTO_TEST_CASE( margin_call_black_swan )
|
|||
* 2) Short Orders for BitAsset backed by BitUSD
|
||||
* 3) Call Orders for BitAsset backed by BitUSD
|
||||
* 4) Issuer Fees
|
||||
* 5) Bond Market Collateral
|
||||
*
|
||||
* This test should fail until the black swan handling code can
|
||||
* perform a recursive blackswan for any other BitAssets that use
|
||||
|
|
@ -2138,69 +2137,6 @@ BOOST_AUTO_TEST_CASE( unimp_transfer_cashback_test )
|
|||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( bond_create_offer_test )
|
||||
{ try {
|
||||
bond_create_offer_operation op;
|
||||
op.fee = asset( 0, 0 );
|
||||
op.creator = account_id_type();
|
||||
op.amount = asset( 1, 0 );
|
||||
op.collateral_rate = price( asset( 1, 0 ), asset( 1, 1 ) );
|
||||
op.min_loan_period_sec = 1;
|
||||
op.loan_period_sec = 1;
|
||||
|
||||
// Fee must be non-negative
|
||||
REQUIRE_OP_VALIDATION_SUCCESS( op, fee, asset( 1, 0 ) );
|
||||
REQUIRE_OP_VALIDATION_SUCCESS( op, fee, asset( 0, 0 ) );
|
||||
REQUIRE_OP_VALIDATION_FAILURE( op, fee, asset( -1, 0 ) );
|
||||
|
||||
// Amount must be positive
|
||||
REQUIRE_OP_VALIDATION_SUCCESS( op, amount, asset( 1, 0 ) );
|
||||
REQUIRE_OP_VALIDATION_FAILURE( op, amount, asset( 0, 0 ) );
|
||||
REQUIRE_OP_VALIDATION_FAILURE( op, amount, asset( -1, 0 ) );
|
||||
|
||||
// Collateral rate must be valid
|
||||
REQUIRE_OP_VALIDATION_SUCCESS( op, collateral_rate, price( asset( 1, 0 ), asset( 1, 1 ) ) );
|
||||
REQUIRE_OP_VALIDATION_FAILURE( op, collateral_rate, price( asset( 0, 0 ), asset( 1, 1 ) ) );
|
||||
REQUIRE_OP_VALIDATION_FAILURE( op, collateral_rate, price( asset( 1, 0 ), asset( 0, 1 ) ) );
|
||||
REQUIRE_OP_VALIDATION_FAILURE( op, collateral_rate, price( asset( 1, 0 ), asset( 1, 0 ) ) );
|
||||
|
||||
// Min loan period must be at least 1 sec
|
||||
REQUIRE_OP_VALIDATION_SUCCESS( op, min_loan_period_sec, 1 );
|
||||
REQUIRE_OP_VALIDATION_FAILURE( op, min_loan_period_sec, 0 );
|
||||
|
||||
// Loan period must be greater than min load period
|
||||
REQUIRE_OP_VALIDATION_SUCCESS( op, loan_period_sec, op.min_loan_period_sec + 1 );
|
||||
REQUIRE_OP_VALIDATION_FAILURE( op, loan_period_sec, 0 );
|
||||
|
||||
// Interest APR cannot be greater than max
|
||||
REQUIRE_OP_VALIDATION_FAILURE( op, interest_apr, GRAPHENE_MAX_INTEREST_APR + 1 );
|
||||
REQUIRE_OP_VALIDATION_SUCCESS( op, interest_apr, GRAPHENE_MAX_INTEREST_APR );
|
||||
REQUIRE_OP_VALIDATION_SUCCESS( op, interest_apr, 0 );
|
||||
|
||||
// Setup world state we will need to test actual evaluation
|
||||
INVOKE( create_uia );
|
||||
const auto& test_asset = get_asset( "TEST" );
|
||||
const auto& nathan_account = create_account( "nathan" );
|
||||
transfer( account_id_type()( db ), nathan_account, asset( 1, 0 ) );
|
||||
|
||||
op.creator = nathan_account.get_id();
|
||||
op.collateral_rate.quote.asset_id = test_asset.get_id();
|
||||
trx.operations.emplace_back( op );
|
||||
|
||||
// Insufficient funds in creator account
|
||||
REQUIRE_THROW_WITH_VALUE( op, creator, account_id_type( 1 ) );
|
||||
|
||||
// Insufficient principle
|
||||
REQUIRE_THROW_WITH_VALUE( op, amount, asset( 2, 0 ) );
|
||||
|
||||
// Insufficient collateral
|
||||
op.offer_to_borrow = true;
|
||||
REQUIRE_THROW_WITH_VALUE( op, amount, asset( 1, test_asset.get_id() ) );
|
||||
|
||||
// This op should be fully valid
|
||||
REQUIRE_OP_EVALUATION_SUCCESS( op, offer_to_borrow, false );
|
||||
} FC_LOG_AND_RETHROW() }
|
||||
|
||||
BOOST_AUTO_TEST_CASE( vesting_balance_create_test )
|
||||
{ try {
|
||||
INVOKE( create_uia );
|
||||
|
|
|
|||
Loading…
Reference in a new issue