Merge branch 'master' of github.com:cryptonomex/graphene
This commit is contained in:
commit
21bd520f9c
37 changed files with 1085 additions and 71 deletions
|
|
@ -17,10 +17,8 @@
|
|||
*/
|
||||
#include <graphene/app/api.hpp>
|
||||
#include <graphene/app/application.hpp>
|
||||
#include <graphene/chain/asset_object.hpp>
|
||||
#include <graphene/chain/database.hpp>
|
||||
#include <graphene/utilities/key_conversion.hpp>
|
||||
#include <graphene/chain/operation_history_object.hpp>
|
||||
|
||||
#include <fc/crypto/hex.hpp>
|
||||
|
||||
|
|
@ -167,7 +165,7 @@ namespace graphene { namespace app {
|
|||
else
|
||||
{
|
||||
result.reserve(assets.size());
|
||||
|
||||
|
||||
std::transform(assets.begin(), assets.end(), std::back_inserter(result),
|
||||
[this, acnt](asset_id_type id) { return _db.get_balance(acnt, id); });
|
||||
}
|
||||
|
|
@ -242,7 +240,7 @@ namespace graphene { namespace app {
|
|||
|
||||
auto itr = assets_by_symbol.lower_bound(lower_bound_symbol);
|
||||
|
||||
if( lower_bound_symbol == "" )
|
||||
if( lower_bound_symbol == "" )
|
||||
itr = assets_by_symbol.begin();
|
||||
|
||||
while(limit-- && itr != assets_by_symbol.end())
|
||||
|
|
@ -251,6 +249,24 @@ namespace graphene { namespace app {
|
|||
return result;
|
||||
}
|
||||
|
||||
fc::optional<delegate_object> database_api::get_delegate_by_account(account_id_type account) const
|
||||
{
|
||||
const auto& idx = _db.get_index_type<delegate_index>().indices().get<by_account>();
|
||||
auto itr = idx.find(account);
|
||||
if( itr != idx.end() )
|
||||
return *itr;
|
||||
return {};
|
||||
}
|
||||
|
||||
fc::optional<witness_object> database_api::get_witness_by_account(account_id_type account) const
|
||||
{
|
||||
const auto& idx = _db.get_index_type<witness_index>().indices().get<by_account>();
|
||||
auto itr = idx.find(account);
|
||||
if( itr != idx.end() )
|
||||
return *itr;
|
||||
return {};
|
||||
}
|
||||
|
||||
login_api::login_api(application& a)
|
||||
:_app(a)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -153,14 +153,14 @@ namespace detail {
|
|||
secret_hash_type::encoder enc;
|
||||
fc::raw::pack(enc, nathan_key);
|
||||
fc::raw::pack(enc, secret_hash_type());
|
||||
auto secret = secret_hash_type::hash(enc.result());
|
||||
for( int i = 0; i < 10; ++i )
|
||||
{
|
||||
initial_state.allocation_targets.emplace_back("init"+fc::to_string(i), nathan_key.get_public_key(), 0, true);
|
||||
initial_state.initial_committee.push_back({"init"+fc::to_string(i)});
|
||||
auto name = "init"+fc::to_string(i);
|
||||
initial_state.allocation_targets.emplace_back(name, nathan_key.get_public_key(), 0, true);
|
||||
initial_state.initial_committee.push_back({name});
|
||||
initial_state.initial_witnesses.push_back({name, nathan_key.get_public_key(), secret});
|
||||
}
|
||||
initial_state.initial_witnesses = vector<genesis_state_type::initial_witness_type>(10, {"committee-account",
|
||||
nathan_key.get_public_key(),
|
||||
secret_hash_type::hash(enc.result())});
|
||||
|
||||
initial_state.allocation_targets.emplace_back("nathan", address(public_key_type(nathan_key.get_public_key())), 1);
|
||||
if( _options->count("genesis-json") )
|
||||
|
|
|
|||
|
|
@ -24,7 +24,10 @@
|
|||
#include <graphene/chain/limit_order_object.hpp>
|
||||
#include <graphene/chain/call_order_object.hpp>
|
||||
#include <graphene/chain/key_object.hpp>
|
||||
#include <graphene/chain/delegate_object.hpp>
|
||||
#include <graphene/chain/witness_object.hpp>
|
||||
#include <graphene/net/node.hpp>
|
||||
|
||||
#include <fc/api.hpp>
|
||||
|
||||
namespace graphene { namespace app {
|
||||
|
|
@ -165,6 +168,19 @@ namespace graphene { namespace app {
|
|||
*/
|
||||
vector<asset_object> list_assets(const string& lower_bound_symbol, uint32_t limit)const;
|
||||
|
||||
/**
|
||||
* @brief Get the delegate owned by a given account
|
||||
* @param account The ID of the account whose delegate should be retrieved
|
||||
* @return The delegate object, or null if the account does not have a delegate
|
||||
*/
|
||||
fc::optional<delegate_object> get_delegate_by_account(account_id_type account)const;
|
||||
/**
|
||||
* @brief Get the witness owned by a given account
|
||||
* @param account The ID of the account whose witness should be retrieved
|
||||
* @return The witness object, or null if the account does not have a witness
|
||||
*/
|
||||
fc::optional<witness_object> get_witness_by_account(account_id_type account)const;
|
||||
|
||||
/**
|
||||
* @group Push Notification Methods
|
||||
* These methods may be used to get push notifications whenever an object or market is changed
|
||||
|
|
@ -338,6 +354,8 @@ FC_API(graphene::app::database_api,
|
|||
(get_call_orders)
|
||||
(get_settle_orders)
|
||||
(list_assets)
|
||||
(get_delegate_by_account)
|
||||
(get_witness_by_account)
|
||||
(subscribe_to_objects)
|
||||
(unsubscribe_from_objects)
|
||||
(subscribe_to_market)
|
||||
|
|
|
|||
|
|
@ -1,16 +1,42 @@
|
|||
file(GLOB HEADERS "include/graphene/chain/*.hpp")
|
||||
|
||||
add_executable( field_reflector
|
||||
field_reflector.cpp
|
||||
types.cpp
|
||||
type_id.cpp
|
||||
address.cpp
|
||||
key_object.cpp
|
||||
${HEADERS} )
|
||||
|
||||
target_include_directories( field_reflector
|
||||
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )
|
||||
|
||||
target_link_libraries( field_reflector fc graphene_db )
|
||||
|
||||
add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/db_reflect_cmp.cpp
|
||||
COMMAND field_reflector ${CMAKE_CURRENT_SOURCE_DIR}/db_reflect_cmp.tmpl ${CMAKE_CURRENT_BINARY_DIR}/db_reflect_cmp.cpp.new
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/db_reflect_cmp.cpp.new ${CMAKE_CURRENT_BINARY_DIR}/db_reflect_cmp.cpp
|
||||
COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_BINARY_DIR}/db_reflect_cmp.cpp.new
|
||||
DEPENDS field_reflector db_reflect_cmp.tmpl
|
||||
)
|
||||
|
||||
## SORT .cpp by most likely to change / break compile
|
||||
add_library( graphene_chain
|
||||
types.cpp
|
||||
type_id.cpp
|
||||
|
||||
${CMAKE_CURRENT_BINARY_DIR}/db_reflect_cmp.cpp
|
||||
|
||||
address.cpp
|
||||
asset.cpp
|
||||
predicate.cpp
|
||||
|
||||
operations.cpp
|
||||
|
||||
evaluator.cpp
|
||||
global_parameters_evaluator.cpp
|
||||
account_evaluator.cpp
|
||||
assert_evaluator.cpp
|
||||
witness_evaluator.cpp
|
||||
delegate_evaluator.cpp
|
||||
asset_evaluator.cpp
|
||||
|
|
|
|||
92
libraries/chain/assert_evaluator.cpp
Normal file
92
libraries/chain/assert_evaluator.cpp
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* 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/assert_evaluator.hpp>
|
||||
#include <graphene/chain/database.hpp>
|
||||
#include <graphene/chain/predicate.hpp>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct predicate_check_visitor
|
||||
{
|
||||
predicate_check_visitor( const database& d ): _db(d){}
|
||||
|
||||
typedef bool result_type;
|
||||
template<typename Predicate> bool operator()( const Predicate& pred )const
|
||||
{
|
||||
return pred.check_predicate( _db );
|
||||
}
|
||||
|
||||
const database& _db;
|
||||
};
|
||||
|
||||
} // graphene::chain::detail
|
||||
|
||||
void_result assert_evaluator::do_evaluate( const assert_operation& o )
|
||||
{
|
||||
const database& _db = db();
|
||||
uint32_t skip = _db.get_node_properties().skip_flags;
|
||||
// TODO: Skip flags
|
||||
if( skip & database::skip_assert_evaluation )
|
||||
return void_result();
|
||||
for( const vector<char>& s_pred : o.predicates )
|
||||
{
|
||||
std::istringstream is( string( s_pred.begin(), s_pred.end() ) );
|
||||
// de-serialize just the static_variant tag
|
||||
unsigned_int t;
|
||||
fc::raw::unpack( is, t );
|
||||
// everyone checks: delegates must have allocated an opcode for it
|
||||
FC_ASSERT( t.value < _db.get_global_properties().parameters.max_predicate_opcode );
|
||||
if( t.value >= predicate::count() )
|
||||
{
|
||||
//
|
||||
// delegates allocated an opcode, but our client doesn't know
|
||||
// the semantics (i.e. we are running an old client)
|
||||
//
|
||||
// skip_unknown_predicate indicates we're cool with assuming
|
||||
// unknown predicates pass
|
||||
//
|
||||
if( skip & database::skip_unknown_predicate )
|
||||
continue;
|
||||
//
|
||||
// ok, unknown predicate must die
|
||||
//
|
||||
FC_ASSERT( false, "unknown predicate" );
|
||||
}
|
||||
// rewind to beginning, unpack it, and check it
|
||||
is.clear();
|
||||
is.seekg(0);
|
||||
predicate pred;
|
||||
fc::raw::unpack( is, pred );
|
||||
bool pred_passed = pred.visit( detail::predicate_check_visitor( _db ) );
|
||||
FC_ASSERT( pred_passed );
|
||||
}
|
||||
return void_result();
|
||||
}
|
||||
|
||||
void_result assert_evaluator::do_apply( const assert_operation& o )
|
||||
{
|
||||
// assert_operation is always a no-op
|
||||
return void_result();
|
||||
}
|
||||
|
||||
} } // graphene::chain
|
||||
|
|
@ -80,7 +80,7 @@ const signed_transaction& database::get_recent_transaction(const transaction_id_
|
|||
*
|
||||
* @return true if we switched forks as a result of this push.
|
||||
*/
|
||||
bool database::push_block( const signed_block& new_block, uint32_t skip )
|
||||
bool database::push_block(const signed_block& new_block, uint32_t skip)
|
||||
{
|
||||
bool result;
|
||||
with_skip_flags( skip, [&]()
|
||||
|
|
@ -90,29 +90,20 @@ bool database::push_block( const signed_block& new_block, uint32_t skip )
|
|||
return result;
|
||||
}
|
||||
|
||||
bool database::_push_block( const signed_block& new_block )
|
||||
bool database::_push_block(const signed_block& new_block)
|
||||
{ try {
|
||||
uint32_t skip = get_node_properties().skip_flags;
|
||||
if( !(skip&skip_fork_db) )
|
||||
{
|
||||
auto new_head = _fork_db.push_block( new_block );
|
||||
auto new_head = _fork_db.push_block(new_block);
|
||||
//If the head block from the longest chain does not build off of the current head, we need to switch forks.
|
||||
if( new_head->data.previous != head_block_id() )
|
||||
{
|
||||
//edump((new_head->data.previous));
|
||||
//If the newly pushed block is the same height as head, we get head back in new_head
|
||||
//Only switch forks if new_head is actually higher than head
|
||||
if( new_head->data.block_num() > head_block_num() )
|
||||
{
|
||||
auto branches = _fork_db.fetch_branch_from( new_head->data.id(), _pending_block.previous );
|
||||
for( auto item : branches.first )
|
||||
{
|
||||
// wdump( ("new")(item->id)(item->data.previous) );
|
||||
}
|
||||
for( auto item : branches.second )
|
||||
{
|
||||
// wdump( ("old")(item->id)(item->data.previous) );
|
||||
}
|
||||
auto branches = _fork_db.fetch_branch_from(new_head->data.id(), _pending_block.previous);
|
||||
|
||||
// pop blocks until we hit the forked block
|
||||
while( head_block_id() != branches.second.back()->data.previous )
|
||||
|
|
@ -131,9 +122,6 @@ bool database::_push_block( const signed_block& new_block )
|
|||
catch ( const fc::exception& e ) { except = e; }
|
||||
if( except )
|
||||
{
|
||||
//wdump((except->to_detail_string()));
|
||||
// elog( "Encountered error when switching to a longer fork at id ${id}. Going back.",
|
||||
// ("id", (*ritr)->id) );
|
||||
// remove the rest of branches.first from the fork_db, those blocks are invalid
|
||||
while( ritr != branches.first.rend() )
|
||||
{
|
||||
|
|
@ -170,8 +158,8 @@ bool database::_push_block( const signed_block& new_block )
|
|||
|
||||
try {
|
||||
auto session = _undo_db.start_undo_session();
|
||||
apply_block( new_block, skip );
|
||||
_block_id_to_block.store( new_block.id(), new_block );
|
||||
apply_block(new_block, skip);
|
||||
_block_id_to_block.store(new_block.id(), new_block);
|
||||
session.commit();
|
||||
} catch ( const fc::exception& e ) {
|
||||
elog("Failed to push new block:\n${e}", ("e", e.to_detail_string()));
|
||||
|
|
@ -204,7 +192,6 @@ processed_transaction database::push_transaction( const signed_transaction& trx,
|
|||
processed_transaction database::_push_transaction( const signed_transaction& trx )
|
||||
{
|
||||
uint32_t skip = get_node_properties().skip_flags;
|
||||
//wdump((trx.digest())(trx.id()));
|
||||
// If this is the first transaction pushed after applying a block, start a new undo session.
|
||||
// This allows us to quickly rewind to the clean state of the head block, in case a new block arrives.
|
||||
if( !_pending_block_session ) _pending_block_session = _undo_db.start_undo_session();
|
||||
|
|
@ -239,9 +226,6 @@ processed_transaction database::push_proposal(const proposal_object& proposal)
|
|||
return std::make_pair(id, authority::owner);
|
||||
});
|
||||
|
||||
//ilog("Attempting to push proposal ${prop}", ("prop", proposal));
|
||||
//idump((eval_state.approved_by));
|
||||
|
||||
eval_state.operation_results.reserve(proposal.proposed_transaction.operations.size());
|
||||
processed_transaction ptrx(proposal.proposed_transaction);
|
||||
eval_state._trx = &ptrx;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include <graphene/chain/account_evaluator.hpp>
|
||||
#include <graphene/chain/asset_evaluator.hpp>
|
||||
#include <graphene/chain/assert_evaluator.hpp>
|
||||
#include <graphene/chain/custom_evaluator.hpp>
|
||||
#include <graphene/chain/delegate_evaluator.hpp>
|
||||
#include <graphene/chain/global_parameters_evaluator.hpp>
|
||||
|
|
@ -73,6 +74,7 @@ void database::initialize_evaluators()
|
|||
register_evaluator<asset_update_feed_producers_evaluator>();
|
||||
register_evaluator<asset_settle_evaluator>();
|
||||
register_evaluator<asset_global_settle_evaluator>();
|
||||
register_evaluator<assert_evaluator>();
|
||||
register_evaluator<limit_order_create_evaluator>();
|
||||
register_evaluator<limit_order_cancel_evaluator>();
|
||||
register_evaluator<call_order_update_evaluator>();
|
||||
|
|
@ -103,8 +105,8 @@ void database::initialize_indexes()
|
|||
add_index< primary_index<force_settlement_index> >();
|
||||
add_index< primary_index<account_index> >();
|
||||
add_index< primary_index<simple_index<key_object>> >();
|
||||
add_index< primary_index<simple_index<delegate_object>> >();
|
||||
add_index< primary_index<simple_index<witness_object>> >();
|
||||
add_index< primary_index<delegate_index> >();
|
||||
add_index< primary_index<witness_index> >();
|
||||
add_index< primary_index<limit_order_index > >();
|
||||
add_index< primary_index<call_order_index > >();
|
||||
add_index< primary_index<proposal_index > >();
|
||||
|
|
@ -116,12 +118,12 @@ void database::initialize_indexes()
|
|||
add_index< primary_index<transaction_index > >();
|
||||
add_index< primary_index<account_balance_index > >();
|
||||
add_index< primary_index<asset_bitasset_data_index > >();
|
||||
add_index< primary_index<simple_index< global_property_object >> >();
|
||||
add_index< primary_index<simple_index< dynamic_global_property_object >> >();
|
||||
add_index< primary_index<simple_index< account_statistics_object >> >();
|
||||
add_index< primary_index<simple_index< asset_dynamic_data_object >> >();
|
||||
add_index< primary_index<flat_index< block_summary_object >> >();
|
||||
add_index< primary_index< simple_index< witness_schedule_object > > >();
|
||||
add_index< primary_index<simple_index<global_property_object >> >();
|
||||
add_index< primary_index<simple_index<dynamic_global_property_object >> >();
|
||||
add_index< primary_index<simple_index<account_statistics_object >> >();
|
||||
add_index< primary_index<simple_index<asset_dynamic_data_object >> >();
|
||||
add_index< primary_index<flat_index< block_summary_object >> >();
|
||||
add_index< primary_index<simple_index<witness_schedule_object >> >();
|
||||
}
|
||||
|
||||
void database::init_genesis(const genesis_state_type& genesis_state)
|
||||
|
|
@ -354,6 +356,6 @@ void database::init_genesis(const genesis_state_type& genesis_state)
|
|||
assert( wso.id == witness_schedule_id_type() );
|
||||
|
||||
_undo_db.enable();
|
||||
} FC_LOG_AND_RETHROW() }
|
||||
} FC_CAPTURE_AND_RETHROW((genesis_state)) }
|
||||
|
||||
} }
|
||||
|
|
|
|||
|
|
@ -31,18 +31,19 @@
|
|||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
template<class ObjectType>
|
||||
vector<std::reference_wrapper<const ObjectType>> database::sort_votable_objects(size_t count) const
|
||||
template<class Index>
|
||||
vector<std::reference_wrapper<const typename Index::object_type>> database::sort_votable_objects(size_t count) const
|
||||
{
|
||||
const auto& all_objects = dynamic_cast<const simple_index<ObjectType>&>(get_index<ObjectType>());
|
||||
using ObjectType = typename Index::object_type;
|
||||
const auto& all_objects = get_index_type<Index>().indices();
|
||||
count = std::min(count, all_objects.size());
|
||||
vector<std::reference_wrapper<const ObjectType>> refs;
|
||||
refs.reserve(all_objects.size());
|
||||
std::transform(all_objects.begin(), all_objects.end(),
|
||||
std::back_inserter(refs),
|
||||
[](const ObjectType& o) { return std::cref(o); });
|
||||
std::partial_sort( refs.begin(), refs.begin() + count, refs.end(),
|
||||
[this]( const ObjectType& a, const ObjectType& b )->bool {
|
||||
std::partial_sort(refs.begin(), refs.begin() + count, refs.end(),
|
||||
[this](const ObjectType& a, const ObjectType& b)->bool {
|
||||
return _vote_tally_buffer[a.vote_id] > _vote_tally_buffer[b.vote_id];
|
||||
});
|
||||
|
||||
|
|
@ -105,7 +106,7 @@ void database::update_active_witnesses()
|
|||
&& (stake_tally <= stake_target) )
|
||||
stake_tally += _witness_count_histogram_buffer[++witness_count];
|
||||
|
||||
auto wits = sort_votable_objects<witness_object>(std::max(witness_count*2+1, GRAPHENE_MIN_WITNESS_COUNT));
|
||||
auto wits = sort_votable_objects<witness_index>(std::max(witness_count*2+1, GRAPHENE_MIN_WITNESS_COUNT));
|
||||
const global_property_object& gpo = get_global_properties();
|
||||
|
||||
// Update witness authority
|
||||
|
|
@ -171,12 +172,12 @@ void database::update_active_delegates()
|
|||
&& (stake_tally <= stake_target) )
|
||||
stake_tally += _committee_count_histogram_buffer[++delegate_count];
|
||||
|
||||
auto delegates = sort_votable_objects<delegate_object>(std::max(delegate_count*2+1, GRAPHENE_MIN_DELEGATE_COUNT));
|
||||
auto delegates = sort_votable_objects<delegate_index>(std::max(delegate_count*2+1, GRAPHENE_MIN_DELEGATE_COUNT));
|
||||
|
||||
// Update genesis authorities
|
||||
if( !delegates.empty() )
|
||||
{
|
||||
modify( get(GRAPHENE_COMMITTEE_ACCOUNT), [&]( account_object& a ) {
|
||||
modify(get(GRAPHENE_COMMITTEE_ACCOUNT), [&](account_object& a) {
|
||||
uint64_t total_votes = 0;
|
||||
map<account_id_type, uint64_t> weights;
|
||||
a.active.weight_threshold = 0;
|
||||
|
|
@ -202,11 +203,11 @@ void database::update_active_delegates()
|
|||
a.active.weight_threshold /= 2;
|
||||
a.active.weight_threshold += 1;
|
||||
});
|
||||
modify( get(GRAPHENE_RELAXED_COMMITTEE_ACCOUNT), [&](account_object& a) {
|
||||
modify(get(GRAPHENE_RELAXED_COMMITTEE_ACCOUNT), [&](account_object& a) {
|
||||
a.active = get(GRAPHENE_COMMITTEE_ACCOUNT).active;
|
||||
});
|
||||
}
|
||||
modify( get_global_properties(), [&]( global_property_object& gp ) {
|
||||
modify(get_global_properties(), [&](global_property_object& gp) {
|
||||
gp.active_delegates.clear();
|
||||
std::transform(delegates.begin(), delegates.end(),
|
||||
std::inserter(gp.active_delegates, gp.active_delegates.begin()),
|
||||
|
|
|
|||
43
libraries/chain/db_reflect_cmp.tmpl
Normal file
43
libraries/chain/db_reflect_cmp.tmpl
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
${generated_file_banner}
|
||||
|
||||
/*
|
||||
object_descriptor = ${object_descriptor}
|
||||
*/
|
||||
|
||||
#include <graphene/chain/db_reflect_cmp.hpp>
|
||||
#include <graphene/chain/db_reflect_cmp_impl.hpp>
|
||||
#include <graphene/chain/wild_object.hpp>
|
||||
|
||||
#include <graphene/db/object_database.hpp>
|
||||
|
||||
namespace graphene { namespace chain { namespace impl {
|
||||
|
||||
bool cmp_attr_impl(
|
||||
const object& obj,
|
||||
uint16_t field_num,
|
||||
const vector<char>& lit,
|
||||
uint8_t opc
|
||||
)
|
||||
{
|
||||
${cmp_attr_impl_body}
|
||||
}
|
||||
|
||||
} } } // graphene::chain::detail
|
||||
239
libraries/chain/field_reflector.cpp
Normal file
239
libraries/chain/field_reflector.cpp
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
* 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 <fc/io/json.hpp>
|
||||
#include <fc/variant.hpp>
|
||||
#include <fc/variant_object.hpp>
|
||||
|
||||
#include <graphene/chain/wild_object.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace graphene::chain;
|
||||
|
||||
fc::mutable_variant_object g_vo_object_types;
|
||||
std::vector< fc::mutable_variant_object > g_vo_fields;
|
||||
|
||||
struct serialize_object_type_member_visitor
|
||||
{
|
||||
public:
|
||||
template<typename Member, class Class, Member (Class::*member)>
|
||||
void operator()( const char* name )const
|
||||
{
|
||||
fc::mutable_variant_object vo;
|
||||
vo["name"] = name;
|
||||
vo["type"] = fc::get_typename<Member>::name();
|
||||
vo["id"] = g_vo_fields.size();
|
||||
g_vo_fields.push_back( vo );
|
||||
}
|
||||
};
|
||||
|
||||
struct serialize_object_type_visitor
|
||||
{
|
||||
typedef void result_type;
|
||||
|
||||
int t = 0;
|
||||
serialize_object_type_visitor(int _t ):t(_t){}
|
||||
|
||||
template<typename Type>
|
||||
result_type operator()( const Type& op )const
|
||||
{
|
||||
fc::mutable_variant_object vo;
|
||||
vo["space_id"] = Type::space_id;
|
||||
vo["type_id"] = Type::type_id;
|
||||
g_vo_fields.clear();
|
||||
// visit all members
|
||||
fc::reflector<Type>::visit( serialize_object_type_member_visitor() );
|
||||
|
||||
vo["fields"] = g_vo_fields;
|
||||
g_vo_object_types[ fc::get_typename<Type>::name() ] = vo;
|
||||
}
|
||||
};
|
||||
|
||||
struct getattr_switch_table_entry
|
||||
{
|
||||
uint32_t _switch_val; // (space << 24) | (type << 16) | fieldnum
|
||||
string _object_typename;
|
||||
string _field_typename;
|
||||
string _field_name;
|
||||
};
|
||||
|
||||
vector< getattr_switch_table_entry > build_switch_table()
|
||||
{
|
||||
vector< getattr_switch_table_entry > result;
|
||||
for( const auto& item : g_vo_object_types )
|
||||
{
|
||||
const variant_object& vo = item.value().get_object();
|
||||
uint32_t top = (vo["space_id"].as_uint64() << 24) | (vo["type_id"].as_uint64() << 16);
|
||||
for( const auto& field : vo["fields"].get_array() )
|
||||
{
|
||||
getattr_switch_table_entry e;
|
||||
e._switch_val = top | field["id"].as_uint64();
|
||||
e._object_typename = item.key();
|
||||
e._field_typename = field["type"].get_string();
|
||||
e._field_name = field["name"].get_string();
|
||||
result.push_back( e );
|
||||
}
|
||||
}
|
||||
|
||||
std::sort( result.begin(), result.end(),
|
||||
[]( const getattr_switch_table_entry& a,
|
||||
const getattr_switch_table_entry& b )
|
||||
{
|
||||
return a._switch_val < b._switch_val;
|
||||
} );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string generate_cmp_attr_impl( const vector< getattr_switch_table_entry >& switch_table )
|
||||
{
|
||||
std::ostringstream out;
|
||||
|
||||
// switch( space )
|
||||
// switch( type )
|
||||
// switch( fieldnum )
|
||||
// switch( opc )
|
||||
|
||||
std::map< uint8_t,
|
||||
std::map< uint8_t,
|
||||
std::map< uint16_t,
|
||||
const getattr_switch_table_entry* > > > index;
|
||||
|
||||
for( const getattr_switch_table_entry& e : switch_table )
|
||||
{
|
||||
uint8_t sp = (e._switch_val >> 24) & 0xFF;
|
||||
uint8_t ty = (e._switch_val >> 16) & 0xFF;
|
||||
uint16_t fn = (e._switch_val ) & 0xFFFF;
|
||||
auto& i0 = index;
|
||||
if( i0.find( sp ) == i0.end() )
|
||||
i0[sp] = std::map< uint8_t, std::map< uint16_t, const getattr_switch_table_entry* > >();
|
||||
auto& i1 = i0[sp];
|
||||
if( i1.find( ty ) == i1.end() )
|
||||
i1[ty] = std::map< uint16_t, const getattr_switch_table_entry* >();
|
||||
auto& i2 = i1[ty];
|
||||
i2[fn] = &e;
|
||||
}
|
||||
out << " switch( obj.id.space() )\n"
|
||||
" {\n";
|
||||
for( const auto& e0 : index )
|
||||
{
|
||||
out << " case " << int( e0.first ) << ":\n"
|
||||
" switch( obj.id.type() )\n"
|
||||
" {\n";
|
||||
for( const auto& e1 : e0.second )
|
||||
{
|
||||
out << " case " << int( e1.first ) << ":\n"
|
||||
" switch( field_num )\n"
|
||||
" {\n";
|
||||
for( const auto& e2 : e1.second )
|
||||
{
|
||||
const std::string& ft = e2.second->_field_typename;
|
||||
const std::string& ot = e2.second->_object_typename;
|
||||
const std::string& fn = e2.second->_field_name;
|
||||
out << " case " << int( e2.first ) << ":\n"
|
||||
" {\n"
|
||||
" // " << ft
|
||||
<< " " << ot
|
||||
<< "." << fn
|
||||
<< "\n"
|
||||
" const " << ft << "& dbval = object_database::cast< " << ot << " >( obj )." << fn << ";\n"
|
||||
" return _cmp< " << ft << " >( dbval, lit, opc );\n"
|
||||
" }\n";
|
||||
}
|
||||
out << " default:\n"
|
||||
" FC_ASSERT( false, \"unrecognized field_num\" );\n"
|
||||
" }\n";
|
||||
}
|
||||
out << " default:\n"
|
||||
" FC_ASSERT( false, \"unrecognized object type\" );\n"
|
||||
" }\n";
|
||||
}
|
||||
out << " default:\n"
|
||||
" FC_ASSERT( false, \"unrecognized object space\" );\n"
|
||||
" }\n";
|
||||
|
||||
return out.str();
|
||||
}
|
||||
|
||||
static const char generated_file_banner[] =
|
||||
"// _ _ __ _ _ //\n"
|
||||
"// | | | | / _(_) | //\n"
|
||||
"// __ _ ___ _ __ ___ _ __ __ _| |_ ___ __| | | |_ _| | ___ //\n"
|
||||
"// / _` |/ _ \\ '_ \\ / _ \\ '__/ _` | __/ _ \\/ _` | | _| | |/ _ \\ //\n"
|
||||
"// | (_| | __/ | | | __/ | | (_| | || __/ (_| | | | | | | __/ //\n"
|
||||
"// \\__, |\\___|_| |_|\\___|_| \\__,_|\\__\\___|\\__,_| |_| |_|_|\\___| //\n"
|
||||
"// __/ | //\n"
|
||||
"// |___/ //\n"
|
||||
"// //\n"
|
||||
"// Generated by: programs/field_reflector/main.cpp //\n"
|
||||
"// //\n"
|
||||
"// Warning: This is a generated file, any changes made here will be //\n"
|
||||
"// overwritten by the build process. If you need to change what //\n"
|
||||
"// is generated here, you should either modify the reflected //\n"
|
||||
"// types, or modify the code generator itself. //\n"
|
||||
"// //\n"
|
||||
;
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
try
|
||||
{
|
||||
if( argc != 3 )
|
||||
{
|
||||
std::cout << "syntax: " << argv[0] << " <template_filename> <output_filename>\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
graphene::chain::impl::wild_object wo;
|
||||
|
||||
for( int32_t i = 0; i < wo.count(); ++i )
|
||||
{
|
||||
wo.set_which(i);
|
||||
wo.visit( serialize_object_type_visitor(i) );
|
||||
}
|
||||
|
||||
vector< getattr_switch_table_entry > switch_table = build_switch_table();
|
||||
|
||||
fc::mutable_variant_object tmpl_params;
|
||||
|
||||
tmpl_params["generated_file_banner"] = generated_file_banner;
|
||||
tmpl_params["object_descriptor"] = fc::json::to_string( g_vo_object_types );
|
||||
tmpl_params["cmp_attr_impl_body"] = generate_cmp_attr_impl( switch_table );
|
||||
|
||||
std::ifstream template_file( argv[1] );
|
||||
if (!template_file)
|
||||
FC_THROW("Error opening template file ${template_file}", ("template_file", argv[1]));
|
||||
std::stringstream ss;
|
||||
ss << template_file.rdbuf();
|
||||
std::string result = fc::format_string( ss.str(), tmpl_params );
|
||||
std::ofstream result_file( argv[2] );
|
||||
result_file << result;
|
||||
}
|
||||
catch ( const fc::exception& e )
|
||||
{
|
||||
edump((e.to_detail_string()));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
34
libraries/chain/include/graphene/chain/assert_evaluator.hpp
Normal file
34
libraries/chain/include/graphene/chain/assert_evaluator.hpp
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* 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>
|
||||
#include <graphene/chain/operations.hpp>
|
||||
#include <graphene/chain/database.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
class assert_evaluator : public evaluator<assert_evaluator>
|
||||
{
|
||||
public:
|
||||
typedef assert_operation operation_type;
|
||||
|
||||
void_result do_evaluate( const assert_operation& o );
|
||||
void_result do_apply( const assert_operation& o );
|
||||
};
|
||||
|
||||
} } // graphene::chain
|
||||
|
|
@ -83,6 +83,7 @@
|
|||
#define GRAPHENE_DEFAULT_CASHBACK_VESTING_THRESHOLD (GRAPHENE_BLOCKCHAIN_PRECISION*int64_t(100))
|
||||
#define GRAPHENE_DEFAULT_BURN_PERCENT_OF_FEE (20*GRAPHENE_1_PERCENT)
|
||||
#define GRAPHENE_WITNESS_PAY_PERCENT_PRECISION (1000000000)
|
||||
#define GRAPHENE_DEFAULT_MAX_ASSERT_OPCODE 1
|
||||
#define GRAPHENE_GENESIS_TIMESTAMP (1431700000) /// Should be divisible by GRAPHENE_DEFAULT_BLOCK_INTERVAL
|
||||
|
||||
// counter initialization values used to derive near and far future seeds for shuffling witnesses
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ namespace graphene { namespace chain {
|
|||
{
|
||||
skip_nothing = 0x00,
|
||||
skip_delegate_signature = 0x01, ///< used while reindexing
|
||||
skip_transaction_signatures = 0x02, ///< used by non delegate nodes
|
||||
skip_transaction_signatures = 0x02, ///< used by non-witness nodes
|
||||
skip_undo_block = 0x04, ///< used while reindexing
|
||||
skip_undo_transaction = 0x08, ///< used while applying block
|
||||
skip_transaction_dupe_check = 0x10, ///< used while reindexing
|
||||
|
|
@ -117,7 +117,9 @@ namespace graphene { namespace chain {
|
|||
skip_block_size_check = 0x40, ///< used when applying locally generated transactions
|
||||
skip_tapos_check = 0x80, ///< used while reindexing -- note this skips expiration check as well
|
||||
skip_authority_check = 0x100, ///< used while reindexing -- disables any checking of authority on transactions
|
||||
skip_merkle_check = 0x200 ///< used while reindexing
|
||||
skip_merkle_check = 0x200, ///< used while reindexing
|
||||
skip_assert_evaluation = 0x400, ///< used while reindexing
|
||||
skip_unknown_predicate = 0x800 ///< used by non-witness nodes to allow unknown predicates
|
||||
};
|
||||
|
||||
void open(const fc::path& data_dir, const genesis_state_type& initial_allocation = genesis_state_type());
|
||||
|
|
@ -397,8 +399,8 @@ namespace graphene { namespace chain {
|
|||
optional<undo_database::session> _pending_block_session;
|
||||
vector< unique_ptr<op_evaluator> > _operation_evaluators;
|
||||
|
||||
template<class ObjectType>
|
||||
vector<std::reference_wrapper<const ObjectType>> sort_votable_objects(size_t count)const;
|
||||
template<class Index>
|
||||
vector<std::reference_wrapper<const typename Index::object_type>> sort_votable_objects(size_t count)const;
|
||||
|
||||
//////////////////// db_block.cpp ////////////////////
|
||||
|
||||
|
|
|
|||
60
libraries/chain/include/graphene/chain/db_reflect_cmp.hpp
Normal file
60
libraries/chain/include/graphene/chain/db_reflect_cmp.hpp
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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 <vector>
|
||||
|
||||
#include <graphene/db/object.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
enum comparison_opcode
|
||||
{
|
||||
opc_equal_to,
|
||||
opc_not_equal_to,
|
||||
opc_greater,
|
||||
opc_less,
|
||||
opc_greater_equal,
|
||||
opc_less_equal
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
|
||||
/**
|
||||
* Compare the given field of the given object to the literal string.
|
||||
* The comparison opcode is specified by opc, which should be one
|
||||
* of comparison_opcode.
|
||||
*
|
||||
* The default behavior is to only allow opc_equal_to or
|
||||
* opc_not_equal_to, and implement these based on comparing the
|
||||
* serialized field to the given bytes.
|
||||
*
|
||||
* To override the default behavior, provide a template override
|
||||
* for _cmp() in db_reflect_cmp_impl.hpp. Beware adding such an
|
||||
* override will create a witness-only hardfork!
|
||||
*/
|
||||
bool cmp_attr_impl(
|
||||
const graphene::db::object& obj,
|
||||
uint16_t field_num,
|
||||
const std::vector<char>& lit,
|
||||
uint8_t opc
|
||||
);
|
||||
}
|
||||
|
||||
} }
|
||||
115
libraries/chain/include/graphene/chain/db_reflect_cmp_impl.hpp
Normal file
115
libraries/chain/include/graphene/chain/db_reflect_cmp_impl.hpp
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* 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 <fc/io/raw.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
//
|
||||
// This file implements the comparison used by the assert op.
|
||||
// The entry point for comparison is _cmp(), it can be specialized for
|
||||
// different types. The default implementation defers to _ser_eq_cmp()
|
||||
// which only allows equality comparisons, and asserts
|
||||
//
|
||||
|
||||
namespace graphene { namespace chain { namespace impl {
|
||||
|
||||
// useful for types which have all comparison ops implemented
|
||||
template< typename T >
|
||||
static bool _full_cmp( const T& a, const T& b, uint8_t opc )
|
||||
{
|
||||
switch( opc )
|
||||
{
|
||||
case opc_equal_to:
|
||||
return (a == b);
|
||||
case opc_not_equal_to:
|
||||
return (a != b);
|
||||
case opc_greater:
|
||||
return (a > b);
|
||||
case opc_less:
|
||||
return (a < b);
|
||||
case opc_greater_equal:
|
||||
return (a >= b);
|
||||
case opc_less_equal:
|
||||
return (a <= b);
|
||||
default:
|
||||
FC_ASSERT( false, "unknown comparison operator" );
|
||||
}
|
||||
}
|
||||
|
||||
// useful for types which have operator== implemented
|
||||
template< typename T >
|
||||
static bool _eq_cmp( const T& a, const T& b, uint8_t opc )
|
||||
{
|
||||
switch( opc )
|
||||
{
|
||||
case opc_equal_to:
|
||||
return (a == b);
|
||||
case opc_not_equal_to:
|
||||
return !(a == b);
|
||||
default:
|
||||
FC_ASSERT( false, "unknown comparison operator" );
|
||||
}
|
||||
}
|
||||
|
||||
// works for every serializable type
|
||||
template< typename T >
|
||||
static bool _ser_eq_cmp( const T& a, const std::vector<char>& b, uint8_t opc )
|
||||
{
|
||||
std::vector< char > _a = fc::raw::pack( a );
|
||||
return _eq_cmp( _a, b, opc );
|
||||
}
|
||||
|
||||
/*
|
||||
static bool _cmp( const fc::sha224& a, const fc::sha224& b, uint8_t opc )
|
||||
{
|
||||
assert( a.data_size() == b.data_size() );
|
||||
int result = memcmp( a.data(), b.data(), a.data_size() );
|
||||
switch( opc )
|
||||
{
|
||||
case opc_equal_to:
|
||||
return (result == 0);
|
||||
case opc_not_equal_to:
|
||||
return (result != 0);
|
||||
case opc_greater:
|
||||
return (result > 0);
|
||||
case opc_less:
|
||||
return (result < 0);
|
||||
case opc_greater_equal:
|
||||
return (result >= 0);
|
||||
case opc_less_equal:
|
||||
return (result <= 0);
|
||||
default:
|
||||
FC_ASSERT( false, "unknown comparison operator" );
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// _cmp needs to be specialized for types which don't have overloads
|
||||
// for all comparison operators
|
||||
|
||||
template< typename T >
|
||||
static bool _cmp( const T& a, const std::vector<char>& b, uint8_t opc )
|
||||
{
|
||||
return _ser_eq_cmp( a, b, opc );
|
||||
}
|
||||
|
||||
} } } // graphene::chain::detail
|
||||
|
|
@ -18,6 +18,7 @@
|
|||
#pragma once
|
||||
#include <graphene/chain/asset.hpp>
|
||||
#include <graphene/db/object.hpp>
|
||||
#include <graphene/db/generic_index.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
using namespace graphene::db;
|
||||
|
|
@ -33,7 +34,7 @@ namespace graphene { namespace chain {
|
|||
* active delegates has control.
|
||||
*
|
||||
* Delegates were separated into a separate object to make iterating over
|
||||
* the set of delegate easy.
|
||||
* the set of delegate easy.
|
||||
*/
|
||||
class delegate_object : public abstract_object<delegate_object>
|
||||
{
|
||||
|
|
@ -45,6 +46,19 @@ namespace graphene { namespace chain {
|
|||
vote_id_type vote_id;
|
||||
};
|
||||
|
||||
struct by_account;
|
||||
using delegate_multi_index_type = multi_index_container<
|
||||
delegate_object,
|
||||
indexed_by<
|
||||
ordered_unique< tag<by_id>,
|
||||
member<object, object_id_type, &object::id>
|
||||
>,
|
||||
hashed_unique< tag<by_account>,
|
||||
member<delegate_object, account_id_type, &delegate_object::delegate_account>
|
||||
>
|
||||
>
|
||||
>;
|
||||
using delegate_index = generic_index<delegate_object, delegate_multi_index_type>;
|
||||
} } // graphene::chain
|
||||
|
||||
FC_REFLECT_DERIVED( graphene::chain::delegate_object, (graphene::db::object),
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
#include <graphene/chain/types.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
typedef static_variant<address,public_key_type> address_or_key;
|
||||
|
||||
/**
|
||||
* @class key_object
|
||||
* @brief maps an ID to a public key or address
|
||||
|
|
@ -38,8 +40,9 @@ namespace graphene { namespace chain {
|
|||
address key_address()const;
|
||||
const public_key_type& key()const { return key_data.get<public_key_type>(); }
|
||||
|
||||
static_variant<address,public_key_type> key_data;
|
||||
address_or_key key_data;
|
||||
};
|
||||
} }
|
||||
|
||||
FC_REFLECT_TYPENAME( graphene::chain::address_or_key )
|
||||
FC_REFLECT_DERIVED( graphene::chain::key_object, (graphene::db::object), (key_data) )
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
*/
|
||||
#pragma once
|
||||
#include <graphene/db/object.hpp>
|
||||
#include <graphene/chain/operations.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
|
|
|
|||
|
|
@ -102,6 +102,25 @@ namespace graphene { namespace chain {
|
|||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief assert that some conditions are true.
|
||||
* @ingroup operations
|
||||
*/
|
||||
struct assert_operation
|
||||
{
|
||||
asset fee;
|
||||
account_id_type fee_paying_account;
|
||||
vector< vector< char > > predicates;
|
||||
flat_set<account_id_type> required_auths;
|
||||
|
||||
account_id_type fee_payer()const { return fee_paying_account; }
|
||||
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const;
|
||||
share_type calculate_fee( const fee_schedule_type& k )const{ return k.assert_op_fee; }
|
||||
void validate()const;
|
||||
|
||||
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const { acc.adjust( fee_payer(), -fee ); }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief reserves a new ID to refer to a particular key or address.
|
||||
* @ingroup operations
|
||||
|
|
@ -1339,7 +1358,8 @@ namespace graphene { namespace chain {
|
|||
vesting_balance_create_operation,
|
||||
vesting_balance_withdraw_operation,
|
||||
worker_create_operation,
|
||||
custom_operation
|
||||
custom_operation,
|
||||
assert_operation
|
||||
> operation;
|
||||
|
||||
/// @} // operations group
|
||||
|
|
@ -1568,7 +1588,10 @@ FC_REFLECT( graphene::chain::worker_create_operation,
|
|||
(fee)(owner)(work_begin_date)(work_end_date)(daily_pay)(initializer) )
|
||||
|
||||
FC_REFLECT( graphene::chain::custom_operation, (fee)(payer)(required_auths)(id)(data) )
|
||||
FC_REFLECT( graphene::chain::assert_operation, (fee)(fee_paying_account)(predicates)(required_auths) )
|
||||
|
||||
FC_REFLECT( graphene::chain::void_result, )
|
||||
|
||||
FC_REFLECT_TYPENAME( graphene::chain::operation )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::operation_result )
|
||||
FC_REFLECT_TYPENAME( fc::flat_set<graphene::chain::vote_id_type> )
|
||||
|
|
|
|||
60
libraries/chain/include/graphene/chain/predicate.hpp
Normal file
60
libraries/chain/include/graphene/chain/predicate.hpp
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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/types.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
class database;
|
||||
|
||||
class pred_field_lit_cmp
|
||||
{
|
||||
public:
|
||||
pred_field_lit_cmp(
|
||||
object_id_type obj_id,
|
||||
uint16_t field_num,
|
||||
const vector<char>& lit,
|
||||
uint8_t opc
|
||||
) :
|
||||
_obj_id( obj_id ),
|
||||
_field_num( field_num ),
|
||||
_lit( lit ),
|
||||
_opc( opc )
|
||||
{}
|
||||
pred_field_lit_cmp() {} // necessary for instantiating static_variant
|
||||
~pred_field_lit_cmp() {}
|
||||
|
||||
bool check_predicate( const database& db )const;
|
||||
|
||||
object_id_type _obj_id;
|
||||
uint16_t _field_num;
|
||||
vector<char> _lit;
|
||||
uint8_t _opc;
|
||||
};
|
||||
|
||||
typedef static_variant<
|
||||
pred_field_lit_cmp
|
||||
> predicate;
|
||||
|
||||
} }
|
||||
|
||||
FC_REFLECT( graphene::chain::pred_field_lit_cmp, (_obj_id)(_field_num)(_lit)(_opc) );
|
||||
|
|
@ -375,6 +375,7 @@ namespace graphene { namespace chain {
|
|||
uint32_t global_settle_fee;
|
||||
uint32_t worker_create_fee; ///< the cost to create a new worker
|
||||
uint32_t worker_delete_fee; ///< the cost to delete a worker
|
||||
uint32_t assert_op_fee; ///< fee per assert operation
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -429,6 +430,7 @@ namespace graphene { namespace chain {
|
|||
bool allow_non_member_whitelists = false; ///< true if non-member accounts may set whitelists and blacklists; false otherwise
|
||||
share_type witness_pay_per_block = GRAPHENE_DEFAULT_WITNESS_PAY_PER_BLOCK; ///< CORE to be allocated to witnesses (per block)
|
||||
share_type worker_budget_per_day = GRAPHENE_DEFAULT_WORKER_BUDGET_PER_DAY; ///< CORE to be allocated to workers (per day)
|
||||
uint16_t max_predicate_opcode = GRAPHENE_DEFAULT_MAX_ASSERT_OPCODE; ///< predicate_opcode must be less than this number
|
||||
|
||||
void validate()const
|
||||
{
|
||||
|
|
@ -548,6 +550,7 @@ FC_REFLECT( graphene::chain::fee_schedule_type,
|
|||
(global_settle_fee)
|
||||
(worker_create_fee)
|
||||
(worker_delete_fee)
|
||||
(assert_op_fee)
|
||||
)
|
||||
|
||||
FC_REFLECT( graphene::chain::chain_parameters,
|
||||
|
|
@ -574,8 +577,11 @@ FC_REFLECT( graphene::chain::chain_parameters,
|
|||
(allow_non_member_whitelists)
|
||||
(witness_pay_per_block)
|
||||
(worker_budget_per_day)
|
||||
(max_predicate_opcode)
|
||||
)
|
||||
|
||||
FC_REFLECT_TYPENAME( graphene::chain::share_type )
|
||||
|
||||
FC_REFLECT_TYPENAME( graphene::chain::key_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::account_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::asset_id_type )
|
||||
|
|
|
|||
|
|
@ -149,6 +149,8 @@ FC_REFLECT(graphene::chain::cdd_vesting_policy,
|
|||
(coin_seconds_earned_last_update)
|
||||
)
|
||||
|
||||
FC_REFLECT_TYPENAME( graphene::chain::vesting_policy )
|
||||
|
||||
FC_REFLECT_DERIVED(graphene::chain::vesting_balance_object, (graphene::db::object),
|
||||
(owner)
|
||||
(balance)
|
||||
|
|
|
|||
61
libraries/chain/include/graphene/chain/wild_object.hpp
Normal file
61
libraries/chain/include/graphene/chain/wild_object.hpp
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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 <fc/static_variant.hpp>
|
||||
|
||||
#include <graphene/chain/account_object.hpp>
|
||||
#include <graphene/chain/call_order_object.hpp>
|
||||
#include <graphene/chain/delegate_object.hpp>
|
||||
#include <graphene/chain/key_object.hpp>
|
||||
#include <graphene/chain/limit_order_object.hpp>
|
||||
#include <graphene/chain/operation_history_object.hpp>
|
||||
#include <graphene/chain/proposal_object.hpp>
|
||||
#include <graphene/chain/vesting_balance_object.hpp>
|
||||
#include <graphene/chain/withdraw_permission_object.hpp>
|
||||
#include <graphene/chain/witness_object.hpp>
|
||||
|
||||
namespace graphene { namespace chain { namespace impl {
|
||||
|
||||
/**
|
||||
* A static_variant of all object types.
|
||||
*
|
||||
* Used by field_reflector, this ultimately determines the object
|
||||
* types which may be inspected by pred_field_lit_cmp.
|
||||
*/
|
||||
typedef fc::static_variant<
|
||||
//null_object,
|
||||
//base_object,
|
||||
key_object,
|
||||
account_object,
|
||||
asset_object,
|
||||
force_settlement_object,
|
||||
delegate_object,
|
||||
witness_object,
|
||||
limit_order_object,
|
||||
call_order_object,
|
||||
//custom_object,
|
||||
proposal_object,
|
||||
operation_history_object,
|
||||
withdraw_permission_object,
|
||||
vesting_balance_object,
|
||||
worker_object
|
||||
> wild_object;
|
||||
|
||||
} } }
|
||||
|
|
@ -18,6 +18,7 @@
|
|||
#pragma once
|
||||
#include <graphene/chain/asset.hpp>
|
||||
#include <graphene/db/object.hpp>
|
||||
#include <graphene/db/generic_index.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
using namespace graphene::db;
|
||||
|
|
@ -40,6 +41,19 @@ namespace graphene { namespace chain {
|
|||
witness_object() : vote_id(vote_id_type::witness) {}
|
||||
};
|
||||
|
||||
struct by_account;
|
||||
using witness_multi_index_type = multi_index_container<
|
||||
witness_object,
|
||||
indexed_by<
|
||||
hashed_unique< tag<by_id>,
|
||||
member<object, object_id_type, &object::id>
|
||||
>,
|
||||
hashed_unique< tag<by_account>,
|
||||
member<witness_object, account_id_type, &witness_object::witness_account>
|
||||
>
|
||||
>
|
||||
>;
|
||||
using witness_index = generic_index<witness_object, witness_multi_index_type>;
|
||||
} } // graphene::chain
|
||||
|
||||
FC_REFLECT_DERIVED( graphene::chain::witness_object, (graphene::db::object),
|
||||
|
|
@ -49,4 +63,3 @@ FC_REFLECT_DERIVED( graphene::chain::witness_object, (graphene::db::object),
|
|||
(last_secret)
|
||||
(accumulated_income)
|
||||
(vote_id) )
|
||||
|
||||
|
|
|
|||
|
|
@ -188,6 +188,8 @@ FC_REFLECT( graphene::chain::refund_worker_type, (total_burned) )
|
|||
FC_REFLECT( graphene::chain::refund_worker_type::initializer, )
|
||||
FC_REFLECT( graphene::chain::vesting_balance_worker_type, (balance) )
|
||||
FC_REFLECT( graphene::chain::vesting_balance_worker_type::initializer, (pay_vesting_period_days) )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::worker_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::worker_initializer )
|
||||
FC_REFLECT_DERIVED( graphene::chain::worker_object, (graphene::db::object),
|
||||
(worker_account)
|
||||
(work_begin_date)
|
||||
|
|
|
|||
|
|
@ -21,8 +21,6 @@
|
|||
namespace graphene { namespace chain {
|
||||
address key_object::key_address()const
|
||||
{
|
||||
typedef static_variant<address,public_key_type> address_or_key;
|
||||
|
||||
switch( key_data.which() )
|
||||
{
|
||||
case address_or_key::tag<address>::value:
|
||||
|
|
|
|||
|
|
@ -813,4 +813,14 @@ share_type account_upgrade_operation::calculate_fee(const fee_schedule_type& k)
|
|||
return k.membership_annual_fee;
|
||||
}
|
||||
|
||||
void assert_operation::validate()const
|
||||
{
|
||||
FC_ASSERT( fee.amount >= 0 );
|
||||
}
|
||||
void assert_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const
|
||||
{
|
||||
active_auth_set.insert(fee_paying_account);
|
||||
active_auth_set.insert(required_auths.begin(), required_auths.end());
|
||||
}
|
||||
|
||||
} } // namespace graphene::chain
|
||||
|
|
|
|||
34
libraries/chain/predicate.cpp
Normal file
34
libraries/chain/predicate.cpp
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* 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/assert_evaluator.hpp>
|
||||
#include <graphene/chain/database.hpp>
|
||||
#include <graphene/chain/db_reflect_cmp.hpp>
|
||||
#include <graphene/chain/predicate.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
bool pred_field_lit_cmp::check_predicate( const database& db )const
|
||||
{
|
||||
return graphene::chain::impl::cmp_attr_impl( db.get_object( _obj_id ), _field_num, _lit, _opc );
|
||||
}
|
||||
|
||||
} } // graphene::chain
|
||||
81
libraries/chain/type_id.cpp
Normal file
81
libraries/chain/type_id.cpp
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
|
||||
#include <graphene/chain/account_object.hpp>
|
||||
#include <graphene/chain/asset_object.hpp>
|
||||
#include <graphene/chain/block_summary_object.hpp>
|
||||
#include <graphene/chain/call_order_object.hpp>
|
||||
#include <graphene/chain/delegate_object.hpp>
|
||||
#include <graphene/chain/global_property_object.hpp>
|
||||
#include <graphene/chain/key_object.hpp>
|
||||
#include <graphene/chain/limit_order_object.hpp>
|
||||
#include <graphene/chain/operation_history_object.hpp>
|
||||
#include <graphene/chain/proposal_object.hpp>
|
||||
#include <graphene/chain/transaction_object.hpp>
|
||||
#include <graphene/chain/vesting_balance_object.hpp>
|
||||
#include <graphene/chain/withdraw_permission_object.hpp>
|
||||
#include <graphene/chain/witness_object.hpp>
|
||||
#include <graphene/chain/witness_schedule_object.hpp>
|
||||
#include <graphene/chain/worker_object.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
// C++ requires that static class variables declared and initialized
|
||||
// in headers must also have a definition in a single source file,
|
||||
// else linker errors will occur [1].
|
||||
//
|
||||
// The purpose of this source file is to collect such definitions in
|
||||
// a single place.
|
||||
//
|
||||
// [1] http://stackoverflow.com/questions/8016780/undefined-reference-to-static-constexpr-char
|
||||
|
||||
const uint8_t account_object::space_id;
|
||||
const uint8_t account_object::type_id;
|
||||
|
||||
const uint8_t asset_object::space_id;
|
||||
const uint8_t asset_object::type_id;
|
||||
|
||||
const uint8_t block_summary_object::space_id;
|
||||
const uint8_t block_summary_object::type_id;
|
||||
|
||||
const uint8_t call_order_object::space_id;
|
||||
const uint8_t call_order_object::type_id;
|
||||
|
||||
const uint8_t delegate_object::space_id;
|
||||
const uint8_t delegate_object::type_id;
|
||||
|
||||
const uint8_t force_settlement_object::space_id;
|
||||
const uint8_t force_settlement_object::type_id;
|
||||
|
||||
const uint8_t global_property_object::space_id;
|
||||
const uint8_t global_property_object::type_id;
|
||||
|
||||
const uint8_t key_object::space_id;
|
||||
const uint8_t key_object::type_id;
|
||||
|
||||
const uint8_t limit_order_object::space_id;
|
||||
const uint8_t limit_order_object::type_id;
|
||||
|
||||
const uint8_t operation_history_object::space_id;
|
||||
const uint8_t operation_history_object::type_id;
|
||||
|
||||
const uint8_t proposal_object::space_id;
|
||||
const uint8_t proposal_object::type_id;
|
||||
|
||||
const uint8_t transaction_object::space_id;
|
||||
const uint8_t transaction_object::type_id;
|
||||
|
||||
const uint8_t vesting_balance_object::space_id;
|
||||
const uint8_t vesting_balance_object::type_id;
|
||||
|
||||
const uint8_t withdraw_permission_object::space_id;
|
||||
const uint8_t withdraw_permission_object::type_id;
|
||||
|
||||
const uint8_t witness_object::space_id;
|
||||
const uint8_t witness_object::type_id;
|
||||
|
||||
const uint8_t witness_schedule_object::space_id;
|
||||
const uint8_t witness_schedule_object::type_id;
|
||||
|
||||
const uint8_t worker_object::space_id;
|
||||
const uint8_t worker_object::type_id;
|
||||
|
||||
} }
|
||||
|
|
@ -93,6 +93,8 @@ namespace graphene { namespace db {
|
|||
virtual vector<char> pack()const { return fc::raw::pack( static_cast<const DerivedClass&>(*this) ); }
|
||||
};
|
||||
|
||||
typedef flat_map<uint8_t, object_id_type> annotation_map;
|
||||
|
||||
/**
|
||||
* @class annotated_object
|
||||
* @brief An object that is easily extended by providing pointers to other objects, one for each space.
|
||||
|
|
@ -117,12 +119,11 @@ namespace graphene { namespace db {
|
|||
* Annotations should be accessed via get_annotation and set_annotation so
|
||||
* that they can be maintained in sorted order.
|
||||
*/
|
||||
flat_map<uint8_t,object_id_type> annotations;
|
||||
annotation_map annotations;
|
||||
};
|
||||
|
||||
} } // graphene::db
|
||||
|
||||
FC_REFLECT_TYPENAME( graphene::db::annotation_map )
|
||||
FC_REFLECT( graphene::db::object, (id) )
|
||||
FC_REFLECT_DERIVED_TEMPLATE( (typename Derived), graphene::db::annotated_object<Derived>, (graphene::db::object), (annotations) )
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -87,6 +87,19 @@ namespace graphene { namespace db {
|
|||
|
||||
///@}
|
||||
|
||||
template<typename T>
|
||||
static const T& cast( const object& obj )
|
||||
{
|
||||
assert( nullptr != dynamic_cast<const T*>(&obj) );
|
||||
return static_cast<const T&>(obj);
|
||||
}
|
||||
template<typename T>
|
||||
static T& cast( object& obj )
|
||||
{
|
||||
assert( nullptr != dynamic_cast<T*>(&obj) );
|
||||
return static_cast<T&>(obj);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
const T& get( object_id_type id )const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit dde8ed9d7ab49807f2556488c0815f3741b11e00
|
||||
Subproject commit a8b85f6dcc4558b7a9913b59ef5dc19f3b5e62ca
|
||||
|
|
@ -243,6 +243,9 @@ struct operation_get_impacted_accounts
|
|||
|
||||
void operator()( const worker_create_operation& )const
|
||||
{}
|
||||
|
||||
void operator()( const assert_operation& )const
|
||||
{}
|
||||
};
|
||||
|
||||
account_create_observer::~account_create_observer()
|
||||
|
|
|
|||
12
programs/field_reflector/CMakeLists.txt
Normal file
12
programs/field_reflector/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
add_executable( field_reflector main.cpp )
|
||||
if( UNIX AND NOT APPLE )
|
||||
set(rt_library rt )
|
||||
endif()
|
||||
#find_package( Gperftools QUIET )
|
||||
#if( GPERFTOOLS_FOUND )
|
||||
# message( STATUS "Found gperftools; compiling client with TCMalloc")
|
||||
# list( APPEND PLATFORM_SPECIFIC_LIBS tcmalloc )
|
||||
#endif()
|
||||
|
||||
target_link_libraries( field_reflector
|
||||
PRIVATE graphene_app graphene_net graphene_chain graphene_utilities graphene_wallet fc ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} )
|
||||
|
|
@ -155,7 +155,7 @@ void database_fixture::verify_asset_supplies( )const
|
|||
total_balances[bad.options.short_backing_asset] += bad.settlement_fund;
|
||||
}
|
||||
}
|
||||
for( const witness_object& witness_obj : db.get_index_type<simple_index<witness_object>>() )
|
||||
for( const witness_object& witness_obj : db.get_index_type<witness_index>().indices() )
|
||||
{
|
||||
total_balances[asset_id_type()] += witness_obj.accumulated_income;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,14 +41,14 @@ genesis_state_type make_genesis() {
|
|||
secret_hash_type::encoder enc;
|
||||
fc::raw::pack(enc, delegate_priv_key);
|
||||
fc::raw::pack(enc, secret_hash_type());
|
||||
auto secret = secret_hash_type::hash(enc.result());
|
||||
for( int i = 0; i < 10; ++i )
|
||||
{
|
||||
genesis_state.allocation_targets.emplace_back("init"+fc::to_string(i), delegate_priv_key.get_public_key(), 0, true);
|
||||
genesis_state.initial_committee.push_back({"init"+fc::to_string(i)});
|
||||
auto name = "init"+fc::to_string(i);
|
||||
genesis_state.allocation_targets.emplace_back(name, delegate_priv_key.get_public_key(), 0, true);
|
||||
genesis_state.initial_committee.push_back({name});
|
||||
genesis_state.initial_witnesses.push_back({name, delegate_priv_key.get_public_key(), secret});
|
||||
}
|
||||
genesis_state.initial_witnesses = vector<genesis_state_type::initial_witness_type>(10, {"committee-account",
|
||||
delegate_priv_key.get_public_key(),
|
||||
secret_hash_type::hash(enc.result())});
|
||||
return genesis_state;
|
||||
}
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ BOOST_AUTO_TEST_CASE( block_database_test )
|
|||
for( uint32_t i = 0; i < 5; ++i )
|
||||
{
|
||||
if( i > 0 ) b.previous = b.id();
|
||||
b.witness = witness_id_type(i+1);
|
||||
b.witness = witness_id_type(i+1);
|
||||
bdb.store( b.id(), b );
|
||||
|
||||
auto fetch = bdb.fetch_by_number( b.block_num() );
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@
|
|||
#include <graphene/chain/vesting_balance_object.hpp>
|
||||
#include <graphene/chain/withdraw_permission_object.hpp>
|
||||
|
||||
#include <graphene/chain/predicate.hpp>
|
||||
#include <graphene/chain/db_reflect_cmp.hpp>
|
||||
|
||||
#include <fc/crypto/digest.hpp>
|
||||
|
||||
#include "../common/database_fixture.hpp"
|
||||
|
|
@ -797,6 +800,47 @@ BOOST_AUTO_TEST_CASE( unimp_force_settlement_unavailable )
|
|||
*/
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( assert_op_test )
|
||||
{
|
||||
try {
|
||||
// create some objects
|
||||
auto nathan_private_key = generate_private_key("nathan");
|
||||
auto dan_private_key = generate_private_key("dan");
|
||||
public_key_type nathan_public_key = nathan_private_key.get_public_key();
|
||||
public_key_type dan_public_key = dan_private_key.get_public_key();
|
||||
key_id_type nathan_key_id = register_key(nathan_public_key).id;
|
||||
key_id_type dan_key_id = register_key(dan_public_key).id;
|
||||
account_id_type nathan_id = create_account("nathan", nathan_key_id).id;
|
||||
|
||||
assert_operation op;
|
||||
decltype( key_object::key_data ) lit_key = nathan_public_key;
|
||||
|
||||
// nathan checks that his public key is equal to the given value.
|
||||
op.fee_paying_account = nathan_id;
|
||||
op.predicates = vector< vector< char > >();
|
||||
op.predicates.push_back(
|
||||
fc::raw::pack(
|
||||
predicate(
|
||||
pred_field_lit_cmp( nathan_key_id, 1, fc::raw::pack( lit_key ), opc_equal_to )
|
||||
)
|
||||
) );
|
||||
trx.operations.push_back(op);
|
||||
trx.sign( nathan_key_id, nathan_private_key );
|
||||
PUSH_TX( db, trx );
|
||||
|
||||
// nathan checks that his public key is not equal to the given value (fail)
|
||||
op.predicates.back() =
|
||||
fc::raw::pack(
|
||||
predicate(
|
||||
pred_field_lit_cmp( nathan_key_id, 1, fc::raw::pack( lit_key ), opc_not_equal_to )
|
||||
)
|
||||
);
|
||||
trx.operations.back() = op;
|
||||
trx.sign( nathan_key_id, nathan_private_key );
|
||||
BOOST_CHECK_THROW( PUSH_TX( db, trx ), fc::exception );
|
||||
} FC_LOG_AND_RETHROW()
|
||||
}
|
||||
|
||||
// TODO: Write linear VBO tests
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
|
|
|||
Loading…
Reference in a new issue