merge master
This commit is contained in:
commit
0a5954db70
34 changed files with 641 additions and 872 deletions
|
|
@ -66,6 +66,7 @@ IF(NOT "${Boost_VERSION}" MATCHES "1.53(.*)")
|
|||
ENDIF()
|
||||
|
||||
if( WIN32 )
|
||||
|
||||
message( STATUS "Configuring Graphene on WIN32")
|
||||
set( DB_VERSION 60 )
|
||||
set( BDB_STATIC_LIBS 1 )
|
||||
|
|
@ -98,13 +99,6 @@ if( WIN32 )
|
|||
SET(TCL_LIBRARY ${TCL_LIBS})
|
||||
|
||||
else( WIN32 ) # Apple AND Linux
|
||||
list(APPEND LEVELDB_BUILD_DEFINES LEVELDB_PLATFORM_POSIX LEVELDB_ATOMIC_PRESENT)
|
||||
if( APPLE )
|
||||
list(APPEND LEVELDB_BUILD_DEFINES OS_MACOSX)
|
||||
else() # Linux
|
||||
list(APPEND LEVELDB_BUILD_DEFINES OS_LINUX)
|
||||
list(APPEND LEVELDB_BUILD_LIBRARIES pthread)
|
||||
endif()
|
||||
|
||||
find_library(READLINE_LIBRARIES NAMES readline)
|
||||
find_path(READLINE_INCLUDE_DIR readline/readline.h)
|
||||
|
|
|
|||
|
|
@ -149,9 +149,10 @@ namespace detail {
|
|||
fc::create_directories(_data_dir / "blockchain/dblock");
|
||||
|
||||
auto nathan_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan")));
|
||||
genesis_allocation initial_allocation = {{graphene::chain::public_key_type(nathan_key.get_public_key()), 1}};
|
||||
genesis_state_type initial_state;
|
||||
initial_state.allocation_targets.emplace_back("nathan", address(public_key_type(nathan_key.get_public_key())), 1);
|
||||
if( _options->count("genesis-json") )
|
||||
initial_allocation = fc::json::from_file(_options->at("genesis-json").as<boost::filesystem::path>()).as<genesis_allocation>();
|
||||
initial_state = fc::json::from_file(_options->at("genesis-json").as<boost::filesystem::path>()).as<genesis_state_type>();
|
||||
else
|
||||
dlog("Allocating all stake to ${key}", ("key", utilities::key_to_wif(nathan_key)));
|
||||
|
||||
|
|
@ -161,12 +162,12 @@ namespace detail {
|
|||
if( _options->count("replay-blockchain") )
|
||||
{
|
||||
ilog("Replaying blockchain on user request.");
|
||||
_chain_db->reindex(_data_dir/"blockchain", initial_allocation);
|
||||
_chain_db->reindex(_data_dir/"blockchain", initial_state);
|
||||
} else if( clean )
|
||||
_chain_db->open(_data_dir / "blockchain", initial_allocation);
|
||||
_chain_db->open(_data_dir / "blockchain", initial_state);
|
||||
else {
|
||||
wlog("Detected unclean shutdown. Replaying blockchain...");
|
||||
_chain_db->reindex(_data_dir / "blockchain", initial_allocation);
|
||||
_chain_db->reindex(_data_dir / "blockchain", initial_state);
|
||||
}
|
||||
|
||||
reset_p2p_node(_data_dir);
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ namespace graphene { namespace chain {
|
|||
checksum_type signed_block::calculate_merkle_root()const
|
||||
{
|
||||
if( transactions.size() == 0 ) return checksum_type();
|
||||
|
||||
vector<digest_type> ids;
|
||||
ids.resize( ((transactions.size() + 1)/2)*2 );
|
||||
for( uint32_t i = 0; i < transactions.size(); ++i )
|
||||
|
|
|
|||
|
|
@ -1,3 +1,20 @@
|
|||
/*
|
||||
* 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/block_database.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
|
@ -8,7 +25,7 @@ struct index_entry
|
|||
uint32_t block_size = 0;
|
||||
block_id_type block_id;
|
||||
};
|
||||
}}
|
||||
}}
|
||||
FC_REFLECT( graphene::chain::index_entry, (block_pos)(block_size)(block_id) );
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
|
@ -117,73 +134,98 @@ block_id_type block_database::fetch_block_id( uint32_t block_num )const
|
|||
|
||||
|
||||
optional<signed_block> block_database::fetch_optional( const block_id_type& id )const
|
||||
{ try {
|
||||
index_entry e;
|
||||
auto index_pos = sizeof(e)*block_header::num_from_id(id);
|
||||
_block_num_to_pos.seekg( 0, _block_num_to_pos.end );
|
||||
FC_ASSERT( _block_num_to_pos.tellg() > index_pos );
|
||||
|
||||
_block_num_to_pos.seekg( index_pos );
|
||||
_block_num_to_pos.read( (char*)&e, sizeof(e) );
|
||||
|
||||
if( e.block_id != id ) return optional<signed_block>();
|
||||
|
||||
vector<char> data( e.block_size );
|
||||
_blocks.seekg( e.block_pos );
|
||||
_blocks.read( data.data(), e.block_size );
|
||||
auto result = fc::raw::unpack<signed_block>(data);
|
||||
FC_ASSERT( result.id() == e.block_id );
|
||||
return result;
|
||||
} FC_CAPTURE_AND_RETHROW( (id) ) }
|
||||
|
||||
{
|
||||
try
|
||||
{
|
||||
index_entry e;
|
||||
auto index_pos = sizeof(e)*block_header::num_from_id(id);
|
||||
_block_num_to_pos.seekg( 0, _block_num_to_pos.end );
|
||||
FC_ASSERT( _block_num_to_pos.tellg() > index_pos );
|
||||
|
||||
_block_num_to_pos.seekg( index_pos );
|
||||
_block_num_to_pos.read( (char*)&e, sizeof(e) );
|
||||
|
||||
if( e.block_id != id ) return optional<signed_block>();
|
||||
|
||||
vector<char> data( e.block_size );
|
||||
_blocks.seekg( e.block_pos );
|
||||
_blocks.read( data.data(), e.block_size );
|
||||
auto result = fc::raw::unpack<signed_block>(data);
|
||||
FC_ASSERT( result.id() == e.block_id );
|
||||
return result;
|
||||
}
|
||||
catch (const fc::exception&)
|
||||
{
|
||||
}
|
||||
catch (const std::exception&)
|
||||
{
|
||||
}
|
||||
return optional<signed_block>();
|
||||
}
|
||||
|
||||
optional<signed_block> block_database::fetch_by_number( uint32_t block_num )const
|
||||
{ try {
|
||||
index_entry e;
|
||||
auto index_pos = sizeof(e)*block_num;
|
||||
_block_num_to_pos.seekg( 0, _block_num_to_pos.end );
|
||||
FC_ASSERT( _block_num_to_pos.tellg() > index_pos );
|
||||
{
|
||||
try
|
||||
{
|
||||
index_entry e;
|
||||
auto index_pos = sizeof(e)*block_num;
|
||||
_block_num_to_pos.seekg( 0, _block_num_to_pos.end );
|
||||
FC_ASSERT( _block_num_to_pos.tellg() > index_pos );
|
||||
|
||||
_block_num_to_pos.seekg( index_pos, _block_num_to_pos.beg );
|
||||
// wdump((int64_t(_block_num_to_pos.tellg())) );
|
||||
_block_num_to_pos.read( (char*)&e, sizeof(e) );
|
||||
// wdump((block_num)(e));
|
||||
_block_num_to_pos.seekg( index_pos, _block_num_to_pos.beg );
|
||||
_block_num_to_pos.read( (char*)&e, sizeof(e) );
|
||||
|
||||
vector<char> data( e.block_size );
|
||||
_blocks.seekg( e.block_pos );
|
||||
_blocks.read( data.data(), e.block_size );
|
||||
auto result = fc::raw::unpack<signed_block>(data);
|
||||
FC_ASSERT( result.id() == e.block_id );
|
||||
return result;
|
||||
} FC_CAPTURE_AND_RETHROW( (block_num) ) }
|
||||
vector<char> data( e.block_size );
|
||||
_blocks.seekg( e.block_pos );
|
||||
_blocks.read( data.data(), e.block_size );
|
||||
auto result = fc::raw::unpack<signed_block>(data);
|
||||
FC_ASSERT( result.id() == e.block_id );
|
||||
return result;
|
||||
}
|
||||
catch (const fc::exception&)
|
||||
{
|
||||
}
|
||||
catch (const std::exception&)
|
||||
{
|
||||
}
|
||||
return optional<signed_block>();
|
||||
}
|
||||
|
||||
|
||||
optional<signed_block> block_database::last()const
|
||||
{
|
||||
index_entry e;
|
||||
_block_num_to_pos.seekg( 0, _block_num_to_pos.end );
|
||||
|
||||
if( _block_num_to_pos.tellp() < sizeof(index_entry) )
|
||||
return optional<signed_block>();
|
||||
|
||||
_block_num_to_pos.seekg( -sizeof(index_entry), _block_num_to_pos.end );
|
||||
_block_num_to_pos.read( (char*)&e, sizeof(e) );
|
||||
while( e.block_size == 0 && _blocks.tellg() > 0 )
|
||||
try
|
||||
{
|
||||
_block_num_to_pos.seekg( -sizeof(index_entry), _block_num_to_pos.cur );
|
||||
index_entry e;
|
||||
_block_num_to_pos.seekg( 0, _block_num_to_pos.end );
|
||||
|
||||
if( _block_num_to_pos.tellp() < sizeof(index_entry) )
|
||||
return optional<signed_block>();
|
||||
|
||||
_block_num_to_pos.seekg( -sizeof(index_entry), _block_num_to_pos.end );
|
||||
_block_num_to_pos.read( (char*)&e, sizeof(e) );
|
||||
while( e.block_size == 0 && _blocks.tellg() > 0 )
|
||||
{
|
||||
_block_num_to_pos.seekg( -sizeof(index_entry), _block_num_to_pos.cur );
|
||||
_block_num_to_pos.read( (char*)&e, sizeof(e) );
|
||||
}
|
||||
|
||||
if( e.block_size == 0 )
|
||||
return optional<signed_block>();
|
||||
|
||||
vector<char> data( e.block_size );
|
||||
_blocks.seekg( e.block_pos );
|
||||
_blocks.read( data.data(), e.block_size );
|
||||
auto result = fc::raw::unpack<signed_block>(data);
|
||||
return result;
|
||||
}
|
||||
|
||||
if( e.block_size == 0 )
|
||||
return optional<signed_block>();
|
||||
|
||||
vector<char> data( e.block_size );
|
||||
_blocks.seekg( e.block_pos );
|
||||
_blocks.read( data.data(), e.block_size );
|
||||
auto result = fc::raw::unpack<signed_block>(data);
|
||||
//wdump((result));
|
||||
return result;
|
||||
catch (const fc::exception&)
|
||||
{
|
||||
}
|
||||
catch (const std::exception&)
|
||||
{
|
||||
}
|
||||
return optional<signed_block>();
|
||||
}
|
||||
|
||||
|
||||
} }
|
||||
|
|
|
|||
|
|
@ -81,7 +81,18 @@ 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 result;
|
||||
with_skip_flags( skip, [&]()
|
||||
{
|
||||
result = _push_block( new_block );
|
||||
} );
|
||||
return result;
|
||||
}
|
||||
|
||||
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 );
|
||||
|
|
@ -182,12 +193,23 @@ bool database::push_block( const signed_block& new_block, uint32_t skip )
|
|||
*/
|
||||
processed_transaction database::push_transaction( const signed_transaction& trx, uint32_t skip )
|
||||
{
|
||||
processed_transaction result;
|
||||
with_skip_flags( skip, [&]()
|
||||
{
|
||||
result = _push_transaction( trx );
|
||||
} );
|
||||
return result;
|
||||
}
|
||||
|
||||
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();
|
||||
auto session = _undo_db.start_undo_session();
|
||||
auto processed_trx = apply_transaction( trx, skip );
|
||||
auto processed_trx = _apply_transaction( trx );
|
||||
_pending_block.transactions.push_back(processed_trx);
|
||||
|
||||
FC_ASSERT( (skip & skip_block_size_check) ||
|
||||
|
|
@ -240,8 +262,23 @@ signed_block database::generate_block(
|
|||
const fc::ecc::private_key& block_signing_private_key,
|
||||
uint32_t skip /* = 0 */
|
||||
)
|
||||
{
|
||||
signed_block result;
|
||||
with_skip_flags( skip, [&]()
|
||||
{
|
||||
result = _generate_block( when, witness_id, block_signing_private_key );
|
||||
} );
|
||||
return result;
|
||||
}
|
||||
|
||||
signed_block database::_generate_block(
|
||||
fc::time_point_sec when,
|
||||
witness_id_type witness_id,
|
||||
const fc::ecc::private_key& block_signing_private_key
|
||||
)
|
||||
{
|
||||
try {
|
||||
uint32_t skip = get_node_properties().skip_flags;
|
||||
uint32_t slot_num = get_slot_at_time( when );
|
||||
witness_id_type scheduled_witness = get_scheduled_witness( slot_num ).first;
|
||||
FC_ASSERT( scheduled_witness == witness_id );
|
||||
|
|
@ -322,7 +359,17 @@ const vector<operation_history_object>& database::get_applied_operations() const
|
|||
//////////////////// private methods ////////////////////
|
||||
|
||||
void database::apply_block( const signed_block& next_block, uint32_t skip )
|
||||
{
|
||||
with_skip_flags( skip, [&]()
|
||||
{
|
||||
_apply_block( next_block );
|
||||
} );
|
||||
return;
|
||||
}
|
||||
|
||||
void database::_apply_block( const signed_block& next_block )
|
||||
{ try {
|
||||
uint32_t skip = get_node_properties().skip_flags;
|
||||
_applied_ops.clear();
|
||||
|
||||
FC_ASSERT( (skip & skip_merkle_check) || next_block.transaction_merkle_root == next_block.calculate_merkle_root(), "", ("next_block.transaction_merkle_root",next_block.transaction_merkle_root)("calc",next_block.calculate_merkle_root())("next_block",next_block)("id",next_block.id()) );
|
||||
|
|
@ -375,16 +422,27 @@ void database::apply_block( const signed_block& next_block, uint32_t skip )
|
|||
|
||||
|
||||
update_pending_block(next_block, current_block_interval);
|
||||
} FC_CAPTURE_AND_RETHROW( (next_block.block_num())(skip) ) }
|
||||
} FC_CAPTURE_AND_RETHROW( (next_block.block_num()) ) }
|
||||
|
||||
processed_transaction database::apply_transaction( const signed_transaction& trx, uint32_t skip )
|
||||
{
|
||||
processed_transaction result;
|
||||
with_skip_flags( skip, [&]()
|
||||
{
|
||||
result = _apply_transaction( trx );
|
||||
} );
|
||||
return result;
|
||||
}
|
||||
|
||||
processed_transaction database::_apply_transaction( const signed_transaction& trx )
|
||||
{ try {
|
||||
uint32_t skip = get_node_properties().skip_flags;
|
||||
trx.validate();
|
||||
auto& trx_idx = get_mutable_index_type<transaction_index>();
|
||||
auto trx_id = trx.id();
|
||||
FC_ASSERT( (skip & skip_transaction_dupe_check) ||
|
||||
trx_idx.indices().get<by_trx_id>().find(trx_id) == trx_idx.indices().get<by_trx_id>().end() );
|
||||
transaction_evaluation_state eval_state(this, skip&skip_authority_check );
|
||||
transaction_evaluation_state eval_state(this);
|
||||
const chain_parameters& chain_parameters = get_global_properties().parameters;
|
||||
eval_state._trx = &trx;
|
||||
|
||||
|
|
|
|||
|
|
@ -63,4 +63,14 @@ decltype( chain_parameters::block_interval ) database::block_interval( )const
|
|||
return get_global_properties().parameters.block_interval;
|
||||
}
|
||||
|
||||
const node_property_object& database::get_node_properties()const
|
||||
{
|
||||
return _node_property_object;
|
||||
}
|
||||
|
||||
node_property_object& database::node_properties()
|
||||
{
|
||||
return _node_property_object;
|
||||
}
|
||||
|
||||
} }
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ void database::initialize_indexes()
|
|||
add_index< primary_index< simple_index< witness_schedule_object > > >();
|
||||
}
|
||||
|
||||
void database::init_genesis(const genesis_allocation& initial_allocation)
|
||||
void database::init_genesis(const genesis_state_type& genesis_state)
|
||||
{ try {
|
||||
_undo_db.disable();
|
||||
|
||||
|
|
@ -219,7 +219,7 @@ void database::init_genesis(const genesis_allocation& initial_allocation)
|
|||
for( const witness_id_type& wit : init_witnesses )
|
||||
p.active_witnesses.insert( wit );
|
||||
p.next_available_vote_id = delegates_and_witnesses * 2;
|
||||
p.chain_id = fc::digest(initial_allocation);
|
||||
p.chain_id = fc::digest(genesis_state);
|
||||
});
|
||||
(void)properties;
|
||||
|
||||
|
|
@ -250,11 +250,11 @@ void database::init_genesis(const genesis_allocation& initial_allocation)
|
|||
assert( get_balance(account_id_type(), asset_id_type()) == asset(dyn_asset.current_supply) );
|
||||
(void)core_asset;
|
||||
|
||||
if( !initial_allocation.empty() )
|
||||
if( !genesis_state.allocation_targets.empty() )
|
||||
{
|
||||
share_type total_allocation = 0;
|
||||
for( const auto& handout : initial_allocation )
|
||||
total_allocation += handout.second;
|
||||
for( const auto& handout : genesis_state.allocation_targets )
|
||||
total_allocation += handout.weight;
|
||||
|
||||
auto mangle_to_name = [](const fc::static_variant<public_key_type, address>& key) {
|
||||
string addr = string(key.which() == std::decay<decltype(key)>::type::tag<address>::value? key.get<address>()
|
||||
|
|
@ -273,22 +273,22 @@ void database::init_genesis(const genesis_allocation& initial_allocation)
|
|||
|
||||
fc::time_point start_time = fc::time_point::now();
|
||||
|
||||
for( const auto& handout : initial_allocation )
|
||||
for( const auto& handout : genesis_state.allocation_targets )
|
||||
{
|
||||
asset amount(handout.second);
|
||||
asset amount(handout.weight);
|
||||
amount.amount = ((fc::uint128(amount.amount.value) * GRAPHENE_INITIAL_SUPPLY)/total_allocation.value).to_uint64();
|
||||
if( amount.amount == 0 )
|
||||
{
|
||||
wlog("Skipping zero allocation to ${k}", ("k", handout.first));
|
||||
wlog("Skipping zero allocation to ${k}", ("k", handout.name));
|
||||
continue;
|
||||
}
|
||||
|
||||
signed_transaction trx;
|
||||
trx.operations.emplace_back(key_create_operation({asset(), genesis_account.id, handout.first}));
|
||||
trx.operations.emplace_back(key_create_operation({asset(), genesis_account.id, handout.addr}));
|
||||
relative_key_id_type key_id(0);
|
||||
authority account_authority(1, key_id, 1);
|
||||
account_create_operation cop;
|
||||
cop.name = mangle_to_name(handout.first);
|
||||
cop.name = handout.name;
|
||||
cop.registrar = account_id_type(1);
|
||||
cop.active = account_authority;
|
||||
cop.owner = account_authority;
|
||||
|
|
@ -322,7 +322,7 @@ void database::init_genesis(const genesis_allocation& initial_allocation)
|
|||
|
||||
fc::microseconds duration = fc::time_point::now() - start_time;
|
||||
ilog("Finished allocating to ${n} accounts in ${t} milliseconds.",
|
||||
("n", initial_allocation.size())("t", duration.count() / 1000));
|
||||
("n", genesis_state.allocation_targets.size())("t", duration.count() / 1000));
|
||||
}
|
||||
|
||||
_undo_db.enable();
|
||||
|
|
|
|||
|
|
@ -272,8 +272,7 @@ void database::process_budget()
|
|||
});
|
||||
modify(dpo, [&]( dynamic_global_property_object& _dpo )
|
||||
{
|
||||
// Should this be +=?
|
||||
_dpo.witness_budget = witness_budget;
|
||||
_dpo.witness_budget += witness_budget;
|
||||
_dpo.last_budget_time = now;
|
||||
});
|
||||
|
||||
|
|
@ -406,8 +405,10 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g
|
|||
next_maintenance_time = time_point_sec() +
|
||||
(((next_block.timestamp.sec_since_epoch() / maintenance_interval) + 1) * maintenance_interval);
|
||||
else
|
||||
next_maintenance_time += maintenance_interval;
|
||||
assert( next_maintenance_time > next_block.timestamp );
|
||||
// It's possible we have missed blocks for at least a maintenance interval.
|
||||
// In this case, we'll need to bump the next maintenance time more than once.
|
||||
do next_maintenance_time += maintenance_interval;
|
||||
while( next_maintenance_time < head_block_time() );
|
||||
}
|
||||
|
||||
modify(get_dynamic_global_properties(), [next_maintenance_time](dynamic_global_property_object& d) {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ database::~database(){
|
|||
_pending_block_session->commit();
|
||||
}
|
||||
|
||||
void database::open( const fc::path& data_dir, const genesis_allocation& initial_allocation )
|
||||
void database::open( const fc::path& data_dir, const genesis_state_type& initial_allocation )
|
||||
{ try {
|
||||
// ilog("Open database in ${d}", ("d", data_dir));
|
||||
object_database::open( data_dir );
|
||||
|
|
@ -55,7 +55,7 @@ void database::open( const fc::path& data_dir, const genesis_allocation& initial
|
|||
|
||||
} FC_CAPTURE_AND_RETHROW( (data_dir) ) }
|
||||
|
||||
void database::reindex(fc::path data_dir, const genesis_allocation& initial_allocation)
|
||||
void database::reindex(fc::path data_dir, const genesis_state_type& initial_allocation)
|
||||
{ try {
|
||||
wipe(data_dir, false);
|
||||
open(data_dir, initial_allocation);
|
||||
|
|
|
|||
|
|
@ -118,18 +118,21 @@ void database::clear_expired_proposals()
|
|||
|
||||
void database::clear_expired_orders()
|
||||
{
|
||||
transaction_evaluation_state cancel_context(this, true);
|
||||
with_skip_flags(
|
||||
get_node_properties().skip_flags | skip_authority_check, [&](){
|
||||
transaction_evaluation_state cancel_context(this);
|
||||
|
||||
//Cancel expired limit orders
|
||||
auto& limit_index = get_index_type<limit_order_index>().indices().get<by_expiration>();
|
||||
while( !limit_index.empty() && limit_index.begin()->expiration <= head_block_time() )
|
||||
{
|
||||
limit_order_cancel_operation canceler;
|
||||
const limit_order_object& order = *limit_index.begin();
|
||||
canceler.fee_paying_account = order.seller;
|
||||
canceler.order = order.id;
|
||||
apply_operation(cancel_context, canceler);
|
||||
}
|
||||
//Cancel expired limit orders
|
||||
auto& limit_index = get_index_type<limit_order_index>().indices().get<by_expiration>();
|
||||
while( !limit_index.empty() && limit_index.begin()->expiration <= head_block_time() )
|
||||
{
|
||||
limit_order_cancel_operation canceler;
|
||||
const limit_order_object& order = *limit_index.begin();
|
||||
canceler.fee_paying_account = order.seller;
|
||||
canceler.order = order.id;
|
||||
apply_operation(cancel_context, canceler);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
//Process expired force settlement orders
|
||||
|
|
|
|||
|
|
@ -95,13 +95,6 @@ namespace graphene { namespace chain {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
bool generic_evaluator::verify_signature( const key_object& k )
|
||||
{
|
||||
return trx_state->_skip_signature_check || trx_state->signed_by( k.id );
|
||||
}
|
||||
*/
|
||||
|
||||
object_id_type generic_evaluator::get_relative_id( object_id_type rel_id )const
|
||||
{
|
||||
if( rel_id.space() == relative_protocol_ids )
|
||||
|
|
|
|||
|
|
@ -1,3 +1,20 @@
|
|||
/*
|
||||
* 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 <fstream>
|
||||
#include <graphene/chain/block.hpp>
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include <graphene/chain/block.hpp>
|
||||
#include <graphene/chain/asset.hpp>
|
||||
#include <graphene/chain/global_property_object.hpp>
|
||||
#include <graphene/chain/node_property_object.hpp>
|
||||
#include <graphene/chain/account_object.hpp>
|
||||
#include <graphene/chain/asset_object.hpp>
|
||||
#include <graphene/chain/fork_database.hpp>
|
||||
|
|
@ -38,7 +39,55 @@ namespace graphene { namespace chain {
|
|||
using graphene::db::abstract_object;
|
||||
using graphene::db::object;
|
||||
|
||||
typedef vector<std::pair<fc::static_variant<address, public_key_type>, share_type >> genesis_allocation;
|
||||
struct genesis_state_type {
|
||||
struct allocation_target_type {
|
||||
allocation_target_type(const string& name = string(), const address& addr = address(), share_type weight = share_type())
|
||||
: name(name), addr(addr), weight(weight){}
|
||||
string name;
|
||||
address addr;
|
||||
share_type weight;
|
||||
};
|
||||
struct initial_witness_type {
|
||||
/// Must correspond to one of the allocation targets.
|
||||
string owner_name;
|
||||
public_key_type block_signing_key;
|
||||
secret_hash_type initial_secret;
|
||||
};
|
||||
struct initial_committee_member_type {
|
||||
/// Must correspond to one of the allocation targets.
|
||||
string owner_name;
|
||||
};
|
||||
|
||||
chain_parameters initial_parameters;
|
||||
vector<allocation_target_type> allocation_targets;
|
||||
vector<initial_witness_type> initial_witnesses;
|
||||
vector<initial_committee_member_type> initial_committee;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
/**
|
||||
* Class used to help the with_skip_flags implementation.
|
||||
* It must be defined in this header because it must be
|
||||
* available to the with_skip_flags implementation,
|
||||
* which is a template and therefore must also be defined
|
||||
* in this header.
|
||||
*/
|
||||
struct skip_flags_restorer
|
||||
{
|
||||
skip_flags_restorer( node_property_object& npo, uint32_t old_skip_flags )
|
||||
: _npo( npo ), _old_skip_flags( old_skip_flags )
|
||||
{}
|
||||
|
||||
~skip_flags_restorer()
|
||||
{
|
||||
_npo.skip_flags = _old_skip_flags;
|
||||
}
|
||||
|
||||
node_property_object& _npo;
|
||||
uint32_t _old_skip_flags;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @class database
|
||||
|
|
@ -67,14 +116,14 @@ namespace graphene { namespace chain {
|
|||
skip_merkle_check = 0x200 ///< used while reindexing
|
||||
};
|
||||
|
||||
void open(const fc::path& data_dir, const genesis_allocation& initial_allocation = genesis_allocation());
|
||||
void open(const fc::path& data_dir, const genesis_state_type& initial_allocation = genesis_state_type());
|
||||
/**
|
||||
* @brief Rebuild object graph from block history and open detabase
|
||||
*
|
||||
* This method may be called after or instead of @ref database::open, and will rebuild the object graph by
|
||||
* replaying blockchain history. When this method exits successfully, the database will be open.
|
||||
*/
|
||||
void reindex(fc::path data_dir, const genesis_allocation& initial_allocation = genesis_allocation());
|
||||
void reindex(fc::path data_dir, const genesis_state_type& initial_allocation = genesis_state_type());
|
||||
|
||||
/**
|
||||
* @brief wipe Delete database from disk, and potentially the raw chain as well.
|
||||
|
|
@ -100,6 +149,9 @@ namespace graphene { namespace chain {
|
|||
|
||||
bool push_block( const signed_block& b, uint32_t skip = skip_nothing );
|
||||
processed_transaction push_transaction( const signed_transaction& trx, uint32_t skip = skip_nothing );
|
||||
bool _push_block( const signed_block& b );
|
||||
processed_transaction _push_transaction( const signed_transaction& trx );
|
||||
|
||||
///@throws fc::exception if the proposed transaction fails to apply.
|
||||
processed_transaction push_proposal( const proposal_object& proposal );
|
||||
|
||||
|
|
@ -107,7 +159,12 @@ namespace graphene { namespace chain {
|
|||
const fc::time_point_sec when,
|
||||
witness_id_type witness_id,
|
||||
const fc::ecc::private_key& block_signing_private_key,
|
||||
uint32_t skip = 0
|
||||
uint32_t skip
|
||||
);
|
||||
signed_block _generate_block(
|
||||
const fc::time_point_sec when,
|
||||
witness_id_type witness_id,
|
||||
const fc::ecc::private_key& block_signing_private_key
|
||||
);
|
||||
|
||||
void pop_block();
|
||||
|
|
@ -192,6 +249,7 @@ namespace graphene { namespace chain {
|
|||
const asset_object& get_core_asset()const;
|
||||
const global_property_object& get_global_properties()const;
|
||||
const dynamic_global_property_object& get_dynamic_global_properties()const;
|
||||
const node_property_object& get_node_properties()const;
|
||||
const fee_schedule_type& current_fee_schedule()const;
|
||||
|
||||
time_point_sec head_block_time()const;
|
||||
|
|
@ -200,12 +258,31 @@ namespace graphene { namespace chain {
|
|||
|
||||
decltype( chain_parameters::block_interval ) block_interval( )const;
|
||||
|
||||
node_property_object& node_properties();
|
||||
|
||||
/**
|
||||
* Set the skip_flags to the given value, call callback,
|
||||
* then reset skip_flags to their previous value after
|
||||
* callback is done.
|
||||
*/
|
||||
template< typename Lambda >
|
||||
void with_skip_flags(
|
||||
uint32_t skip_flags,
|
||||
Lambda callback )
|
||||
{
|
||||
node_property_object& npo = node_properties();
|
||||
detail::skip_flags_restorer restorer( npo, npo.skip_flags );
|
||||
npo.skip_flags = skip_flags;
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
//////////////////// db_init.cpp ////////////////////
|
||||
|
||||
void initialize_evaluators();
|
||||
/// Reset the object graph in-memory
|
||||
void initialize_indexes();
|
||||
void init_genesis(const genesis_allocation& initial_allocation = genesis_allocation());
|
||||
void init_genesis(const genesis_state_type& genesis_state = genesis_state_type());
|
||||
|
||||
template<typename EvaluatorType>
|
||||
void register_evaluator()
|
||||
|
|
@ -323,12 +400,15 @@ namespace graphene { namespace chain {
|
|||
|
||||
void apply_block( const signed_block& next_block, uint32_t skip = skip_nothing );
|
||||
processed_transaction apply_transaction( const signed_transaction& trx, uint32_t skip = skip_nothing );
|
||||
void _apply_block( const signed_block& next_block );
|
||||
processed_transaction _apply_transaction( const signed_transaction& trx );
|
||||
operation_result apply_operation( transaction_evaluation_state& eval_state, const operation& op );
|
||||
|
||||
///Steps involved in applying a new block
|
||||
///@{
|
||||
|
||||
const witness_object& validate_block_header( uint32_t skip, const signed_block& next_block )const;
|
||||
const witness_object& _validate_block_header( const signed_block& next_block )const;
|
||||
void create_block_summary(const signed_block& next_block);
|
||||
|
||||
//////////////////// db_update.cpp ////////////////////
|
||||
|
|
@ -392,6 +472,8 @@ namespace graphene { namespace chain {
|
|||
vector<uint64_t> _witness_count_histogram_buffer;
|
||||
vector<uint64_t> _committee_count_histogram_buffer;
|
||||
uint64_t _total_voting_stake;
|
||||
|
||||
node_property_object _node_property_object;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
|
|
@ -421,3 +503,8 @@ namespace graphene { namespace chain {
|
|||
}
|
||||
|
||||
} }
|
||||
|
||||
FC_REFLECT(graphene::chain::genesis_state_type::allocation_target_type, (name)(addr)(weight))
|
||||
FC_REFLECT(graphene::chain::genesis_state_type::initial_witness_type, (owner_name)(block_signing_key)(initial_secret))
|
||||
FC_REFLECT(graphene::chain::genesis_state_type::initial_committee_member_type, (owner_name))
|
||||
FC_REFLECT(graphene::chain::genesis_state_type, (initial_parameters)(allocation_targets)(initial_witnesses)(initial_committee))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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/db/object.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
/**
|
||||
* @brief Contains per-node database configuration.
|
||||
*
|
||||
* Transactions are evaluated differently based on per-node state.
|
||||
* Settings here may change based on whether the node is syncing or up-to-date.
|
||||
* Or whether the node is a witness node. Or if we're processing a
|
||||
* transaction in a witness-signed block vs. a fresh transaction
|
||||
* from the p2p network. Or configuration-specified tradeoffs of
|
||||
* performance/hardfork resilience vs. paranoia.
|
||||
*/
|
||||
class node_property_object
|
||||
{
|
||||
public:
|
||||
node_property_object() : skip_flags(0) {}
|
||||
~node_property_object(){}
|
||||
|
||||
uint32_t skip_flags;
|
||||
};
|
||||
} } // graphene::chain
|
||||
|
|
@ -33,8 +33,8 @@ namespace graphene { namespace chain {
|
|||
class transaction_evaluation_state
|
||||
{
|
||||
public:
|
||||
transaction_evaluation_state( database* db = nullptr, bool skip_authority_check = false )
|
||||
:_db(db),_skip_authority_check(skip_authority_check){}
|
||||
transaction_evaluation_state( database* db = nullptr )
|
||||
:_db(db){}
|
||||
|
||||
bool check_authority( const account_object&, authority::classification auth_class = authority::active, int depth = 0 );
|
||||
|
||||
|
|
@ -55,7 +55,6 @@ namespace graphene { namespace chain {
|
|||
|
||||
const signed_transaction* _trx = nullptr;
|
||||
database* _db = nullptr;
|
||||
bool _skip_authority_check = false;
|
||||
bool _is_proposed_trx = false;
|
||||
};
|
||||
} } // namespace graphene::chain
|
||||
|
|
|
|||
|
|
@ -93,13 +93,16 @@ void_result proposal_update_evaluator::do_evaluate(const proposal_update_operati
|
|||
FC_ASSERT( _proposal->available_owner_approvals.find(id) != _proposal->available_owner_approvals.end(),
|
||||
"", ("id", id)("available", _proposal->available_owner_approvals) );
|
||||
}
|
||||
for( key_id_type id : o.key_approvals_to_add )
|
||||
if( (d.get_node_properties().skip_flags & database::skip_authority_check) == 0 )
|
||||
{
|
||||
FC_ASSERT( trx_state->signed_by(id) || trx_state->_skip_authority_check );
|
||||
}
|
||||
for( key_id_type id : o.key_approvals_to_remove )
|
||||
{
|
||||
FC_ASSERT( trx_state->signed_by(id) || trx_state->_skip_authority_check );
|
||||
for( key_id_type id : o.key_approvals_to_add )
|
||||
{
|
||||
FC_ASSERT( trx_state->signed_by(id) );
|
||||
}
|
||||
for( key_id_type id : o.key_approvals_to_remove )
|
||||
{
|
||||
FC_ASSERT( trx_state->signed_by(id) );
|
||||
}
|
||||
}
|
||||
|
||||
return void_result();
|
||||
|
|
|
|||
|
|
@ -25,7 +25,9 @@
|
|||
namespace graphene { namespace chain {
|
||||
bool transaction_evaluation_state::check_authority( const account_object& account, authority::classification auth_class, int depth )
|
||||
{
|
||||
if( _skip_authority_check || approved_by.find(make_pair(account.id, auth_class)) != approved_by.end() )
|
||||
if( (!_is_proposed_trx) && (_db->get_node_properties().skip_flags & database::skip_authority_check) )
|
||||
return true;
|
||||
if( approved_by.find(make_pair(account.id, auth_class)) != approved_by.end() )
|
||||
return true;
|
||||
|
||||
FC_ASSERT( account.id.instance() != 0 || _is_proposed_trx );
|
||||
|
|
|
|||
|
|
@ -1,224 +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/db/level_map.hpp>
|
||||
#include <fc/thread/thread.hpp>
|
||||
#include <map>
|
||||
|
||||
namespace graphene { namespace db {
|
||||
|
||||
template<typename Key, typename Value, class CacheType = std::map<Key,Value>>
|
||||
class cached_level_map
|
||||
{
|
||||
public:
|
||||
void open( const fc::path& dir, bool create = true, size_t leveldb_cache_size = 0, bool write_through = true, bool sync_on_write = false )
|
||||
{ try {
|
||||
_db.open( dir, create, leveldb_cache_size );
|
||||
for( auto itr = _db.begin(); itr.valid(); ++itr )
|
||||
_cache.emplace_hint( _cache.end(), itr.key(), itr.value() );
|
||||
_write_through = write_through;
|
||||
_sync_on_write = sync_on_write;
|
||||
} FC_CAPTURE_AND_RETHROW( (dir)(create)(leveldb_cache_size)(write_through)(sync_on_write) ) }
|
||||
|
||||
void close()
|
||||
{ try {
|
||||
if( _db.is_open() ) flush();
|
||||
_db.close();
|
||||
_cache.clear();
|
||||
_dirty_store.clear();
|
||||
_dirty_remove.clear();
|
||||
} FC_CAPTURE_AND_RETHROW() }
|
||||
|
||||
void set_write_through( bool write_through )
|
||||
{ try {
|
||||
if( write_through == _write_through )
|
||||
return;
|
||||
|
||||
if( write_through )
|
||||
flush();
|
||||
|
||||
_write_through = write_through;
|
||||
} FC_CAPTURE_AND_RETHROW( (write_through) ) }
|
||||
|
||||
void flush()
|
||||
{ try {
|
||||
typename level_map<Key, Value>::write_batch batch = _db.create_batch( _sync_on_write );
|
||||
for( const auto& key : _dirty_store )
|
||||
batch.store( key, _cache.at( key ) );
|
||||
for( const auto& key : _dirty_remove )
|
||||
batch.remove( key );
|
||||
batch.commit();
|
||||
|
||||
_dirty_store.clear();
|
||||
_dirty_remove.clear();
|
||||
} FC_CAPTURE_AND_RETHROW() }
|
||||
|
||||
fc::optional<Value> fetch_optional( const Key& key )const
|
||||
{ try {
|
||||
const auto itr = _cache.find( key );
|
||||
if( itr != _cache.end() )
|
||||
return itr->second;
|
||||
return fc::optional<Value>();
|
||||
} FC_CAPTURE_AND_RETHROW( (key) ) }
|
||||
|
||||
Value fetch( const Key& key )const
|
||||
{ try {
|
||||
const auto itr = _cache.find( key );
|
||||
if( itr != _cache.end() )
|
||||
return itr->second;
|
||||
FC_CAPTURE_AND_THROW( fc::key_not_found_exception, (key) );
|
||||
} FC_CAPTURE_AND_RETHROW( (key) ) }
|
||||
|
||||
void store( const Key& key, const Value& value )
|
||||
{ try {
|
||||
_cache[ key ] = value;
|
||||
if( _write_through )
|
||||
{
|
||||
_db.store( key, value, _sync_on_write );
|
||||
}
|
||||
else
|
||||
{
|
||||
_dirty_store.insert( key );
|
||||
_dirty_remove.erase( key );
|
||||
}
|
||||
} FC_CAPTURE_AND_RETHROW( (key)(value) ) }
|
||||
|
||||
void remove( const Key& key )
|
||||
{ try {
|
||||
_cache.erase( key );
|
||||
if( _write_through )
|
||||
{
|
||||
_db.remove( key, _sync_on_write );
|
||||
}
|
||||
else
|
||||
{
|
||||
_dirty_store.erase( key );
|
||||
_dirty_remove.insert( key );
|
||||
}
|
||||
} FC_CAPTURE_AND_RETHROW( (key) ) }
|
||||
|
||||
size_t size()const
|
||||
{ try {
|
||||
return _cache.size();
|
||||
} FC_CAPTURE_AND_RETHROW() }
|
||||
|
||||
bool last( Key& key )const
|
||||
{ try {
|
||||
const auto ritr = _cache.crbegin();
|
||||
if( ritr != _cache.crend() )
|
||||
{
|
||||
key = ritr->first;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} FC_CAPTURE_AND_RETHROW( (key) ) }
|
||||
|
||||
bool last( Key& key, Value& value )
|
||||
{ try {
|
||||
const auto ritr = _cache.crbegin();
|
||||
if( ritr != _cache.crend() )
|
||||
{
|
||||
key = ritr->first;
|
||||
value = ritr->second;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} FC_CAPTURE_AND_RETHROW( (key)(value) ) }
|
||||
|
||||
class iterator
|
||||
{
|
||||
public:
|
||||
iterator(){}
|
||||
bool valid()const { return _it != _end; }
|
||||
|
||||
Key key()const { return _it->first; }
|
||||
Value value()const { return _it->second; }
|
||||
|
||||
iterator& operator++() { ++_it; return *this; }
|
||||
iterator operator++(int) {
|
||||
auto backup = *this;
|
||||
++_it;
|
||||
return backup;
|
||||
}
|
||||
|
||||
iterator& operator--()
|
||||
{
|
||||
if( _it == _begin )
|
||||
_it = _end;
|
||||
else
|
||||
--_it;
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator operator--(int) {
|
||||
auto backup = *this;
|
||||
operator--();
|
||||
return backup;
|
||||
}
|
||||
|
||||
void reset() { _it = _end; }
|
||||
|
||||
protected:
|
||||
friend class cached_level_map;
|
||||
iterator( typename CacheType::const_iterator it, typename CacheType::const_iterator begin, typename CacheType::const_iterator end )
|
||||
:_it(it),_begin(begin),_end(end)
|
||||
{ }
|
||||
|
||||
typename CacheType::const_iterator _it;
|
||||
typename CacheType::const_iterator _begin;
|
||||
typename CacheType::const_iterator _end;
|
||||
};
|
||||
|
||||
iterator begin()const
|
||||
{
|
||||
return iterator( _cache.begin(), _cache.begin(), _cache.end() );
|
||||
}
|
||||
|
||||
iterator last()const
|
||||
{
|
||||
if( _cache.empty() )
|
||||
return iterator( _cache.end(), _cache.begin(), _cache.end() );
|
||||
return iterator( --_cache.end(), _cache.begin(), _cache.end() );
|
||||
}
|
||||
|
||||
iterator find( const Key& key )const
|
||||
{
|
||||
return iterator( _cache.find(key), _cache.begin(), _cache.end() );
|
||||
}
|
||||
|
||||
iterator lower_bound( const Key& key )const
|
||||
{
|
||||
return iterator( _cache.lower_bound(key), _cache.begin(), _cache.end() );
|
||||
}
|
||||
|
||||
// TODO: Iterate over cache instead
|
||||
void export_to_json( const fc::path& path )const
|
||||
{ try {
|
||||
_db.export_to_json( path );
|
||||
} FC_CAPTURE_AND_RETHROW( (path) ) }
|
||||
|
||||
private:
|
||||
level_map<Key, Value> _db;
|
||||
CacheType _cache;
|
||||
std::set<Key> _dirty_store;
|
||||
std::set<Key> _dirty_remove;
|
||||
bool _write_through = true;
|
||||
bool _sync_on_write = false;
|
||||
};
|
||||
|
||||
} }
|
||||
|
|
@ -1,143 +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/db/level_map.hpp>
|
||||
|
||||
namespace graphene { namespace db {
|
||||
|
||||
template<typename K, typename V>
|
||||
class fast_level_map
|
||||
{
|
||||
level_map<K, V> _ldb;
|
||||
fc::optional<fc::path> _ldb_path;
|
||||
bool _ldb_enabled = true;
|
||||
|
||||
std::unordered_map<K, V> _cache;
|
||||
|
||||
public:
|
||||
|
||||
~fast_level_map()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void open( const fc::path& path )
|
||||
{ try {
|
||||
FC_ASSERT( !_ldb_path.valid() );
|
||||
_ldb_path = path;
|
||||
_ldb.open( *_ldb_path );
|
||||
_cache.reserve( _ldb.size() );
|
||||
for( auto iter = _ldb.begin(); iter.valid(); ++iter )
|
||||
_cache.emplace( iter.key(), iter.value() );
|
||||
} FC_CAPTURE_AND_RETHROW( (path) ) }
|
||||
|
||||
void close()
|
||||
{ try {
|
||||
if( _ldb_path.valid() )
|
||||
{
|
||||
if( !_ldb_enabled ) toggle_leveldb( true );
|
||||
_ldb.close();
|
||||
_ldb_path = fc::optional<fc::path>();
|
||||
}
|
||||
_cache.clear();
|
||||
} FC_CAPTURE_AND_RETHROW() }
|
||||
|
||||
void toggle_leveldb( const bool enabled )
|
||||
{ try {
|
||||
FC_ASSERT( _ldb_path.valid() );
|
||||
if( enabled == _ldb_enabled )
|
||||
return;
|
||||
|
||||
if( enabled )
|
||||
{
|
||||
_ldb.open( *_ldb_path );
|
||||
auto batch = _ldb.create_batch();
|
||||
for( const auto& item : _cache )
|
||||
batch.store( item.first, item.second );
|
||||
batch.commit();
|
||||
}
|
||||
else
|
||||
{
|
||||
_ldb.close();
|
||||
fc::remove_all( *_ldb_path );
|
||||
}
|
||||
|
||||
_ldb_enabled = enabled;
|
||||
} FC_CAPTURE_AND_RETHROW( (enabled) ) }
|
||||
|
||||
void store( const K& key, const V& value )
|
||||
{ try {
|
||||
_cache[ key ] = value;
|
||||
if( _ldb_enabled )
|
||||
_ldb.store( key, value );
|
||||
} FC_CAPTURE_AND_RETHROW( (key)(value) ) }
|
||||
|
||||
void remove( const K& key )
|
||||
{ try {
|
||||
_cache.erase( key );
|
||||
if( _ldb_enabled )
|
||||
_ldb.remove( key );
|
||||
} FC_CAPTURE_AND_RETHROW( (key) ) }
|
||||
|
||||
auto empty()const -> decltype( _cache.empty() )
|
||||
{
|
||||
return _cache.empty();
|
||||
}
|
||||
|
||||
auto size()const -> decltype( _cache.size() )
|
||||
{
|
||||
return _cache.size();
|
||||
}
|
||||
|
||||
auto count( const K& key )const -> decltype( _cache.count( key ) )
|
||||
{
|
||||
return _cache.count( key );
|
||||
}
|
||||
|
||||
auto unordered_begin()const -> decltype( _cache.cbegin() )
|
||||
{
|
||||
return _cache.cbegin();
|
||||
}
|
||||
|
||||
auto unordered_end()const -> decltype( _cache.cend() )
|
||||
{
|
||||
return _cache.cend();
|
||||
}
|
||||
|
||||
auto unordered_find( const K& key )const -> decltype( _cache.find( key ) )
|
||||
{
|
||||
return _cache.find( key );
|
||||
}
|
||||
|
||||
auto ordered_first()const -> decltype( _ldb.begin() )
|
||||
{ try {
|
||||
return _ldb.begin();
|
||||
} FC_CAPTURE_AND_RETHROW() }
|
||||
|
||||
auto ordered_last()const -> decltype( _ldb.last() )
|
||||
{ try {
|
||||
return _ldb.last();
|
||||
} FC_CAPTURE_AND_RETHROW() }
|
||||
|
||||
auto ordered_lower_bound( const K& key )const -> decltype( _ldb.lower_bound( key ) )
|
||||
{ try {
|
||||
return _ldb.lower_bound( key );
|
||||
} FC_CAPTURE_AND_RETHROW( (key) ) }
|
||||
};
|
||||
|
||||
} } // graphene::db
|
||||
|
|
@ -1,132 +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 <leveldb/db.h>
|
||||
#include <leveldb/comparator.h>
|
||||
#include <fc/reflect/reflect.hpp>
|
||||
#include <fc/io/raw.hpp>
|
||||
#include <fc/exception/exception.hpp>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
|
||||
namespace fc { class path; }
|
||||
|
||||
/**
|
||||
* This code has no graphene dependencies, and it
|
||||
* could be moved to fc, if fc ever adds a leveldb dependency
|
||||
*
|
||||
* This code enables legacy databases files created by older programs to
|
||||
* be upgraded to the current database formats. Whenever a database is first opened,
|
||||
* this code checks if the database is stored in an old format and looks for an
|
||||
* upgrade function to upgrade it to the current format. If found, the objects
|
||||
* in the database will be immediately upgraded to the current format.
|
||||
*
|
||||
* Upgrades are performed by executing a series of chained copy constructors
|
||||
* from the legacy object format to the current object format. This means
|
||||
* that only one new copy constructor typically needs to be written to support
|
||||
* upgrading any previous version of the object when an object type is modified.
|
||||
*
|
||||
* - Database versioning is only supported for changes to database value types
|
||||
* (databases with modified key types cannot currently be upgraded).
|
||||
* - The database versioning code requires that fc::get_typename is defined for
|
||||
* all value types which are to be versioned.
|
||||
*/
|
||||
|
||||
/*
|
||||
Below is a simple example of how client code needs to be written to support
|
||||
database versioning. Originally, a database stored values of record0, and
|
||||
record was typedef'd to be record0. A new type record1 was created to add
|
||||
"new_field" to record type, and record was typedef'd to record1. The typedef
|
||||
is used to minimize required changes to the client code that references
|
||||
record objects.
|
||||
|
||||
@code
|
||||
|
||||
struct record0
|
||||
{
|
||||
record0() : points(0) {}
|
||||
double points;
|
||||
};
|
||||
|
||||
FC_REFLECT( record0, (points) )
|
||||
REGISTER_DB_OBJECT(record,0) //This creates an upgrade function for record0 databases
|
||||
|
||||
struct record1
|
||||
{
|
||||
record1() : points(0), new_field("EMPTY") {}
|
||||
|
||||
record1(const record0& r0) //convert from record0 to record1 for legacy files
|
||||
{
|
||||
key = r0.key;
|
||||
new_field = "EMPTY";
|
||||
}
|
||||
std::string new_field;
|
||||
double points;
|
||||
};
|
||||
FC_REFLECT( record1, (points)(new_field) )
|
||||
|
||||
typedef record1 record; //current databases store record1 objects
|
||||
|
||||
@endcode
|
||||
*/
|
||||
|
||||
namespace graphene { namespace db {
|
||||
|
||||
typedef std::function<void(leveldb::DB*)> upgrade_db_function;
|
||||
|
||||
class upgrade_db_mapper
|
||||
{
|
||||
public:
|
||||
static upgrade_db_mapper& instance();
|
||||
int32_t add_type( const std::string& type_name, const upgrade_db_function& function);
|
||||
|
||||
std::map<std::string,upgrade_db_function> _upgrade_db_function_registry;
|
||||
};
|
||||
|
||||
#define REGISTER_DB_OBJECT(TYPE,VERSIONNUM) \
|
||||
void UpgradeDb ## TYPE ## VERSIONNUM(leveldb::DB* dbase) \
|
||||
{ \
|
||||
std::unique_ptr<leveldb::Iterator> dbase_itr( dbase->NewIterator(leveldb::ReadOptions()) ); \
|
||||
dbase_itr->SeekToFirst(); \
|
||||
if( dbase_itr->status().IsNotFound() ) /*if empty database, do nothing*/ \
|
||||
return; \
|
||||
if( !dbase_itr->status().ok() ) \
|
||||
FC_THROW_EXCEPTION( exception, "database error: ${msg}", ("msg", dbase_itr->status().ToString() ) ); \
|
||||
while( dbase_itr->Valid() ) /* convert dbase objects from legacy TypeVersionNum to current Type */ \
|
||||
{ \
|
||||
TYPE ## VERSIONNUM old_value; /*load old record type*/ \
|
||||
fc::datastream<const char*> dstream( dbase_itr->value().data(), dbase_itr->value().size() ); \
|
||||
fc::raw::unpack( dstream, old_value ); \
|
||||
TYPE new_value(old_value); /*convert to new record type*/ \
|
||||
leveldb::Slice key_slice = dbase_itr->key(); \
|
||||
auto vec = fc::raw::pack(new_value); \
|
||||
leveldb::Slice value_slice( vec.data(), vec.size() ); \
|
||||
auto status = dbase->Put( leveldb::WriteOptions(), key_slice, value_slice ); \
|
||||
if( !status.ok() ) \
|
||||
{ \
|
||||
FC_THROW_EXCEPTION( exception, "database error: ${msg}", ("msg", status.ToString() ) ); \
|
||||
} \
|
||||
dbase_itr->Next(); \
|
||||
} /*while*/ \
|
||||
} \
|
||||
static int dummyResult ## TYPE ## VERSIONNUM = \
|
||||
upgrade_db_mapper::instance()->add_type(fc::get_typename<TYPE ## VERSIONNUM>::name(), UpgradeDb ## TYPE ## VERSIONNUM);
|
||||
|
||||
void try_upgrade_db( const fc::path& dir, leveldb::DB* dbase, const char* record_type, size_t record_type_size );
|
||||
|
||||
} } // namespace db
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <BaseTsd.h>
|
||||
typedef SSIZE_T ssize_t;
|
||||
|
||||
#include "../../../leveldb/include/leveldb/db.h"
|
||||
|
|
@ -1 +0,0 @@
|
|||
/* empty unistd to allow leveldb to compile with msvc which is missing this file */
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
This directory contains the files needed to make the stock LevelDB distribution
|
||||
from https://github.com/bitcoin/leveldb.git compile on Windows with Visual C++.
|
||||
Add this 'include' directory to yur include path before the regular includes
|
||||
only when building leveldb (it isn't needed when compiling code that uses
|
||||
leveldb).
|
||||
|
|
@ -17,6 +17,7 @@
|
|||
*/
|
||||
#include <graphene/witness/witness.hpp>
|
||||
|
||||
#include <graphene/chain/database.hpp>
|
||||
#include <graphene/chain/witness_object.hpp>
|
||||
#include <graphene/time/time.hpp>
|
||||
|
||||
|
|
@ -176,7 +177,8 @@ void witness_plugin::block_production_loop()
|
|||
auto block = db.generate_block(
|
||||
scheduled_time,
|
||||
scheduled_witness,
|
||||
_private_keys[ scheduled_key ]
|
||||
_private_keys[ scheduled_key ],
|
||||
graphene::chain::database::skip_nothing
|
||||
);
|
||||
ilog("Generated block #${n} with timestamp ${t} at time ${c}",
|
||||
("n", block.block_num())("t", block.timestamp)("c", now));
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE( two_node_network )
|
|||
fc::temp_directory app_dir;
|
||||
fc::temp_directory app2_dir;
|
||||
fc::temp_file genesis_json;
|
||||
fc::json::save_to_file(genesis_allocation(), genesis_json.path());
|
||||
fc::json::save_to_file(genesis_state_type(), genesis_json.path());
|
||||
|
||||
fc::time_point_sec now( GRAPHENE_GENESIS_TIMESTAMP );
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ BOOST_AUTO_TEST_CASE( two_node_network )
|
|||
|
||||
now += GRAPHENE_DEFAULT_BLOCK_INTERVAL;
|
||||
app2.p2p_node()->broadcast(graphene::net::block_message(db2->generate_block(
|
||||
now, db2->get_scheduled_witness( 1 ).first, genesis_key )));
|
||||
now, db2->get_scheduled_witness( 1 ).first, genesis_key, database::skip_nothing )));
|
||||
|
||||
fc::usleep(fc::milliseconds(500));
|
||||
BOOST_CHECK_EQUAL(app1.p2p_node()->get_connection_count(), 1);
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ BOOST_AUTO_TEST_CASE( operation_sanity_check )
|
|||
BOOST_AUTO_TEST_CASE( genesis_and_persistence_bench )
|
||||
{
|
||||
try {
|
||||
genesis_allocation allocation;
|
||||
genesis_state_type genesis_state;
|
||||
|
||||
#ifdef NDEBUG
|
||||
ilog("Running in release mode.");
|
||||
|
|
@ -57,14 +57,15 @@ BOOST_AUTO_TEST_CASE( genesis_and_persistence_bench )
|
|||
#endif
|
||||
|
||||
for( int i = 0; i < account_count; ++i )
|
||||
allocation.emplace_back(public_key_type(fc::ecc::private_key::regenerate(fc::digest(i)).get_public_key()),
|
||||
GRAPHENE_INITIAL_SUPPLY / account_count);
|
||||
genesis_state.allocation_targets.emplace_back("target"+fc::to_string(i),
|
||||
public_key_type(fc::ecc::private_key::regenerate(fc::digest(i)).get_public_key()),
|
||||
GRAPHENE_INITIAL_SUPPLY / account_count);
|
||||
|
||||
fc::temp_directory data_dir(fc::current_path());
|
||||
|
||||
{
|
||||
database db;
|
||||
db.open(data_dir.path(), allocation);
|
||||
db.open(data_dir.path(), genesis_state);
|
||||
|
||||
for( int i = 11; i < account_count + 11; ++i)
|
||||
BOOST_CHECK(db.get_balance(account_id_type(i), asset_id_type()).amount == GRAPHENE_INITIAL_SUPPLY / account_count);
|
||||
|
|
@ -110,7 +111,7 @@ BOOST_AUTO_TEST_CASE( genesis_and_persistence_bench )
|
|||
|
||||
auto start_time = fc::time_point::now();
|
||||
wlog( "about to start reindex..." );
|
||||
db.reindex(data_dir.path(), allocation);
|
||||
db.reindex(data_dir.path(), genesis_state);
|
||||
ilog("Replayed database in ${t} milliseconds.", ("t", (fc::time_point::now() - start_time).count() / 1000));
|
||||
|
||||
for( int i = 0; i < blocks_to_produce; ++i )
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ database_fixture::~database_fixture()
|
|||
verify_account_history_plugin_index();
|
||||
}
|
||||
|
||||
BOOST_CHECK( db.get_node_properties().skip_flags == database::skip_nothing );
|
||||
|
||||
if( data_dir )
|
||||
db.close();
|
||||
return;
|
||||
|
|
@ -92,11 +94,6 @@ string database_fixture::generate_anon_acct_name()
|
|||
return "anon-acct-x" + std::to_string( anon_acct_count++ );
|
||||
}
|
||||
|
||||
void database_fixture::_push_transaction( const signed_transaction& tx, uint32_t skip_flags, const char* file, int line )
|
||||
{
|
||||
db.push_transaction( tx, skip_flags );
|
||||
}
|
||||
|
||||
void database_fixture::verify_asset_supplies( )const
|
||||
{
|
||||
//wlog("*** Begin asset supply verification ***");
|
||||
|
|
@ -268,8 +265,9 @@ void database_fixture::generate_blocks(fc::time_point_sec timestamp, bool miss_i
|
|||
{
|
||||
if( miss_intermediate_blocks )
|
||||
{
|
||||
generate_block();
|
||||
auto slots_to_miss = db.get_slot_at_time(timestamp) - 1;
|
||||
assert(slots_to_miss > 0);
|
||||
if( slots_to_miss <= 0 ) return;
|
||||
generate_block(~0, generate_private_key("genesis"), slots_to_miss);
|
||||
return;
|
||||
}
|
||||
|
|
@ -835,4 +833,18 @@ int64_t database_fixture::get_balance( const account_object& account, const asse
|
|||
return db.get_balance(account.get_id(), a.get_id()).amount.value;
|
||||
}
|
||||
|
||||
namespace test {
|
||||
|
||||
bool _push_block( database& db, const signed_block& b, uint32_t skip_flags /* = 0 */ )
|
||||
{
|
||||
return db.push_block( b, skip_flags);
|
||||
}
|
||||
|
||||
processed_transaction _push_transaction( database& db, const signed_transaction& tx, uint32_t skip_flags /* = 0 */ )
|
||||
{
|
||||
return db.push_transaction( tx, skip_flags );
|
||||
}
|
||||
|
||||
} // graphene::chain::test
|
||||
|
||||
} } // graphene::chain
|
||||
|
|
|
|||
|
|
@ -24,6 +24,12 @@
|
|||
|
||||
using namespace graphene::db;
|
||||
|
||||
#define PUSH_TX \
|
||||
graphene::chain::test::_push_transaction
|
||||
|
||||
#define PUSH_BLOCK \
|
||||
graphene::chain::test::_push_block
|
||||
|
||||
// See below
|
||||
#define REQUIRE_OP_VALIDATION_SUCCESS( op, field, value ) \
|
||||
{ \
|
||||
|
|
@ -65,9 +71,6 @@ using namespace graphene::db;
|
|||
/// i.e. This allows a test on update_account to begin with the database at the end state of create_account.
|
||||
#define INVOKE(test) ((struct test*)this)->test_method(); trx.clear()
|
||||
|
||||
#define PUSH_TX( tx, skip_flags ) \
|
||||
_push_transaction( tx, skip_flags, __FILE__, __LINE__ )
|
||||
|
||||
#define PREP_ACTOR(name) \
|
||||
fc::ecc::private_key name ## _private_key = generate_private_key(BOOST_PP_STRINGIZE(name)); \
|
||||
key_id_type name ## _key_id = register_key(name ## _private_key.get_public_key()).get_id();
|
||||
|
|
@ -111,7 +114,6 @@ struct database_fixture {
|
|||
|
||||
static fc::ecc::private_key generate_private_key(string seed);
|
||||
string generate_anon_acct_name();
|
||||
void _push_transaction( const signed_transaction& tx, uint32_t skip_flags, const char* file, int line );
|
||||
void verify_asset_supplies( )const;
|
||||
void verify_account_history_plugin_index( )const;
|
||||
void open_database();
|
||||
|
|
@ -129,7 +131,7 @@ struct database_fixture {
|
|||
* @brief Generates blocks until the head block time matches or exceeds timestamp
|
||||
* @param timestamp target time to generate blocks until
|
||||
*/
|
||||
void generate_blocks(fc::time_point_sec timestamp, bool miss_intermediate_blocks = false);
|
||||
void generate_blocks(fc::time_point_sec timestamp, bool miss_intermediate_blocks = true);
|
||||
|
||||
account_create_operation make_account(
|
||||
const std::string& name = "nathan",
|
||||
|
|
@ -211,4 +213,9 @@ struct database_fixture {
|
|||
int64_t get_balance( const account_object& account, const asset_object& a )const;
|
||||
};
|
||||
|
||||
namespace test {
|
||||
bool _push_block( database& db, const signed_block& b, uint32_t skip_flags = 0 );
|
||||
processed_transaction _push_transaction( database& db, const signed_transaction& tx, uint32_t skip_flags = 0 );
|
||||
}
|
||||
|
||||
} }
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ BOOST_AUTO_TEST_CASE( simple_single_signature )
|
|||
transfer_operation op = {asset(),nathan.id, account_id_type(), core.amount(500)};
|
||||
trx.operations.push_back(op);
|
||||
sign(trx, key.id, nathan_key);
|
||||
db.push_transaction(trx, database::skip_transaction_dupe_check);
|
||||
PUSH_TX( db, trx, database::skip_transaction_dupe_check );
|
||||
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan, core), old_balance - 500);
|
||||
} catch (fc::exception& e) {
|
||||
|
|
@ -80,7 +80,7 @@ BOOST_AUTO_TEST_CASE( any_two_of_three )
|
|||
op.owner = *op.active;
|
||||
trx.operations.push_back(op);
|
||||
sign(trx, key1.id,nathan_key1);
|
||||
db.push_transaction(trx, database::skip_transaction_dupe_check);
|
||||
PUSH_TX( db, trx, database::skip_transaction_dupe_check );
|
||||
trx.operations.clear();
|
||||
trx.signatures.clear();
|
||||
} FC_CAPTURE_AND_RETHROW ((nathan.active)(key1))
|
||||
|
|
@ -88,27 +88,27 @@ BOOST_AUTO_TEST_CASE( any_two_of_three )
|
|||
transfer_operation op = {asset(), nathan.id, account_id_type(), core.amount(500)};
|
||||
trx.operations.push_back(op);
|
||||
sign(trx, key1.id,nathan_key1);
|
||||
BOOST_CHECK_THROW(db.push_transaction(trx, database::skip_transaction_dupe_check), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db, trx, database::skip_transaction_dupe_check ), fc::exception);
|
||||
sign(trx, key2.id,nathan_key2);
|
||||
db.push_transaction(trx, database::skip_transaction_dupe_check);
|
||||
PUSH_TX( db, trx, database::skip_transaction_dupe_check );
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan, core), old_balance - 500);
|
||||
|
||||
trx.signatures.clear();
|
||||
sign(trx, key2.id,nathan_key2);
|
||||
sign(trx, key3.id,nathan_key3);
|
||||
db.push_transaction(trx, database::skip_transaction_dupe_check);
|
||||
PUSH_TX( db, trx, database::skip_transaction_dupe_check );
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan, core), old_balance - 1000);
|
||||
|
||||
trx.signatures.clear();
|
||||
sign(trx, key1.id,nathan_key1);
|
||||
sign(trx, key3.id,nathan_key3);
|
||||
db.push_transaction(trx, database::skip_transaction_dupe_check);
|
||||
PUSH_TX( db, trx, database::skip_transaction_dupe_check );
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan, core), old_balance - 1500);
|
||||
|
||||
trx.signatures.clear();
|
||||
//sign(trx, fc::ecc::private_key::generate());
|
||||
sign(trx, key3.id,nathan_key3);
|
||||
BOOST_CHECK_THROW(db.push_transaction(trx, database::skip_transaction_dupe_check), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db, trx, database::skip_transaction_dupe_check ), fc::exception);
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan, core), old_balance - 1500);
|
||||
} catch (fc::exception& e) {
|
||||
edump((e.to_detail_string()));
|
||||
|
|
@ -133,7 +133,7 @@ BOOST_AUTO_TEST_CASE( recursive_accounts )
|
|||
make_child_op.owner = authority(2, account_id_type(parent1.id), 1, account_id_type(parent2.id), 1);
|
||||
make_child_op.active = authority(2, account_id_type(parent1.id), 1, account_id_type(parent2.id), 1);
|
||||
trx.operations.push_back(make_child_op);
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
trx.operations.clear();
|
||||
}
|
||||
|
||||
|
|
@ -142,17 +142,17 @@ BOOST_AUTO_TEST_CASE( recursive_accounts )
|
|||
|
||||
transfer_operation op = {asset(), child.id, account_id_type(), core.amount(500)};
|
||||
trx.operations.push_back(op);
|
||||
BOOST_CHECK_THROW(db.push_transaction(trx, database::skip_transaction_dupe_check), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db, trx, database::skip_transaction_dupe_check ), fc::exception);
|
||||
sign(trx, key1.id,parent1_key);
|
||||
sign(trx, key1.id,parent1_key);
|
||||
sign(trx, key1.id,parent1_key);
|
||||
sign(trx, key1.id,parent1_key);
|
||||
BOOST_CHECK_THROW(db.push_transaction(trx, database::skip_transaction_dupe_check), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db, trx, database::skip_transaction_dupe_check ), fc::exception);
|
||||
trx.signatures.clear();
|
||||
sign(trx, key2.id,parent2_key);
|
||||
BOOST_CHECK_THROW(db.push_transaction(trx, database::skip_transaction_dupe_check), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db, trx, database::skip_transaction_dupe_check ), fc::exception);
|
||||
sign(trx, key1.id,parent1_key);
|
||||
db.push_transaction(trx, database::skip_transaction_dupe_check);
|
||||
PUSH_TX( db, trx, database::skip_transaction_dupe_check );
|
||||
BOOST_CHECK_EQUAL(get_balance(child, core), old_balance - 500);
|
||||
trx.operations.clear();
|
||||
trx.signatures.clear();
|
||||
|
|
@ -167,7 +167,7 @@ BOOST_AUTO_TEST_CASE( recursive_accounts )
|
|||
trx.operations.push_back(op);
|
||||
sign(trx, key1.id,parent1_key);
|
||||
sign(trx, key2.id,parent2_key);
|
||||
db.push_transaction(trx, database::skip_transaction_dupe_check);
|
||||
PUSH_TX( db, trx, database::skip_transaction_dupe_check );
|
||||
BOOST_REQUIRE_EQUAL(child.active.auths.size(), 3);
|
||||
trx.operations.clear();
|
||||
trx.signatures.clear();
|
||||
|
|
@ -175,18 +175,18 @@ BOOST_AUTO_TEST_CASE( recursive_accounts )
|
|||
|
||||
op = {asset(),child.id, account_id_type(), core.amount(500)};
|
||||
trx.operations.push_back(op);
|
||||
BOOST_CHECK_THROW(db.push_transaction(trx, database::skip_transaction_dupe_check), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db, trx, database::skip_transaction_dupe_check ), fc::exception);
|
||||
sign(trx, key1.id,parent1_key);
|
||||
BOOST_CHECK_THROW(db.push_transaction(trx, database::skip_transaction_dupe_check), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db, trx, database::skip_transaction_dupe_check ), fc::exception);
|
||||
trx.signatures.clear();
|
||||
sign(trx, key2.id,parent2_key);
|
||||
BOOST_CHECK_THROW(db.push_transaction(trx, database::skip_transaction_dupe_check), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db, trx, database::skip_transaction_dupe_check ), fc::exception);
|
||||
sign(trx, key1.id, parent1_key);
|
||||
db.push_transaction(trx, database::skip_transaction_dupe_check);
|
||||
PUSH_TX( db, trx, database::skip_transaction_dupe_check );
|
||||
BOOST_CHECK_EQUAL(get_balance(child, core), old_balance - 1000);
|
||||
trx.signatures.clear();
|
||||
sign(trx, child_key_obj.id, child_key);
|
||||
db.push_transaction(trx, database::skip_transaction_dupe_check);
|
||||
PUSH_TX( db, trx, database::skip_transaction_dupe_check );
|
||||
BOOST_CHECK_EQUAL(get_balance(child, core), old_balance - 1500);
|
||||
trx.operations.clear();
|
||||
trx.signatures.clear();
|
||||
|
|
@ -204,7 +204,7 @@ BOOST_AUTO_TEST_CASE( recursive_accounts )
|
|||
op.active = authority(1, grandparent_key_obj.get_id(), 1);
|
||||
op.owner = *op.active;
|
||||
trx.operations.push_back(op);
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
trx.operations.clear();
|
||||
trx.signatures.clear();
|
||||
}
|
||||
|
|
@ -212,9 +212,9 @@ BOOST_AUTO_TEST_CASE( recursive_accounts )
|
|||
trx.operations.push_back(op);
|
||||
sign(trx, key1.id, parent1_key);
|
||||
sign(trx, key2.id, parent2_key);
|
||||
BOOST_CHECK_THROW(db.push_transaction(trx, database::skip_transaction_dupe_check), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db, trx, database::skip_transaction_dupe_check ), fc::exception);
|
||||
sign(trx, grandparent_key_obj.id, grandparent_key);
|
||||
db.push_transaction(trx, database::skip_transaction_dupe_check);
|
||||
PUSH_TX( db, trx, database::skip_transaction_dupe_check );
|
||||
BOOST_CHECK_EQUAL(get_balance(child, core), old_balance - 2000);
|
||||
trx.operations.clear();
|
||||
trx.signatures.clear();
|
||||
|
|
@ -225,7 +225,7 @@ BOOST_AUTO_TEST_CASE( recursive_accounts )
|
|||
op.active = authority(1, account_id_type(), 1);
|
||||
op.owner = *op.active;
|
||||
trx.operations.push_back(op);
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
trx.operations.clear();
|
||||
trx.signatures.clear();
|
||||
}
|
||||
|
|
@ -235,9 +235,9 @@ BOOST_AUTO_TEST_CASE( recursive_accounts )
|
|||
sign(trx, grandparent_key_obj.id,grandparent_key);
|
||||
sign(trx, key_id_type(), generate_private_key("genesis"));
|
||||
//Fails due to recursion depth.
|
||||
BOOST_CHECK_THROW(db.push_transaction(trx, database::skip_transaction_dupe_check), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db, trx, database::skip_transaction_dupe_check ), fc::exception);
|
||||
sign(trx, child_key_obj.id, child_key);
|
||||
db.push_transaction(trx, database::skip_transaction_dupe_check);
|
||||
PUSH_TX( db, trx, database::skip_transaction_dupe_check );
|
||||
BOOST_CHECK_EQUAL(get_balance(child, core), old_balance - 2500);
|
||||
trx.operations.clear();
|
||||
trx.signatures.clear();
|
||||
|
|
@ -248,7 +248,7 @@ BOOST_AUTO_TEST_CASE( recursive_accounts )
|
|||
op.active = authority(1, account_id_type(child.id), 1);
|
||||
op.owner = *op.active;
|
||||
trx.operations.push_back(op);
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
trx.operations.clear();
|
||||
trx.signatures.clear();
|
||||
}
|
||||
|
|
@ -256,7 +256,7 @@ BOOST_AUTO_TEST_CASE( recursive_accounts )
|
|||
trx.operations.push_back(op);
|
||||
sign(trx, key2.id, parent2_key);
|
||||
//Fails due to recursion depth.
|
||||
BOOST_CHECK_THROW(db.push_transaction(trx, database::skip_transaction_dupe_check), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db, trx, database::skip_transaction_dupe_check ), fc::exception);
|
||||
} catch (fc::exception& e) {
|
||||
edump((e.to_detail_string()));
|
||||
throw;
|
||||
|
|
@ -301,7 +301,7 @@ BOOST_AUTO_TEST_CASE( proposed_single_account )
|
|||
trx.operations.push_back(op);
|
||||
trx.set_expiration(db.head_block_id());
|
||||
sign(trx, this->genesis_key, genesis_key);
|
||||
const proposal_object& proposal = db.get<proposal_object>(db.push_transaction(trx).operation_results.front().get<object_id_type>());
|
||||
const proposal_object& proposal = db.get<proposal_object>(PUSH_TX( db, trx ).operation_results.front().get<object_id_type>());
|
||||
|
||||
BOOST_CHECK_EQUAL(proposal.required_active_approvals.size(), 1);
|
||||
BOOST_CHECK_EQUAL(proposal.available_active_approvals.size(), 0);
|
||||
|
|
@ -312,11 +312,11 @@ BOOST_AUTO_TEST_CASE( proposed_single_account )
|
|||
trx.operations = {proposal_update_operation{account_id_type(), asset(), proposal.id,{nathan.id},flat_set<account_id_type>{},flat_set<account_id_type>{},flat_set<account_id_type>{},flat_set<key_id_type>{},flat_set<key_id_type>{}}};
|
||||
trx.sign( this->genesis_key, genesis_key );
|
||||
//Genesis may not add nathan's approval.
|
||||
BOOST_CHECK_THROW(db.push_transaction(trx), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db, trx ), fc::exception);
|
||||
trx.operations = {proposal_update_operation{account_id_type(), asset(), proposal.id,{account_id_type()},flat_set<account_id_type>{},flat_set<account_id_type>{},flat_set<account_id_type>{},flat_set<key_id_type>{},flat_set<key_id_type>{}}};
|
||||
trx.sign( key_id_type(), genesis_key );
|
||||
//Genesis has no stake in the transaction.
|
||||
BOOST_CHECK_THROW(db.push_transaction(trx), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db, trx ), fc::exception);
|
||||
|
||||
trx.signatures.clear();
|
||||
trx.operations = {proposal_update_operation{nathan.id, asset(), proposal.id,{nathan.id},flat_set<account_id_type>{},flat_set<account_id_type>{},flat_set<account_id_type>{},flat_set<key_id_type>{},flat_set<key_id_type>{}}};
|
||||
|
|
@ -326,7 +326,7 @@ BOOST_AUTO_TEST_CASE( proposed_single_account )
|
|||
//trx.signatures = {nathan_key3.sign_compact(trx.digest()), nathan_key2.sign_compact(trx.digest())};
|
||||
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan, core), nathan_start_balance.amount.value);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan, core), nathan_start_balance.amount.value - 100);
|
||||
} catch (fc::exception& e) {
|
||||
edump((e.to_detail_string()));
|
||||
|
|
@ -354,7 +354,7 @@ BOOST_AUTO_TEST_CASE( genesis_authority )
|
|||
|
||||
trx.operations.push_back(transfer_operation({asset(), account_id_type(), nathan.id, asset(100000)}));
|
||||
sign(trx, key_id_type(), genesis_key);
|
||||
BOOST_CHECK_THROW(db.push_transaction(trx), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db, trx ), fc::exception);
|
||||
|
||||
auto sign = [&] { trx.signatures.clear(); trx.sign(nathan_key_id,nathan_key); };
|
||||
|
||||
|
|
@ -366,16 +366,16 @@ BOOST_AUTO_TEST_CASE( genesis_authority )
|
|||
sign();
|
||||
|
||||
// The review period isn't set yet. Make sure it throws.
|
||||
BOOST_REQUIRE_THROW( db.push_transaction(trx), fc::exception );
|
||||
BOOST_REQUIRE_THROW( PUSH_TX( db, trx ), fc::exception );
|
||||
pop.review_period_seconds = global_params.genesis_proposal_review_period / 2;
|
||||
trx.operations.back() = pop;
|
||||
sign();
|
||||
// The review period is too short. Make sure it throws.
|
||||
BOOST_REQUIRE_THROW( db.push_transaction(trx), fc::exception );
|
||||
BOOST_REQUIRE_THROW( PUSH_TX( db, trx ), fc::exception );
|
||||
pop.review_period_seconds = global_params.genesis_proposal_review_period;
|
||||
trx.operations.back() = pop;
|
||||
sign();
|
||||
proposal_object prop = db.get<proposal_object>(db.push_transaction(trx).operation_results.front().get<object_id_type>());
|
||||
proposal_object prop = db.get<proposal_object>(PUSH_TX( db, trx ).operation_results.front().get<object_id_type>());
|
||||
BOOST_REQUIRE(db.find_object(prop.id));
|
||||
|
||||
BOOST_CHECK(prop.expiration_time == pop.expiration_time);
|
||||
|
|
@ -396,7 +396,7 @@ BOOST_AUTO_TEST_CASE( genesis_authority )
|
|||
uop.key_approvals_to_add.emplace();
|
||||
trx.operations.push_back(uop);
|
||||
trx.sign(key_id_type(), genesis_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan, asset_id_type()(db)), 0);
|
||||
BOOST_CHECK(db.get<proposal_object>(prop.id).is_authorized_to_execute(&db));
|
||||
|
||||
|
|
@ -406,7 +406,7 @@ BOOST_AUTO_TEST_CASE( genesis_authority )
|
|||
trx.operations.back() = uop;
|
||||
trx.sign(key_id_type(), genesis_key);
|
||||
// Should throw because the transaction is now in review.
|
||||
BOOST_CHECK_THROW(db.push_transaction(trx), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db, trx ), fc::exception);
|
||||
|
||||
generate_blocks(prop.expiration_time);
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan, asset_id_type()(db)), 100000);
|
||||
|
|
@ -445,7 +445,7 @@ BOOST_FIXTURE_TEST_CASE( fired_delegates, database_fixture )
|
|||
pop.proposed_ops.emplace_back(transfer_operation({asset(),account_id_type(), nathan->id, asset(100000)}));
|
||||
trx.operations.push_back(pop);
|
||||
sign(trx, key_id_type(), genesis_key);
|
||||
const proposal_object& prop = db.get<proposal_object>(db.push_transaction(trx).operation_results.front().get<object_id_type>());
|
||||
const proposal_object& prop = db.get<proposal_object>(PUSH_TX( db, trx ).operation_results.front().get<object_id_type>());
|
||||
proposal_id_type pid = prop.id;
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(&db));
|
||||
|
||||
|
|
@ -456,7 +456,7 @@ BOOST_FIXTURE_TEST_CASE( fired_delegates, database_fixture )
|
|||
uop.key_approvals_to_add.emplace();
|
||||
trx.operations.back() = uop;
|
||||
trx.sign(key_id_type(), genesis_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
BOOST_CHECK(prop.is_authorized_to_execute(&db));
|
||||
|
||||
//Time passes... the proposal is now in its review period.
|
||||
|
|
@ -468,6 +468,7 @@ BOOST_FIXTURE_TEST_CASE( fired_delegates, database_fixture )
|
|||
BOOST_CHECK(pid(db).is_authorized_to_execute(&db));
|
||||
|
||||
nathan = &get_account("nathan");
|
||||
// no money yet
|
||||
BOOST_CHECK_EQUAL(get_balance(*nathan, asset_id_type()(db)), 5000);
|
||||
|
||||
{
|
||||
|
|
@ -478,20 +479,24 @@ BOOST_FIXTURE_TEST_CASE( fired_delegates, database_fixture )
|
|||
op.new_options->votes = delegates;
|
||||
trx.operations.push_back(op);
|
||||
trx.set_expiration(db.head_block_time() + GRAPHENE_DEFAULT_MAX_TIME_UNTIL_EXPIRATION);
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
trx.operations.clear();
|
||||
}
|
||||
// still no money
|
||||
BOOST_CHECK_EQUAL(get_balance(*nathan, asset_id_type()(db)), 5000);
|
||||
|
||||
//Time passes... the set of active delegates gets updated.
|
||||
generate_blocks(maintenance_time);
|
||||
//The proposal is no longer authorized, because the active delegates got changed.
|
||||
BOOST_CHECK(!pid(db).is_authorized_to_execute(&db));
|
||||
// still no money
|
||||
BOOST_CHECK_EQUAL(get_balance(*nathan, asset_id_type()(db)), 5000);
|
||||
|
||||
//Time passes... the proposal has now expired.
|
||||
generate_blocks(pid(db).expiration_time);
|
||||
BOOST_CHECK(db.find(pid) == nullptr);
|
||||
|
||||
//Nathan didn't get any more money because the proposal was rejected.
|
||||
nathan = &get_account("nathan");
|
||||
//Nathan never got any more money because the proposal was rejected.
|
||||
BOOST_CHECK_EQUAL(get_balance(*nathan, asset_id_type()(db)), 5000);
|
||||
} FC_LOG_AND_RETHROW() }
|
||||
|
||||
|
|
@ -524,7 +529,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_two_accounts, database_fixture )
|
|||
pop.expiration_time = db.head_block_time() + fc::days(1);
|
||||
trx.operations.push_back(pop);
|
||||
trx.sign(nathan_key_obj.id,nathan_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
}
|
||||
|
||||
|
|
@ -541,7 +546,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_two_accounts, database_fixture )
|
|||
uop.fee_paying_account = nathan.get_id();
|
||||
trx.operations.push_back(uop);
|
||||
trx.sign(nathan_key_obj.id,nathan_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
|
||||
BOOST_CHECK(db.find_object(pid) != nullptr);
|
||||
|
|
@ -550,9 +555,9 @@ BOOST_FIXTURE_TEST_CASE( proposal_two_accounts, database_fixture )
|
|||
uop.active_approvals_to_add = {dan.get_id()};
|
||||
trx.operations.push_back(uop);
|
||||
trx.sign(nathan_key_obj.id,nathan_key);
|
||||
BOOST_REQUIRE_THROW(db.push_transaction(trx), fc::exception);
|
||||
BOOST_REQUIRE_THROW(PUSH_TX( db, trx ), fc::exception);
|
||||
trx.sign(dan_key_obj.id,dan_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
|
||||
BOOST_CHECK(db.find_object(pid) == nullptr);
|
||||
}
|
||||
|
|
@ -588,7 +593,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_delete, database_fixture )
|
|||
pop.expiration_time = db.head_block_time() + fc::days(1);
|
||||
trx.operations.push_back(pop);
|
||||
trx.sign(nathan_key_obj.id,nathan_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
}
|
||||
|
||||
|
|
@ -604,7 +609,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_delete, database_fixture )
|
|||
uop.active_approvals_to_add.insert(nathan.get_id());
|
||||
trx.operations.push_back(uop);
|
||||
trx.sign(nathan_key_obj.id,nathan_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(&db));
|
||||
BOOST_CHECK_EQUAL(prop.available_active_approvals.size(), 1);
|
||||
|
|
@ -612,7 +617,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_delete, database_fixture )
|
|||
std::swap(uop.active_approvals_to_add, uop.active_approvals_to_remove);
|
||||
trx.operations.push_back(uop);
|
||||
trx.sign(nathan_key_obj.id,nathan_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(&db));
|
||||
BOOST_CHECK_EQUAL(prop.available_active_approvals.size(), 0);
|
||||
|
|
@ -625,7 +630,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_delete, database_fixture )
|
|||
dop.proposal = pid;
|
||||
trx.operations.push_back(dop);
|
||||
trx.sign(nathan_key_obj.id,nathan_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
BOOST_CHECK(db.find_object(pid) == nullptr);
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan, asset_id_type()(db)), 100000);
|
||||
}
|
||||
|
|
@ -666,7 +671,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_delete, database_fixture )
|
|||
pop.expiration_time = db.head_block_time() + fc::days(1);
|
||||
trx.operations.push_back(pop);
|
||||
trx.sign(nathan_key_obj.id,nathan_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
}
|
||||
|
||||
|
|
@ -682,7 +687,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_delete, database_fixture )
|
|||
uop.owner_approvals_to_add.insert(nathan.get_id());
|
||||
trx.operations.push_back(uop);
|
||||
trx.sign(nathan_key_obj.id,nathan_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(&db));
|
||||
BOOST_CHECK_EQUAL(prop.available_owner_approvals.size(), 1);
|
||||
|
|
@ -690,7 +695,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_delete, database_fixture )
|
|||
std::swap(uop.owner_approvals_to_add, uop.owner_approvals_to_remove);
|
||||
trx.operations.push_back(uop);
|
||||
trx.sign(nathan_key_obj.id,nathan_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(&db));
|
||||
BOOST_CHECK_EQUAL(prop.available_owner_approvals.size(), 0);
|
||||
|
|
@ -704,7 +709,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_delete, database_fixture )
|
|||
dop.using_owner_authority = true;
|
||||
trx.operations.push_back(dop);
|
||||
trx.sign(nathan_key_obj.id,nathan_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
BOOST_CHECK(db.find_object(pid) == nullptr);
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan, asset_id_type()(db)), 100000);
|
||||
}
|
||||
|
|
@ -745,7 +750,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_complete, database_fixture )
|
|||
pop.expiration_time = db.head_block_time() + fc::days(1);
|
||||
trx.operations.push_back(pop);
|
||||
trx.sign(nathan_key_obj.id,nathan_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
}
|
||||
|
||||
|
|
@ -763,7 +768,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_complete, database_fixture )
|
|||
trx.operations.push_back(uop);
|
||||
trx.sign(nathan_key_obj.id,nathan_key);
|
||||
trx.sign(dan_key_obj.id,dan_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(&db));
|
||||
BOOST_CHECK_EQUAL(prop.available_key_approvals.size(), 1);
|
||||
|
|
@ -772,7 +777,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_complete, database_fixture )
|
|||
trx.operations.push_back(uop);
|
||||
trx.sign(nathan_key_obj.id,nathan_key);
|
||||
trx.sign(dan_key_obj.id,dan_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(&db));
|
||||
BOOST_CHECK_EQUAL(prop.available_key_approvals.size(), 0);
|
||||
|
|
@ -783,7 +788,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_complete, database_fixture )
|
|||
trx.operations.push_back(uop);
|
||||
trx.sign(nathan_key_obj.id,nathan_key);
|
||||
trx.sign(dan_key_obj.id,dan_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(&db));
|
||||
BOOST_CHECK_EQUAL(prop.available_key_approvals.size(), 1);
|
||||
|
|
@ -792,7 +797,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_complete, database_fixture )
|
|||
uop.owner_approvals_to_add.insert(nathan.get_id());
|
||||
trx.operations.push_back(uop);
|
||||
trx.sign(nathan_key_obj.id,nathan_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
BOOST_CHECK(db.find_object(pid) == nullptr);
|
||||
}
|
||||
|
|
@ -842,7 +847,7 @@ BOOST_FIXTURE_TEST_CASE( max_authority_membership, database_fixture )
|
|||
kc_op.key_data = public_key_type( privkey.get_public_key() );
|
||||
tx.operations.push_back( kc_op );
|
||||
}
|
||||
ptx = db.push_transaction(tx, ~0);
|
||||
ptx = PUSH_TX( db, tx, ~0 );
|
||||
|
||||
vector<key_id_type> key_ids;
|
||||
|
||||
|
|
@ -882,11 +887,11 @@ BOOST_FIXTURE_TEST_CASE( max_authority_membership, database_fixture )
|
|||
|
||||
if( num_keys > max_authority_membership )
|
||||
{
|
||||
BOOST_REQUIRE_THROW(db.push_transaction(tx, ~0), fc::exception);
|
||||
BOOST_REQUIRE_THROW(PUSH_TX( db, tx, ~0 ), fc::exception);
|
||||
}
|
||||
else
|
||||
{
|
||||
db.push_transaction(tx, ~0);
|
||||
PUSH_TX( db, tx, ~0 );
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
|
@ -942,38 +947,37 @@ BOOST_FIXTURE_TEST_CASE( bogus_signature, database_fixture )
|
|||
xfer_op.get<transfer_operation>().get_required_auth(active_set, owner_set);
|
||||
// wdump( (active_set)(owner_set)(alice_key_id) (alice_account_object) );
|
||||
|
||||
PUSH_TX( trx, skip );
|
||||
PUSH_TX( db, trx, skip );
|
||||
|
||||
trx.operations.push_back( xfer_op );
|
||||
// Alice's signature is now invalid
|
||||
//edump((trx));
|
||||
BOOST_REQUIRE_THROW( PUSH_TX( trx, skip ), fc::exception );
|
||||
BOOST_REQUIRE_THROW( PUSH_TX( db, trx, skip ), fc::exception );
|
||||
// Re-sign, now OK (sig is replaced)
|
||||
trx.sign( alice_key_id, alice_key );
|
||||
PUSH_TX( trx, skip );
|
||||
PUSH_TX( db, trx, skip );
|
||||
|
||||
trx.signatures.clear();
|
||||
trx.sign( charlie_key_id, alice_key );
|
||||
// Sign with Alice's key (valid) claiming to be Charlie
|
||||
BOOST_REQUIRE_THROW( PUSH_TX( trx, skip ), fc::exception );
|
||||
BOOST_REQUIRE_THROW( PUSH_TX( db, trx, skip ), fc::exception );
|
||||
// and with Charlie's key (invalid) claiming to be Alice
|
||||
trx.sign( charlie_key_id, alice_key );
|
||||
BOOST_REQUIRE_THROW( PUSH_TX( trx, skip ), fc::exception );
|
||||
BOOST_REQUIRE_THROW( PUSH_TX( db, trx, skip ), fc::exception );
|
||||
trx.signatures.clear();
|
||||
// okay, now sign ONLY with Charlie's key claiming to be Alice
|
||||
trx.sign( charlie_key_id, alice_key );
|
||||
BOOST_REQUIRE_THROW( PUSH_TX( trx, skip ), fc::exception );
|
||||
BOOST_REQUIRE_THROW( PUSH_TX( db, trx, skip ), fc::exception );
|
||||
|
||||
trx.signatures.clear();
|
||||
trx.operations.pop_back();
|
||||
trx.sign( alice_key_id, alice_key );
|
||||
trx.sign( charlie_key_id, charlie_key );
|
||||
// Signed by third-party Charlie (irrelevant key, not in authority)
|
||||
PUSH_TX( trx, skip );
|
||||
PUSH_TX( db, trx, skip );
|
||||
trx.operations.push_back( xfer_op );
|
||||
trx.sign( alice_key_id, alice_key );
|
||||
// Alice's sig is valid but Charlie's is invalid
|
||||
BOOST_REQUIRE_THROW( PUSH_TX( trx, skip ), fc::exception );
|
||||
BOOST_REQUIRE_THROW( PUSH_TX( db, trx, skip ), fc::exception );
|
||||
}
|
||||
FC_LOG_AND_RETHROW()
|
||||
}
|
||||
|
|
@ -1000,7 +1004,7 @@ BOOST_FIXTURE_TEST_CASE( voting_account, database_fixture )
|
|||
op.new_options->num_committee = 1;
|
||||
trx.operations.push_back(op);
|
||||
trx.sign(nathan_key_id, nathan_private_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
}
|
||||
{
|
||||
|
|
@ -1012,11 +1016,11 @@ BOOST_FIXTURE_TEST_CASE( voting_account, database_fixture )
|
|||
trx.operations.push_back(op);
|
||||
trx.sign(vikram_key_id, vikram_private_key);
|
||||
// Fails because num_committee is larger than the cardinality of committee members being voted for
|
||||
BOOST_CHECK_THROW(db.push_transaction(trx), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db, trx ), fc::exception);
|
||||
op.new_options->num_committee = 3;
|
||||
trx.operations = {op};
|
||||
trx.sign(vikram_key_id, vikram_private_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -116,8 +116,8 @@ BOOST_AUTO_TEST_CASE( generate_empty_blocks )
|
|||
auto delegate_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("genesis")) );
|
||||
{
|
||||
database db;
|
||||
db.open(data_dir.path(), genesis_allocation() );
|
||||
b = db.generate_block( now, db.get_scheduled_witness( 1 ).first, delegate_priv_key );
|
||||
db.open(data_dir.path(), genesis_state_type() );
|
||||
b = db.generate_block( now, db.get_scheduled_witness( 1 ).first, delegate_priv_key, database::skip_nothing );
|
||||
|
||||
for( uint32_t i = 1; i < 200; ++i )
|
||||
{
|
||||
|
|
@ -127,7 +127,7 @@ BOOST_AUTO_TEST_CASE( generate_empty_blocks )
|
|||
witness_id_type cur_witness = db.get_scheduled_witness( 1 ).first;
|
||||
// TODO: Uncomment this when witness scheduling implemented
|
||||
BOOST_CHECK( cur_witness != prev_witness );
|
||||
b = db.generate_block( now, cur_witness, delegate_priv_key );
|
||||
b = db.generate_block( now, cur_witness, delegate_priv_key, database::skip_nothing );
|
||||
BOOST_CHECK( b.witness == cur_witness );
|
||||
}
|
||||
db.close();
|
||||
|
|
@ -145,7 +145,7 @@ BOOST_AUTO_TEST_CASE( generate_empty_blocks )
|
|||
witness_id_type cur_witness = db.get_scheduled_witness( 1 ).first;
|
||||
// TODO: Uncomment this when witness scheduling implemented
|
||||
BOOST_CHECK( cur_witness != prev_witness );
|
||||
b = db.generate_block( now, cur_witness, delegate_priv_key );
|
||||
b = db.generate_block( now, cur_witness, delegate_priv_key, database::skip_nothing );
|
||||
}
|
||||
BOOST_CHECK_EQUAL( db.head_block_num(), 400 );
|
||||
}
|
||||
|
|
@ -161,14 +161,14 @@ BOOST_AUTO_TEST_CASE( undo_block )
|
|||
fc::temp_directory data_dir;
|
||||
{
|
||||
database db;
|
||||
db.open(data_dir.path(), genesis_allocation() );
|
||||
db.open(data_dir.path(), genesis_state_type() );
|
||||
fc::time_point_sec now( GRAPHENE_GENESIS_TIMESTAMP );
|
||||
|
||||
auto delegate_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("genesis")) );
|
||||
for( uint32_t i = 0; i < 5; ++i )
|
||||
{
|
||||
now += db.block_interval();
|
||||
auto b = db.generate_block( now, db.get_scheduled_witness( 1 ).first, delegate_priv_key );
|
||||
auto b = db.generate_block( now, db.get_scheduled_witness( 1 ).first, delegate_priv_key, database::skip_nothing );
|
||||
}
|
||||
BOOST_CHECK( db.head_block_num() == 5 );
|
||||
db.pop_block();
|
||||
|
|
@ -186,7 +186,7 @@ BOOST_AUTO_TEST_CASE( undo_block )
|
|||
for( uint32_t i = 0; i < 5; ++i )
|
||||
{
|
||||
now += db.block_interval();
|
||||
auto b = db.generate_block( now, db.get_scheduled_witness( 1 ).first, delegate_priv_key );
|
||||
auto b = db.generate_block( now, db.get_scheduled_witness( 1 ).first, delegate_priv_key, database::skip_nothing );
|
||||
}
|
||||
BOOST_CHECK( db.head_block_num() == 7 );
|
||||
}
|
||||
|
|
@ -204,32 +204,32 @@ BOOST_AUTO_TEST_CASE( fork_blocks )
|
|||
fc::time_point_sec now( GRAPHENE_GENESIS_TIMESTAMP );
|
||||
|
||||
database db1;
|
||||
db1.open( data_dir1.path(), genesis_allocation() );
|
||||
db1.open(data_dir1.path(), genesis_state_type());
|
||||
database db2;
|
||||
db2.open( data_dir2.path(), genesis_allocation() );
|
||||
db2.open(data_dir2.path(), genesis_state_type());
|
||||
|
||||
auto delegate_priv_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("genesis")) );
|
||||
for( uint32_t i = 0; i < 10; ++i )
|
||||
{
|
||||
now += db1.block_interval();
|
||||
auto b = db1.generate_block( now, db1.get_scheduled_witness( 1 ).first, delegate_priv_key );
|
||||
auto b = db1.generate_block(now, db1.get_scheduled_witness(1).first, delegate_priv_key, database::skip_nothing);
|
||||
try {
|
||||
db2.push_block(b);
|
||||
PUSH_BLOCK( db2, b );
|
||||
} FC_CAPTURE_AND_RETHROW( ("db2") );
|
||||
}
|
||||
for( uint32_t i = 10; i < 13; ++i )
|
||||
{
|
||||
now += db1.block_interval();
|
||||
auto b = db1.generate_block( now, db1.get_scheduled_witness( 1 ).first, delegate_priv_key );
|
||||
auto b = db1.generate_block(now, db1.get_scheduled_witness(1).first, delegate_priv_key, database::skip_nothing);
|
||||
}
|
||||
string db1_tip = db1.head_block_id().str();
|
||||
for( uint32_t i = 13; i < 16; ++i )
|
||||
{
|
||||
now += db2.block_interval();
|
||||
auto b = db2.generate_block( now, db2.get_scheduled_witness( db2.get_slot_at_time( now ) ).first, delegate_priv_key );
|
||||
auto b = db2.generate_block(now, db2.get_scheduled_witness(db2.get_slot_at_time(now)).first, delegate_priv_key, database::skip_nothing);
|
||||
// notify both databases of the new block.
|
||||
// only db2 should switch to the new fork, db1 should not
|
||||
db1.push_block(b);
|
||||
PUSH_BLOCK( db1, b );
|
||||
BOOST_CHECK_EQUAL(db1.head_block_id().str(), db1_tip);
|
||||
BOOST_CHECK_EQUAL(db2.head_block_id().str(), b.id().str());
|
||||
}
|
||||
|
|
@ -241,20 +241,20 @@ BOOST_AUTO_TEST_CASE( fork_blocks )
|
|||
BOOST_CHECK_EQUAL(db2.head_block_num(), 13);
|
||||
{
|
||||
now += db2.block_interval();
|
||||
auto b = db2.generate_block( now, db2.get_scheduled_witness( 1 ).first, delegate_priv_key );
|
||||
auto b = db2.generate_block(now, db2.get_scheduled_witness(1).first, delegate_priv_key, database::skip_nothing);
|
||||
good_block = b;
|
||||
b.transactions.emplace_back(signed_transaction());
|
||||
b.transactions.back().operations.emplace_back(transfer_operation());
|
||||
b.sign(delegate_priv_key);
|
||||
BOOST_CHECK_EQUAL(b.block_num(), 14);
|
||||
BOOST_CHECK_THROW(db1.push_block(b), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_BLOCK( db1, b ), fc::exception);
|
||||
}
|
||||
BOOST_CHECK_EQUAL(db1.head_block_num(), 13);
|
||||
BOOST_CHECK_EQUAL(db1.head_block_id().str(), db1_tip);
|
||||
|
||||
// assert that db1 switches to new fork with good block
|
||||
BOOST_CHECK_EQUAL(db2.head_block_num(), 14);
|
||||
db1.push_block(good_block);
|
||||
PUSH_BLOCK( db1, good_block );
|
||||
BOOST_CHECK_EQUAL(db1.head_block_id().str(), db2.head_block_id().str());
|
||||
} catch (fc::exception& e) {
|
||||
edump((e.to_detail_string()));
|
||||
|
|
@ -265,7 +265,7 @@ BOOST_AUTO_TEST_CASE( fork_blocks )
|
|||
BOOST_AUTO_TEST_CASE( undo_pending )
|
||||
{
|
||||
try {
|
||||
fc::time_point_sec now( GRAPHENE_GENESIS_TIMESTAMP );
|
||||
fc::time_point_sec now(GRAPHENE_GENESIS_TIMESTAMP);
|
||||
fc::temp_directory data_dir;
|
||||
{
|
||||
database db;
|
||||
|
|
@ -278,7 +278,7 @@ BOOST_AUTO_TEST_CASE( undo_pending )
|
|||
signed_transaction trx;
|
||||
trx.set_expiration(db.head_block_time() + fc::minutes(1));
|
||||
trx.operations.push_back(transfer_operation({asset(), account_id_type(), account_id_type(1), asset(10000000)}));
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
now += db.block_interval();
|
||||
auto b = db.generate_block( now, db.get_scheduled_witness( 1 ).first, delegate_priv_key, ~0 );
|
||||
|
|
@ -293,10 +293,10 @@ BOOST_AUTO_TEST_CASE( undo_pending )
|
|||
cop.owner = authority(1, key_id_type(), 1);
|
||||
trx.operations.push_back(cop);
|
||||
trx.sign( key_id_type(), delegate_priv_key );
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
|
||||
now += db.block_interval();
|
||||
auto b = db.generate_block( now, db.get_scheduled_witness( 1 ).first, delegate_priv_key );
|
||||
auto b = db.generate_block( now, db.get_scheduled_witness( 1 ).first, delegate_priv_key, database::skip_nothing );
|
||||
|
||||
BOOST_CHECK(nathan_id(db).name == "nathan");
|
||||
|
||||
|
|
@ -304,12 +304,12 @@ BOOST_AUTO_TEST_CASE( undo_pending )
|
|||
trx.set_expiration(db.head_block_time() + db.get_global_properties().parameters.maximum_time_until_expiration-1);
|
||||
trx.operations.push_back(transfer_operation({asset(1),account_id_type(1), nathan_id, asset(5000)}));
|
||||
trx.sign( key_id_type(), delegate_priv_key );
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
trx.set_expiration(db.head_block_time() + db.get_global_properties().parameters.maximum_time_until_expiration-2);
|
||||
trx.operations.push_back(transfer_operation({asset(1),account_id_type(1), nathan_id, asset(5000)}));
|
||||
trx.sign( key_id_type(), delegate_priv_key );
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
|
||||
BOOST_CHECK(db.get_balance(nathan_id, asset_id_type()).amount == 10000);
|
||||
db.clear_pending();
|
||||
|
|
@ -344,31 +344,31 @@ BOOST_AUTO_TEST_CASE( switch_forks_undo_create )
|
|||
cop.owner = authority(1, key_id_type(), 1);
|
||||
trx.operations.push_back(cop);
|
||||
trx.sign( key_id_type(), delegate_priv_key );
|
||||
db1.push_transaction(trx);
|
||||
PUSH_TX( db1, trx );
|
||||
|
||||
auto aw = db1.get_global_properties().active_witnesses;
|
||||
now += db1.block_interval();
|
||||
auto b = db1.generate_block( now, db1.get_scheduled_witness( 1 ).first, delegate_priv_key );
|
||||
auto b = db1.generate_block( now, db1.get_scheduled_witness( 1 ).first, delegate_priv_key, database::skip_nothing );
|
||||
|
||||
BOOST_CHECK(nathan_id(db1).name == "nathan");
|
||||
|
||||
now = fc::time_point_sec( GRAPHENE_GENESIS_TIMESTAMP );
|
||||
now += db2.block_interval();
|
||||
b = db2.generate_block( now, db2.get_scheduled_witness( 1 ).first, delegate_priv_key );
|
||||
db1.push_block(b);
|
||||
b = db2.generate_block( now, db2.get_scheduled_witness( 1 ).first, delegate_priv_key, database::skip_nothing );
|
||||
PUSH_BLOCK( db1, b );
|
||||
aw = db2.get_global_properties().active_witnesses;
|
||||
now += db2.block_interval();
|
||||
b = db2.generate_block( now, db2.get_scheduled_witness( 1 ).first, delegate_priv_key );
|
||||
db1.push_block(b);
|
||||
b = db2.generate_block( now, db2.get_scheduled_witness( 1 ).first, delegate_priv_key, database::skip_nothing );
|
||||
PUSH_BLOCK( db1, b );
|
||||
|
||||
BOOST_CHECK_THROW(nathan_id(db1), fc::exception);
|
||||
|
||||
db2.push_transaction(trx);
|
||||
PUSH_TX( db2, trx );
|
||||
|
||||
aw = db2.get_global_properties().active_witnesses;
|
||||
now += db2.block_interval();
|
||||
b = db2.generate_block( now, db2.get_scheduled_witness( 1 ).first, delegate_priv_key );
|
||||
db1.push_block(b);
|
||||
b = db2.generate_block( now, db2.get_scheduled_witness( 1 ).first, delegate_priv_key, database::skip_nothing );
|
||||
PUSH_BLOCK( db1, b );
|
||||
|
||||
BOOST_CHECK(nathan_id(db1).name == "nathan");
|
||||
BOOST_CHECK(nathan_id(db2).name == "nathan");
|
||||
|
|
@ -402,22 +402,22 @@ BOOST_AUTO_TEST_CASE( duplicate_transactions )
|
|||
cop.owner = authority(1, key_id_type(), 1);
|
||||
trx.operations.push_back(cop);
|
||||
trx.sign( key_id_type(), delegate_priv_key );
|
||||
db1.push_transaction(trx, skip_sigs);
|
||||
PUSH_TX( db1, trx, skip_sigs );
|
||||
|
||||
trx = decltype(trx)();
|
||||
trx.set_expiration(db1.head_block_time() + fc::minutes(1));
|
||||
trx.operations.push_back(transfer_operation({asset(), account_id_type(), nathan_id, asset(500)}));
|
||||
trx.sign( key_id_type(), delegate_priv_key );
|
||||
db1.push_transaction(trx, skip_sigs);
|
||||
PUSH_TX( db1, trx, skip_sigs );
|
||||
|
||||
BOOST_CHECK_THROW(db1.push_transaction(trx, skip_sigs), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db1, trx, skip_sigs ), fc::exception);
|
||||
|
||||
now += db1.block_interval();
|
||||
auto b = db1.generate_block( now, db1.get_scheduled_witness( 1 ).first, delegate_priv_key, skip_sigs );
|
||||
db2.push_block(b, skip_sigs);
|
||||
PUSH_BLOCK( db2, b, skip_sigs );
|
||||
|
||||
BOOST_CHECK_THROW(db1.push_transaction(trx, skip_sigs), fc::exception);
|
||||
BOOST_CHECK_THROW(db2.push_transaction(trx, skip_sigs), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db1, trx, skip_sigs ), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db2, trx, skip_sigs ), fc::exception);
|
||||
BOOST_CHECK_EQUAL(db1.get_balance(nathan_id, asset_id_type()).amount.value, 500);
|
||||
BOOST_CHECK_EQUAL(db2.get_balance(nathan_id, asset_id_type()).amount.value, 500);
|
||||
} catch (fc::exception& e) {
|
||||
|
|
@ -443,7 +443,7 @@ BOOST_AUTO_TEST_CASE( tapos )
|
|||
const graphene::db::index& account_idx = db1.get_index(protocol_ids, account_object_type);
|
||||
|
||||
now += db1.block_interval();
|
||||
auto b = db1.generate_block( now, db1.get_scheduled_witness( 1 ).first, delegate_priv_key );
|
||||
auto b = db1.generate_block( now, db1.get_scheduled_witness( 1 ).first, delegate_priv_key, database::skip_nothing );
|
||||
|
||||
signed_transaction trx;
|
||||
//This transaction must be in the next block after its reference, or it is invalid.
|
||||
|
|
@ -459,21 +459,21 @@ BOOST_AUTO_TEST_CASE( tapos )
|
|||
|
||||
trx.signatures.clear();
|
||||
trx.sign( key_id_type(), delegate_priv_key );
|
||||
db1.push_transaction(trx);
|
||||
PUSH_TX( db1, trx );
|
||||
|
||||
now += db1.block_interval();
|
||||
b = db1.generate_block( now, db1.get_scheduled_witness( 1 ).first, delegate_priv_key );
|
||||
b = db1.generate_block( now, db1.get_scheduled_witness( 1 ).first, delegate_priv_key, database::skip_nothing );
|
||||
|
||||
trx.operations.clear();
|
||||
trx.signatures.clear();
|
||||
trx.operations.push_back(transfer_operation({asset(), account_id_type(), nathan_id, asset(50)}));
|
||||
trx.sign( key_id_type(), delegate_priv_key );
|
||||
//relative_expiration is 1, but ref block is 2 blocks old, so this should fail.
|
||||
BOOST_REQUIRE_THROW(db1.push_transaction(trx, database::skip_transaction_signatures | database::skip_authority_check), fc::exception);
|
||||
BOOST_REQUIRE_THROW(PUSH_TX( db1, trx, database::skip_transaction_signatures | database::skip_authority_check ), fc::exception);
|
||||
trx.set_expiration(db1.head_block_id(), 2);
|
||||
trx.signatures.clear();
|
||||
trx.sign( key_id_type(), delegate_priv_key );
|
||||
db1.push_transaction(trx, database::skip_transaction_signatures | database::skip_authority_check);
|
||||
PUSH_TX( db1, trx, database::skip_transaction_signatures | database::skip_authority_check );
|
||||
} catch (fc::exception& e) {
|
||||
edump((e.to_detail_string()));
|
||||
throw;
|
||||
|
|
@ -498,7 +498,7 @@ BOOST_FIXTURE_TEST_CASE( maintenance_interval, database_fixture )
|
|||
op.new_options = nathan.options;
|
||||
op.new_options->votes.insert(nathans_delegate.vote_id);
|
||||
trx.operations.push_back(op);
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
trx.operations.clear();
|
||||
}
|
||||
transfer(account_id_type()(db), nathan, asset(5000));
|
||||
|
|
@ -551,7 +551,7 @@ BOOST_FIXTURE_TEST_CASE( limit_order_expiration, database_fixture )
|
|||
op.min_to_receive = test->amount(500);
|
||||
op.expiration = db.head_block_time() + fc::seconds(10);
|
||||
trx.operations.push_back(op);
|
||||
auto ptrx = db.push_transaction(trx, ~0);
|
||||
auto ptrx = PUSH_TX( db, trx, ~0 );
|
||||
|
||||
BOOST_CHECK_EQUAL( get_balance(*nathan, *core), 49500 );
|
||||
|
||||
|
|
@ -564,7 +564,7 @@ BOOST_FIXTURE_TEST_CASE( limit_order_expiration, database_fixture )
|
|||
BOOST_CHECK_EQUAL( get_balance(*nathan, *core), 49500 );
|
||||
auto id = limit_itr->id;
|
||||
|
||||
generate_blocks(op.expiration);
|
||||
generate_blocks(op.expiration, false);
|
||||
test = &get_asset("TEST");
|
||||
core = &asset_id_type()(db);
|
||||
nathan = &get_account("nathan");
|
||||
|
|
@ -591,7 +591,7 @@ BOOST_FIXTURE_TEST_CASE( change_block_interval, database_fixture )
|
|||
cop.proposed_ops.emplace_back(uop);
|
||||
trx.operations.push_back(cop);
|
||||
trx.sign(key_id_type(),generate_private_key("genesis"));
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
}
|
||||
{
|
||||
proposal_update_operation uop;
|
||||
|
|
@ -600,7 +600,7 @@ BOOST_FIXTURE_TEST_CASE( change_block_interval, database_fixture )
|
|||
account_id_type(5), account_id_type(6), account_id_type(7), account_id_type(8)};
|
||||
trx.operations.push_back(uop);
|
||||
trx.sign(key_id_type(),generate_private_key("genesis"));
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
BOOST_CHECK(proposal_id_type()(db).is_authorized_to_execute(&db));
|
||||
}
|
||||
|
||||
|
|
@ -645,7 +645,7 @@ BOOST_FIXTURE_TEST_CASE( force_settlement, database_fixture )
|
|||
op.new_options.maximum_force_settlement_volume = 9000;
|
||||
trx.clear();
|
||||
trx.operations.push_back(op);
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
trx.clear();
|
||||
}
|
||||
generate_block();
|
||||
|
|
@ -686,7 +686,7 @@ BOOST_FIXTURE_TEST_CASE( force_settlement, database_fixture )
|
|||
trx.operations.push_back(pop);
|
||||
}
|
||||
trx.sign(key_id_type(),private_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
|
||||
asset_settle_operation sop;
|
||||
|
|
@ -698,7 +698,7 @@ BOOST_FIXTURE_TEST_CASE( force_settlement, database_fixture )
|
|||
trx.sign(key_id_type(),private_key);
|
||||
|
||||
//Partially settle a call
|
||||
force_settlement_id_type settle_id = db.push_transaction(trx).operation_results.front().get<object_id_type>();
|
||||
force_settlement_id_type settle_id = PUSH_TX( db, trx ).operation_results.front().get<object_id_type>();
|
||||
trx.clear();
|
||||
call_order_id_type call_id = db.get_index_type<call_order_index>().indices().get<by_collateral>().begin()->id;
|
||||
BOOST_CHECK_EQUAL(settle_id(db).balance.amount.value, 50);
|
||||
|
|
@ -716,10 +716,10 @@ BOOST_FIXTURE_TEST_CASE( force_settlement, database_fixture )
|
|||
trx.operations.push_back(sop);
|
||||
trx.sign(key_id_type(),private_key);
|
||||
//Trx has expired by now. Make sure it throws.
|
||||
BOOST_CHECK_THROW(settle_id = db.push_transaction(trx).operation_results.front().get<object_id_type>(), fc::exception);
|
||||
BOOST_CHECK_THROW(settle_id = PUSH_TX( db, trx ).operation_results.front().get<object_id_type>(), fc::exception);
|
||||
trx.set_expiration(db.head_block_time() + fc::minutes(1));
|
||||
trx.sign(key_id_type(),private_key);
|
||||
settle_id = db.push_transaction(trx).operation_results.front().get<object_id_type>();
|
||||
settle_id = PUSH_TX( db, trx ).operation_results.front().get<object_id_type>();
|
||||
trx.clear();
|
||||
|
||||
generate_blocks(settle_id(db).settlement_date);
|
||||
|
|
@ -732,7 +732,7 @@ BOOST_FIXTURE_TEST_CASE( force_settlement, database_fixture )
|
|||
sop.amount = db.get_balance(nathan_id, bit_usd);
|
||||
trx.operations.push_back(sop);
|
||||
trx.sign(key_id_type(),private_key);
|
||||
settle_id = db.push_transaction(trx).operation_results.front().get<object_id_type>();
|
||||
settle_id = PUSH_TX( db, trx ).operation_results.front().get<object_id_type>();
|
||||
trx.clear();
|
||||
|
||||
generate_blocks(settle_id(db).settlement_date);
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ BOOST_AUTO_TEST_CASE( cashback_test )
|
|||
op.fee = op.calculate_fee(fees); \
|
||||
trx.operations = {op}; \
|
||||
trx.sign(registrar_name ## _key_id, registrar_name ## _private_key); \
|
||||
actor_name ## _id = db.push_transaction(trx).operation_results.front().get<object_id_type>(); \
|
||||
actor_name ## _id = PUSH_TX( db, trx ).operation_results.front().get<object_id_type>(); \
|
||||
trx.clear(); \
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -146,17 +146,17 @@ BOOST_AUTO_TEST_CASE( create_account_test )
|
|||
op.owner.add_authority(account_id_type(9999999999), 10);
|
||||
trx.operations.back() = op;
|
||||
op.owner = auth_bak;
|
||||
BOOST_REQUIRE_THROW(db.push_transaction(trx, ~0), fc::exception);
|
||||
BOOST_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception);
|
||||
op.owner = auth_bak;
|
||||
op.owner.add_authority(key_id_type(9999999999), 10);
|
||||
trx.operations.back() = op;
|
||||
BOOST_REQUIRE_THROW(db.push_transaction(trx, ~0), fc::exception);
|
||||
BOOST_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception);
|
||||
op.owner = auth_bak;
|
||||
|
||||
trx.operations.back() = op;
|
||||
trx.sign( key_id_type(), fc::ecc::private_key::regenerate(fc::sha256::hash(string("genesis"))) );
|
||||
trx.validate();
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
const account_object& nathan_account = *db.get_index_type<account_index>().indices().get<by_name>().find("nathan");
|
||||
BOOST_CHECK(nathan_account.id.space() == protocol_ids);
|
||||
|
|
@ -206,15 +206,15 @@ BOOST_AUTO_TEST_CASE( child_account )
|
|||
trx.operations.emplace_back(op);
|
||||
sign(trx, key_id_type(), fc::ecc::private_key::regenerate(fc::sha256::hash(string("genesis"))));
|
||||
|
||||
BOOST_REQUIRE_THROW(db.push_transaction(trx), fc::exception);
|
||||
BOOST_REQUIRE_THROW(PUSH_TX( db, trx ), fc::exception);
|
||||
sign(trx, nathan_key.id,nathan_private_key);
|
||||
BOOST_REQUIRE_THROW(db.push_transaction(trx), fc::exception);
|
||||
BOOST_REQUIRE_THROW(PUSH_TX( db, trx ), fc::exception);
|
||||
trx.signatures.clear();
|
||||
op.owner = authority(1, account_id_type(nathan.id), 1);
|
||||
trx.operations = {op};
|
||||
sign(trx, key_id_type(), fc::ecc::private_key::regenerate(fc::sha256::hash(string("genesis"))));
|
||||
sign(trx, nathan_key.id, nathan_private_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
|
||||
BOOST_CHECK( get_account("nathan/child").active.auths == op.active.auths );
|
||||
} catch (fc::exception& e) {
|
||||
|
|
@ -235,7 +235,7 @@ BOOST_AUTO_TEST_CASE( update_account )
|
|||
transfer(account_id_type()(db), nathan, asset(30000));
|
||||
|
||||
trx.operations.emplace_back(key_create_operation({asset(),nathan.id,address(nathan_new_key.get_public_key())}));
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
account_update_operation op;
|
||||
op.account = nathan.id;
|
||||
|
|
@ -245,7 +245,7 @@ BOOST_AUTO_TEST_CASE( update_account )
|
|||
op.new_options->votes = flat_set<vote_id_type>({active_delegates[0](db).vote_id, active_delegates[5](db).vote_id});
|
||||
op.new_options->num_committee = 2;
|
||||
trx.operations.back() = op;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
BOOST_CHECK(nathan.options.memo_key == key_id_type());
|
||||
BOOST_CHECK(nathan.active.weight_threshold == 2);
|
||||
|
|
@ -275,7 +275,7 @@ BOOST_AUTO_TEST_CASE( update_account )
|
|||
op.upgrade_to_lifetime_member = true;
|
||||
op.fee = op.calculate_fee(db.get_global_properties().parameters.current_fees);
|
||||
trx.operations = {op};
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
}
|
||||
|
||||
BOOST_CHECK( nathan.is_lifetime_member() );
|
||||
|
|
@ -303,7 +303,7 @@ BOOST_AUTO_TEST_CASE( transfer_core_asset )
|
|||
|
||||
asset fee = trx.operations.front().get<transfer_operation>().fee;
|
||||
trx.validate();
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
BOOST_CHECK_EQUAL(get_balance(account_id_type()(db), asset_id_type()(db)),
|
||||
(genesis_balance.amount - 10000 - fee.amount).value);
|
||||
|
|
@ -322,7 +322,7 @@ BOOST_AUTO_TEST_CASE( transfer_core_asset )
|
|||
|
||||
fee = trx.operations.front().get<transfer_operation>().fee;
|
||||
trx.validate();
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan_account, asset_id_type()(db)), 8000 - fee.amount.value);
|
||||
BOOST_CHECK_EQUAL(get_balance(account_id_type()(db), asset_id_type()(db)), genesis_balance.amount.value + 2000);
|
||||
|
|
@ -346,7 +346,7 @@ BOOST_AUTO_TEST_CASE( create_delegate )
|
|||
trx.operations.back() = op;
|
||||
|
||||
delegate_id_type delegate_id = db.get_index_type<primary_index<simple_index<delegate_object>>>().get_next_id();
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
const delegate_object& d = delegate_id(db);
|
||||
|
||||
BOOST_CHECK(d.delegate_account == account_id_type());
|
||||
|
|
@ -384,11 +384,11 @@ BOOST_AUTO_TEST_CASE( update_mia )
|
|||
trx.operations.emplace_back(op);
|
||||
|
||||
trx.operations.back() = op;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
std::swap(op.new_options.flags, op.new_options.issuer_permissions);
|
||||
op.new_issuer = account_id_type();
|
||||
trx.operations.back() = op;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
{
|
||||
asset_publish_feed_operation pop;
|
||||
|
|
@ -402,7 +402,7 @@ BOOST_AUTO_TEST_CASE( update_mia )
|
|||
pop.feed = feed;
|
||||
REQUIRE_THROW_WITH_VALUE(pop, feed.maintenance_collateral_ratio, 0);
|
||||
trx.operations.back() = pop;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
}
|
||||
|
||||
trx.operations.clear();
|
||||
|
|
@ -410,13 +410,13 @@ BOOST_AUTO_TEST_CASE( update_mia )
|
|||
op.issuer = account_id_type();
|
||||
op.new_issuer = nathan.id;
|
||||
trx.operations.emplace_back(op);
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
BOOST_CHECK(bit_usd.issuer == nathan.id);
|
||||
|
||||
op.issuer = nathan.id;
|
||||
op.new_issuer = account_id_type();
|
||||
trx.operations.back() = op;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
BOOST_CHECK(bit_usd.issuer == account_id_type());
|
||||
} catch ( const fc::exception& e ) {
|
||||
elog( "${e}", ("e", e.to_detail_string() ) );
|
||||
|
|
@ -440,7 +440,7 @@ BOOST_AUTO_TEST_CASE( create_uia )
|
|||
creator.common_options.flags = charge_market_fee;
|
||||
creator.common_options.core_exchange_rate = price({asset(2),asset(1,1)});
|
||||
trx.operations.push_back(std::move(creator));
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
const asset_object& test_asset = test_asset_id(db);
|
||||
BOOST_CHECK(test_asset.symbol == "TEST");
|
||||
|
|
@ -449,7 +449,7 @@ BOOST_AUTO_TEST_CASE( create_uia )
|
|||
BOOST_CHECK(test_asset.options.max_supply == 100000000);
|
||||
BOOST_CHECK(!test_asset.bitasset_data_id.valid());
|
||||
BOOST_CHECK(test_asset.options.market_fee_percent == GRAPHENE_MAX_MARKET_FEE_PERCENT/100);
|
||||
BOOST_REQUIRE_THROW(db.push_transaction(trx, ~0), fc::exception);
|
||||
BOOST_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception);
|
||||
|
||||
const asset_dynamic_data_object& test_asset_dynamic_data = test_asset.dynamic_asset_data_id(db);
|
||||
BOOST_CHECK(test_asset_dynamic_data.current_supply == 0);
|
||||
|
|
@ -499,22 +499,22 @@ BOOST_AUTO_TEST_CASE( update_uia )
|
|||
|
||||
op.new_options.core_exchange_rate = price(asset(3), test.amount(5));
|
||||
trx.operations.back() = op;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
REQUIRE_THROW_WITH_VALUE(op, new_options.core_exchange_rate, price());
|
||||
op.new_options.core_exchange_rate = test.options.core_exchange_rate;
|
||||
op.new_issuer = nathan.id;
|
||||
trx.operations.back() = op;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
op.issuer = nathan.id;
|
||||
op.new_issuer.reset();
|
||||
op.new_options.flags = transfer_restricted | white_list;
|
||||
trx.operations.back() = op;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
REQUIRE_THROW_WITH_VALUE(op, new_options.issuer_permissions, test.options.issuer_permissions & ~white_list);
|
||||
op.new_options.issuer_permissions = test.options.issuer_permissions & ~white_list;
|
||||
op.new_options.flags = 0;
|
||||
trx.operations.back() = op;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
op.new_options.issuer_permissions = test.options.issuer_permissions;
|
||||
op.new_options.flags = test.options.flags;
|
||||
BOOST_CHECK(!(test.options.issuer_permissions & white_list));
|
||||
|
|
@ -522,9 +522,9 @@ BOOST_AUTO_TEST_CASE( update_uia )
|
|||
REQUIRE_THROW_WITH_VALUE(op, new_options.flags, white_list);
|
||||
op.new_issuer = account_id_type();
|
||||
trx.operations.back() = op;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
op.issuer = account_id_type();
|
||||
BOOST_REQUIRE_THROW(db.push_transaction(trx, ~0), fc::exception);
|
||||
BOOST_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception);
|
||||
op.new_issuer.reset();
|
||||
} catch(fc::exception& e) {
|
||||
edump((e.to_detail_string()));
|
||||
|
|
@ -549,7 +549,7 @@ BOOST_AUTO_TEST_CASE( issue_uia )
|
|||
REQUIRE_THROW_WITH_VALUE(op, issue_to_account, account_id_type(999999999));
|
||||
|
||||
trx.operations.back() = op;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
const asset_dynamic_data_object& test_dynamic_data = test_asset.dynamic_asset_data_id(db);
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan_account, test_asset), 5000000);
|
||||
|
|
@ -557,7 +557,7 @@ BOOST_AUTO_TEST_CASE( issue_uia )
|
|||
BOOST_CHECK(test_dynamic_data.accumulated_fees == 0);
|
||||
BOOST_CHECK(test_dynamic_data.fee_pool == 0);
|
||||
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan_account, test_asset), 10000000);
|
||||
BOOST_CHECK(test_dynamic_data.current_supply == 10000000);
|
||||
|
|
@ -580,11 +580,11 @@ BOOST_AUTO_TEST_CASE( transfer_uia )
|
|||
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan, uia), 10000000);
|
||||
trx.operations.push_back(transfer_operation({asset(),nathan.id, genesis.id, uia.amount(5000)}));
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan, uia), 10000000 - 5000);
|
||||
BOOST_CHECK_EQUAL(get_balance(genesis, uia), 5000);
|
||||
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan, uia), 10000000 - 10000);
|
||||
BOOST_CHECK_EQUAL(get_balance(genesis, uia), 10000);
|
||||
} catch(fc::exception& e) {
|
||||
|
|
@ -782,7 +782,7 @@ BOOST_AUTO_TEST_CASE( uia_fees )
|
|||
BOOST_CHECK(fee.amount > 0);
|
||||
asset core_fee = fee*test_asset.options.core_exchange_rate;
|
||||
trx.operations.push_back(std::move(op));
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan_account, test_asset),
|
||||
(old_balance - fee - test_asset.amount(100)).amount.value);
|
||||
|
|
@ -791,7 +791,7 @@ BOOST_AUTO_TEST_CASE( uia_fees )
|
|||
BOOST_CHECK(asset_dynamic.fee_pool == 1000000 - core_fee.amount);
|
||||
|
||||
//Do it again, for good measure.
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan_account, test_asset),
|
||||
(old_balance - fee - fee - test_asset.amount(200)).amount.value);
|
||||
BOOST_CHECK_EQUAL(get_balance(genesis_account, test_asset), 200);
|
||||
|
|
@ -808,7 +808,7 @@ BOOST_AUTO_TEST_CASE( uia_fees )
|
|||
BOOST_CHECK_EQUAL(get_balance(nathan_account, asset_id_type()(db)), 20);
|
||||
|
||||
trx.operations.emplace_back(std::move(op));
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan_account, asset_id_type()(db)), 0);
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan_account, test_asset),
|
||||
|
|
@ -855,7 +855,7 @@ BOOST_AUTO_TEST_CASE( delegate_feeds )
|
|||
asset_update_operation uop(get_asset("BITUSD"));
|
||||
uop.new_issuer = account_id_type();
|
||||
trx.operations.push_back(uop);
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
trx.clear();
|
||||
}
|
||||
generate_block();
|
||||
|
|
@ -870,7 +870,7 @@ BOOST_AUTO_TEST_CASE( delegate_feeds )
|
|||
op.feed.settlement_price = price(asset(GRAPHENE_BLOCKCHAIN_PRECISION),bit_usd.amount(30));
|
||||
// Accept defaults for required collateral
|
||||
trx.operations.emplace_back(op);
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
{
|
||||
//Dumb sanity check of some operators. Only here to improve code coverage. :D
|
||||
|
|
@ -892,7 +892,7 @@ BOOST_AUTO_TEST_CASE( delegate_feeds )
|
|||
op.publisher = active_witnesses[1];
|
||||
op.feed.settlement_price = price(asset(GRAPHENE_BLOCKCHAIN_PRECISION),bit_usd.amount(25));
|
||||
trx.operations.back() = op;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
BOOST_CHECK_EQUAL(bitasset.current_feed.settlement_price.to_real(), GRAPHENE_BLOCKCHAIN_PRECISION / 25.0);
|
||||
BOOST_CHECK(bitasset.current_feed.maintenance_collateral_ratio == GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO);
|
||||
|
|
@ -902,7 +902,7 @@ BOOST_AUTO_TEST_CASE( delegate_feeds )
|
|||
// But this delegate is an idiot.
|
||||
op.feed.maintenance_collateral_ratio = 1000;
|
||||
trx.operations.back() = op;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
BOOST_CHECK_EQUAL(bitasset.current_feed.settlement_price.to_real(), GRAPHENE_BLOCKCHAIN_PRECISION / 30.0);
|
||||
BOOST_CHECK(bitasset.current_feed.maintenance_collateral_ratio == GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO);
|
||||
|
|
@ -913,7 +913,6 @@ BOOST_AUTO_TEST_CASE( delegate_feeds )
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create an order such that when the trade executes at the
|
||||
* requested price the resulting payout to one party is 0
|
||||
|
|
@ -1195,10 +1194,10 @@ BOOST_AUTO_TEST_CASE( limit_order_fill_or_kill )
|
|||
|
||||
trx.operations.clear();
|
||||
trx.operations.push_back(op);
|
||||
BOOST_CHECK_THROW(db.push_transaction(trx, ~0), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db, trx, ~0 ), fc::exception);
|
||||
op.fill_or_kill = false;
|
||||
trx.operations.back() = op;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
} FC_LOG_AND_RETHROW() }
|
||||
|
||||
/// Shameless code coverage plugging. Otherwise, these calls never happen.
|
||||
|
|
@ -1246,7 +1245,7 @@ BOOST_AUTO_TEST_CASE( witness_withdraw_pay_test )
|
|||
trx.visit(operation_set_fee(db.current_fee_schedule()));
|
||||
trx.validate();
|
||||
trx.sign(key_id_type(),generate_private_key("genesis"));
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
BOOST_CHECK_EQUAL(get_balance(*nathan, *core), 8950000000);
|
||||
|
||||
|
|
@ -1325,7 +1324,7 @@ BOOST_AUTO_TEST_CASE( witness_withdraw_pay_test )
|
|||
trx.visit(operation_set_fee(db.current_fee_schedule()));
|
||||
trx.validate();
|
||||
trx.sign(key_id_type(),generate_private_key("genesis"));
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
|
||||
BOOST_CHECK_EQUAL(get_balance(witness->witness_account(db), *core), witness_ppb - 1/*fee*/);
|
||||
|
|
@ -1555,7 +1554,7 @@ BOOST_AUTO_TEST_CASE( vesting_balance_withdraw_test )
|
|||
create_op.vesting_seconds = vesting_seconds;
|
||||
tx.operations.push_back( create_op );
|
||||
|
||||
processed_transaction ptx = db.push_transaction( tx, ~0 );
|
||||
processed_transaction ptx = PUSH_TX( db, tx, ~0 );
|
||||
const vesting_balance_object& vbo = vesting_balance_id_type(
|
||||
ptx.operation_results[0].get<object_id_type>())(db);
|
||||
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_create )
|
|||
}
|
||||
|
||||
trx.sign(nathan_key_id, nathan_private_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
} FC_LOG_AND_RETHROW() }
|
||||
|
||||
|
|
@ -108,7 +108,7 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_test )
|
|||
op.amount_to_withdraw = asset(1);
|
||||
trx.operations.push_back(op);
|
||||
//Throws because we haven't entered the first withdrawal period yet.
|
||||
BOOST_REQUIRE_THROW(db.push_transaction(trx), fc::exception);
|
||||
BOOST_REQUIRE_THROW(PUSH_TX( db, trx ), fc::exception);
|
||||
//Get to the actual withdrawal period
|
||||
generate_blocks(permit(db).period_start_time);
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_test )
|
|||
trx.clear();
|
||||
trx.operations.push_back(op);
|
||||
trx.sign(dan_key_id, dan_private_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
|
||||
// would be legal on its own, but doesn't work because trx already withdrew
|
||||
REQUIRE_THROW_WITH_VALUE(op, amount_to_withdraw, asset(5));
|
||||
|
|
@ -131,7 +131,7 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_test )
|
|||
trx.operations.back() = op; // withdraw 1
|
||||
trx.ref_block_prefix++; // make it different from previous trx so it's non-duplicate
|
||||
trx.sign(dan_key_id, dan_private_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
}
|
||||
|
||||
|
|
@ -162,11 +162,11 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_test )
|
|||
trx.operations.push_back(op);
|
||||
trx.sign(dan_key_id, dan_private_key);
|
||||
//Throws because nathan doesn't have the money
|
||||
BOOST_CHECK_THROW(db.push_transaction(trx), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db, trx ), fc::exception);
|
||||
op.amount_to_withdraw = asset(1);
|
||||
trx.operations.back() = op;
|
||||
trx.sign(dan_key_id, dan_private_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan_id, asset_id_type()), 0);
|
||||
|
|
@ -196,7 +196,7 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_test )
|
|||
trx.operations.push_back(op);
|
||||
trx.sign(dan_key_id, dan_private_key);
|
||||
//Throws because the permission has expired
|
||||
BOOST_CHECK_THROW(db.push_transaction(trx), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db, trx ), fc::exception);
|
||||
}
|
||||
} FC_LOG_AND_RETHROW() }
|
||||
|
||||
|
|
@ -226,7 +226,7 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_nominal_case )
|
|||
// so tx's have different txid's
|
||||
trx.ref_block_prefix++;
|
||||
trx.sign(dan_key_id, dan_private_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
// tx's involving withdraw_permissions can't delete it even
|
||||
// if no further withdrawals are possible
|
||||
BOOST_CHECK(db.find_object(permit) != nullptr);
|
||||
|
|
@ -273,7 +273,7 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_update )
|
|||
REQUIRE_THROW_WITH_VALUE(op, period_start_time, db.head_block_time() - 50);
|
||||
trx.operations.back() = op;
|
||||
trx.sign(nathan_key_id, nathan_private_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
}
|
||||
|
||||
{
|
||||
|
|
@ -297,7 +297,7 @@ BOOST_AUTO_TEST_CASE( withdraw_permission_delete )
|
|||
trx.set_expiration(db.head_block_id());
|
||||
trx.operations.push_back(op);
|
||||
trx.sign(get_account("nathan").active.auths.begin()->first, generate_private_key("nathan"));
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
} FC_LOG_AND_RETHROW() }
|
||||
|
||||
BOOST_AUTO_TEST_CASE( mia_feeds )
|
||||
|
|
@ -313,7 +313,7 @@ BOOST_AUTO_TEST_CASE( mia_feeds )
|
|||
op.new_issuer = nathan_id;
|
||||
op.new_options = obj.options;
|
||||
trx.operations.push_back(op);
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
generate_block();
|
||||
trx.clear();
|
||||
}
|
||||
|
|
@ -324,7 +324,7 @@ BOOST_AUTO_TEST_CASE( mia_feeds )
|
|||
op.new_feed_producers = {dan_id, ben_id, vikram_id};
|
||||
trx.operations.push_back(op);
|
||||
trx.sign(nathan_key_id, nathan_private_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
generate_block(database::skip_nothing);
|
||||
}
|
||||
{
|
||||
|
|
@ -340,7 +340,7 @@ BOOST_AUTO_TEST_CASE( mia_feeds )
|
|||
// We'll expire margins after a month
|
||||
// Accept defaults for required collateral
|
||||
trx.operations.emplace_back(op);
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
const asset_bitasset_data_object& bitasset = bit_usd.bitasset_data(db);
|
||||
BOOST_CHECK(bitasset.current_feed.settlement_price.to_real() == GRAPHENE_BLOCKCHAIN_PRECISION / 30.0);
|
||||
|
|
@ -349,7 +349,7 @@ BOOST_AUTO_TEST_CASE( mia_feeds )
|
|||
op.publisher = ben_id;
|
||||
op.feed.settlement_price = price(asset(GRAPHENE_BLOCKCHAIN_PRECISION),bit_usd.amount(25));
|
||||
trx.operations.back() = op;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
BOOST_CHECK_EQUAL(bitasset.current_feed.settlement_price.to_real(), GRAPHENE_BLOCKCHAIN_PRECISION / 25.0);
|
||||
BOOST_CHECK(bitasset.current_feed.maintenance_collateral_ratio == GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO);
|
||||
|
|
@ -358,14 +358,14 @@ BOOST_AUTO_TEST_CASE( mia_feeds )
|
|||
op.feed.settlement_price = price(asset(GRAPHENE_BLOCKCHAIN_PRECISION),bit_usd.amount(40));
|
||||
op.feed.maintenance_collateral_ratio = 1000;
|
||||
trx.operations.back() = op;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
BOOST_CHECK_EQUAL(bitasset.current_feed.settlement_price.to_real(), GRAPHENE_BLOCKCHAIN_PRECISION / 30.0);
|
||||
BOOST_CHECK(bitasset.current_feed.maintenance_collateral_ratio == GRAPHENE_DEFAULT_MAINTENANCE_COLLATERAL_RATIO);
|
||||
|
||||
op.publisher = nathan_id;
|
||||
trx.operations.back() = op;
|
||||
BOOST_CHECK_THROW(db.push_transaction(trx, ~0), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db, trx, ~0 ), fc::exception);
|
||||
}
|
||||
} FC_LOG_AND_RETHROW() }
|
||||
|
||||
|
|
@ -391,7 +391,7 @@ BOOST_AUTO_TEST_CASE( witness_create )
|
|||
[](vote_id_type id) { return id.type() == vote_id_type::committee; });
|
||||
trx.operations.push_back(op);
|
||||
trx.sign(nathan_key_id, nathan_private_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
}
|
||||
|
||||
|
|
@ -468,7 +468,7 @@ BOOST_AUTO_TEST_CASE( global_settle_test )
|
|||
REQUIRE_THROW_WITH_VALUE(op, issuer, account_id_type(2));
|
||||
trx.operations.back() = op;
|
||||
trx.sign(nathan_key_id, nathan_private_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL(get_balance(valentine_id, bit_usd_id), 0);
|
||||
|
|
@ -502,7 +502,7 @@ BOOST_AUTO_TEST_CASE( worker_create_test )
|
|||
REQUIRE_THROW_WITH_VALUE(op, work_end_date, op.work_begin_date);
|
||||
trx.operations.back() = op;
|
||||
trx.sign(nathan_key_id, nathan_private_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
}
|
||||
|
||||
const worker_object& worker = worker_id_type()(db);
|
||||
|
|
@ -532,7 +532,7 @@ BOOST_AUTO_TEST_CASE( worker_pay_test )
|
|||
op.new_options = nathan_id(db).options;
|
||||
op.new_options->votes.insert(worker_id_type()(db).vote_for);
|
||||
trx.operations.push_back(op);
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
trx.clear();
|
||||
}
|
||||
{
|
||||
|
|
@ -540,7 +540,7 @@ BOOST_AUTO_TEST_CASE( worker_pay_test )
|
|||
op.payer = account_id_type();
|
||||
op.amount_to_burn = asset(GRAPHENE_INITIAL_SUPPLY/2);
|
||||
trx.operations.push_back(op);
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
trx.clear();
|
||||
}
|
||||
|
||||
|
|
@ -557,7 +557,7 @@ BOOST_AUTO_TEST_CASE( worker_pay_test )
|
|||
trx.set_expiration(db.head_block_id());
|
||||
trx.operations.push_back(op);
|
||||
trx.sign(nathan_key_id, nathan_private_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.signatures.clear();
|
||||
REQUIRE_THROW_WITH_VALUE(op, amount, asset(1));
|
||||
trx.clear();
|
||||
|
|
@ -572,7 +572,7 @@ BOOST_AUTO_TEST_CASE( worker_pay_test )
|
|||
op.new_options = nathan_id(db).options;
|
||||
op.new_options->votes.erase(worker_id_type()(db).vote_for);
|
||||
trx.operations.push_back(op);
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
trx.clear();
|
||||
}
|
||||
|
||||
|
|
@ -592,7 +592,7 @@ BOOST_AUTO_TEST_CASE( worker_pay_test )
|
|||
REQUIRE_THROW_WITH_VALUE(op, amount, asset(501));
|
||||
trx.operations.back() = op;
|
||||
trx.sign(nathan_key_id, nathan_private_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.signatures.clear();
|
||||
trx.clear();
|
||||
}
|
||||
|
|
@ -625,7 +625,7 @@ BOOST_AUTO_TEST_CASE( refund_worker_test )
|
|||
REQUIRE_THROW_WITH_VALUE(op, work_end_date, op.work_begin_date);
|
||||
trx.operations.back() = op;
|
||||
trx.sign(nathan_key_id, nathan_private_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
}
|
||||
|
||||
|
|
@ -645,7 +645,7 @@ BOOST_AUTO_TEST_CASE( refund_worker_test )
|
|||
op.new_options = nathan_id(db).options;
|
||||
op.new_options->votes.insert(worker_id_type()(db).vote_for);
|
||||
trx.operations.push_back(op);
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
trx.clear();
|
||||
}
|
||||
{
|
||||
|
|
@ -653,14 +653,17 @@ BOOST_AUTO_TEST_CASE( refund_worker_test )
|
|||
op.payer = account_id_type();
|
||||
op.amount_to_burn = asset(GRAPHENE_INITIAL_SUPPLY/2);
|
||||
trx.operations.push_back(op);
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
trx.clear();
|
||||
}
|
||||
|
||||
// auto supply = asset_id_type()(db).dynamic_data(db).current_supply;
|
||||
verify_asset_supplies();
|
||||
generate_blocks(db.get_dynamic_global_properties().next_maintenance_time);
|
||||
verify_asset_supplies();
|
||||
BOOST_CHECK_EQUAL(worker_id_type()(db).worker.get<refund_worker_type>().total_burned.value, 1000);
|
||||
generate_blocks(db.get_dynamic_global_properties().next_maintenance_time);
|
||||
verify_asset_supplies();
|
||||
BOOST_CHECK_EQUAL(worker_id_type()(db).worker.get<refund_worker_type>().total_burned.value, 2000);
|
||||
generate_blocks(db.get_dynamic_global_properties().next_maintenance_time);
|
||||
BOOST_CHECK(!db.get(worker_id_type()).is_active(db.head_block_time()));
|
||||
|
|
@ -690,7 +693,7 @@ BOOST_AUTO_TEST_CASE( force_settlement_unavailable )
|
|||
op.new_options.maximum_force_settlement_volume = 9000;
|
||||
trx.clear();
|
||||
trx.operations.push_back(op);
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
trx.clear();
|
||||
}
|
||||
generate_block();
|
||||
|
|
@ -730,7 +733,7 @@ BOOST_AUTO_TEST_CASE( force_settlement_unavailable )
|
|||
trx.operations.push_back(pop);
|
||||
}
|
||||
trx.sign(key_id_type(),private_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
|
||||
asset_settle_operation sop;
|
||||
|
|
@ -738,7 +741,7 @@ BOOST_AUTO_TEST_CASE( force_settlement_unavailable )
|
|||
sop.amount = asset(50, bit_usd);
|
||||
trx.operations = {sop};
|
||||
//Force settlement is disabled; check that it fails
|
||||
BOOST_CHECK_THROW(db.push_transaction(trx, ~0), fc::exception);
|
||||
BOOST_CHECK_THROW(PUSH_TX( db, trx, ~0 ), fc::exception);
|
||||
{
|
||||
//Enable force settlement
|
||||
asset_update_operation op;
|
||||
|
|
@ -748,7 +751,7 @@ BOOST_AUTO_TEST_CASE( force_settlement_unavailable )
|
|||
op.new_options.flags &= ~disable_force_settle;
|
||||
trx.operations = {op};
|
||||
trx.sign(key_id_type(), private_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
trx.operations = {sop};
|
||||
}
|
||||
REQUIRE_THROW_WITH_VALUE(sop, amount, asset(999999, bit_usd));
|
||||
|
|
@ -756,7 +759,7 @@ BOOST_AUTO_TEST_CASE( force_settlement_unavailable )
|
|||
trx.sign(key_id_type(),private_key);
|
||||
|
||||
//Partially settle a call
|
||||
force_settlement_id_type settle_id = db.push_transaction(trx).operation_results.front().get<object_id_type>();
|
||||
force_settlement_id_type settle_id = PUSH_TX( db, trx ).operation_results.front().get<object_id_type>();
|
||||
trx.clear();
|
||||
call_order_id_type call_id = db.get_index_type<call_order_index>().indices().get<by_collateral>().begin()->id;
|
||||
BOOST_CHECK_EQUAL(settle_id(db).balance.amount.value, 50);
|
||||
|
|
@ -778,7 +781,7 @@ BOOST_AUTO_TEST_CASE( force_settlement_unavailable )
|
|||
trx.operations.push_back(op);
|
||||
trx.set_expiration(db.head_block_id());
|
||||
trx.sign(key_id_type(), private_key);
|
||||
db.push_transaction(trx);
|
||||
PUSH_TX( db, trx );
|
||||
//Check that force settlements were all canceled
|
||||
BOOST_CHECK(db.get_index_type<force_settlement_index>().indices().empty());
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan_id, bit_usd), bit_usd(db).dynamic_data(db).current_supply.value);
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ BOOST_AUTO_TEST_CASE( create_advanced_uia )
|
|||
creator.common_options.core_exchange_rate = price({asset(2),asset(1,1)});
|
||||
creator.common_options.whitelist_authorities = creator.common_options.blacklist_authorities = {account_id_type()};
|
||||
trx.operations.push_back(std::move(creator));
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
const asset_object& test_asset = test_asset_id(db);
|
||||
BOOST_CHECK(test_asset.symbol == "ADVANCED");
|
||||
|
|
@ -82,16 +82,16 @@ BOOST_AUTO_TEST_CASE( issue_whitelist_uia )
|
|||
asset_issue_operation op({asset(), advanced.issuer, advanced.amount(1000), nathan.id});
|
||||
trx.operations.emplace_back(op);
|
||||
//Fail because nathan is not whitelisted.
|
||||
BOOST_REQUIRE_THROW(db.push_transaction(trx, ~0), fc::exception);
|
||||
BOOST_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception);
|
||||
|
||||
account_whitelist_operation wop({asset(), account_id_type(), nathan.id, account_whitelist_operation::white_listed});
|
||||
|
||||
trx.operations.back() = wop;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
BOOST_CHECK(nathan.is_authorized_asset(advanced));
|
||||
trx.operations.back() = op;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan, advanced), 1000);
|
||||
} catch(fc::exception& e) {
|
||||
|
|
@ -113,13 +113,13 @@ BOOST_AUTO_TEST_CASE( transfer_whitelist_uia )
|
|||
transfer_operation op({advanced.amount(0), nathan.id, dan.id, advanced.amount(100)});
|
||||
trx.operations.push_back(op);
|
||||
//Fail because dan is not whitelisted.
|
||||
BOOST_REQUIRE_THROW(db.push_transaction(trx, ~0), fc::exception);
|
||||
BOOST_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception);
|
||||
|
||||
account_whitelist_operation wop({asset(), account_id_type(), dan.id, account_whitelist_operation::white_listed});
|
||||
trx.operations.back() = wop;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
trx.operations.back() = op;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan, advanced), 900);
|
||||
BOOST_CHECK_EQUAL(get_balance(dan, advanced), 100);
|
||||
|
|
@ -127,16 +127,16 @@ BOOST_AUTO_TEST_CASE( transfer_whitelist_uia )
|
|||
wop.new_listing |= account_whitelist_operation::black_listed;
|
||||
wop.account_to_list = nathan.id;
|
||||
trx.operations.back() = wop;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
op.amount = advanced.amount(50);
|
||||
trx.operations.back() = op;
|
||||
//Fail because nathan is blacklisted
|
||||
BOOST_REQUIRE_THROW(db.push_transaction(trx, ~0), fc::exception);
|
||||
BOOST_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception);
|
||||
std::swap(op.from, op.to);
|
||||
trx.operations.back() = op;
|
||||
//Fail because nathan is blacklisted
|
||||
BOOST_REQUIRE_THROW(db.push_transaction(trx, ~0), fc::exception);
|
||||
BOOST_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception);
|
||||
|
||||
{
|
||||
asset_update_operation op;
|
||||
|
|
@ -145,12 +145,12 @@ BOOST_AUTO_TEST_CASE( transfer_whitelist_uia )
|
|||
op.new_options.blacklist_authorities.clear();
|
||||
op.new_options.blacklist_authorities.insert(dan.id);
|
||||
trx.operations.back() = op;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
BOOST_CHECK(advanced.options.blacklist_authorities.find(dan.id) != advanced.options.blacklist_authorities.end());
|
||||
}
|
||||
|
||||
trx.operations.back() = op;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan, advanced), 950);
|
||||
BOOST_CHECK_EQUAL(get_balance(dan, advanced), 50);
|
||||
|
||||
|
|
@ -158,29 +158,29 @@ BOOST_AUTO_TEST_CASE( transfer_whitelist_uia )
|
|||
wop.account_to_list = nathan.id;
|
||||
wop.new_listing = account_whitelist_operation::black_listed;
|
||||
trx.operations.back() = wop;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
trx.operations.back() = op;
|
||||
//Fail because nathan is blacklisted
|
||||
BOOST_CHECK(!nathan.is_authorized_asset(advanced));
|
||||
BOOST_REQUIRE_THROW(db.push_transaction(trx, ~0), fc::exception);
|
||||
BOOST_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception);
|
||||
|
||||
//Remove nathan from genesis' whitelist, add him to dan's. This should not authorize him to hold ADVANCED.
|
||||
wop.authorizing_account = account_id_type();
|
||||
wop.account_to_list = nathan.id;
|
||||
wop.new_listing = account_whitelist_operation::no_listing;
|
||||
trx.operations.back() = wop;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
wop.authorizing_account = dan.id;
|
||||
wop.account_to_list = nathan.id;
|
||||
wop.new_listing = account_whitelist_operation::white_listed;
|
||||
trx.operations.back() = wop;
|
||||
db.push_transaction(trx, ~0);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
trx.operations.back() = op;
|
||||
//Fail because nathan is not whitelisted
|
||||
BOOST_CHECK(!nathan.is_authorized_asset(advanced));
|
||||
BOOST_REQUIRE_THROW(db.push_transaction(trx, ~0), fc::exception);
|
||||
BOOST_REQUIRE_THROW(PUSH_TX( db, trx, ~0 ), fc::exception);
|
||||
} catch(fc::exception& e) {
|
||||
edump((e.to_detail_string()));
|
||||
throw;
|
||||
|
|
|
|||
Loading…
Reference in a new issue