Merge branch 'github_master'

Conflicts:
	libraries/fc
This commit is contained in:
Eric Frias 2015-06-15 16:05:42 -04:00
commit 39cd21c11e
36 changed files with 83 additions and 1057 deletions

6
.gitignore vendored
View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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> >();

View file

@ -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 )

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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) )

View file

@ -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))
///@}

View file

@ -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(); }
};
} }

View file

@ -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
{

View file

@ -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) )

View file

@ -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

View file

@ -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) )

View file

@ -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;
};

View file

@ -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) )

View file

@ -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 )

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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 )

View file

@ -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();

View file

@ -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 );

View file

@ -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

View file

@ -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 );

View file

@ -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:
;
}

View file

@ -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" );

View file

@ -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} )

View file

@ -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;

View file

@ -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 );