Skip to content

Commit

Permalink
Merge pull request #1 from bitshares/develop
Browse files Browse the repository at this point in the history
updates on 12/20
  • Loading branch information
manikey123 authored Dec 20, 2018
2 parents 91eb971 + d3ba372 commit cb5250f
Show file tree
Hide file tree
Showing 49 changed files with 1,108 additions and 717 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ Visit [BitShares.org](https://bitshares.org/) to learn about BitShares and join

Information for developers can be found in the [Bitshares Developer Portal](https://dev.bitshares.works/). Users interested in how bitshares works can go to the [BitShares Documentation](https://how.bitshares.works/) site.

For security issues and bug bounty program please visit [Hack the DEX](https://hackthedex.io).

Getting Started
---------------
Build instructions and additional documentation are available in the
Expand Down
13 changes: 7 additions & 6 deletions libraries/app/api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,18 +159,18 @@ namespace graphene { namespace app {
}
}

void network_broadcast_api::broadcast_transaction(const signed_transaction& trx)
void network_broadcast_api::broadcast_transaction(const precomputable_transaction& trx)
{
trx.validate();
_app.chain_database()->precompute_parallel( trx ).wait();
_app.chain_database()->push_transaction(trx);
if( _app.p2p_node() != nullptr )
_app.p2p_node()->broadcast_transaction(trx);
}

fc::variant network_broadcast_api::broadcast_transaction_synchronous(const signed_transaction& trx)
fc::variant network_broadcast_api::broadcast_transaction_synchronous(const precomputable_transaction& trx)
{
fc::promise<fc::variant>::ptr prom( new fc::promise<fc::variant>() );
broadcast_transaction_with_callback( [=]( const fc::variant& v ){
broadcast_transaction_with_callback( [prom]( const fc::variant& v ){
prom->set_value(v);
}, trx );

Expand All @@ -179,14 +179,15 @@ namespace graphene { namespace app {

void network_broadcast_api::broadcast_block( const signed_block& b )
{
_app.chain_database()->precompute_parallel( b ).wait();
_app.chain_database()->push_block(b);
if( _app.p2p_node() != nullptr )
_app.p2p_node()->broadcast( net::block_message( b ));
}

void network_broadcast_api::broadcast_transaction_with_callback(confirmation_callback cb, const signed_transaction& trx)
void network_broadcast_api::broadcast_transaction_with_callback(confirmation_callback cb, const precomputable_transaction& trx)
{
trx.validate();
_app.chain_database()->precompute_parallel( trx ).wait();
_callbacks[trx.id()] = cb;
_app.chain_database()->push_transaction(trx);
if( _app.p2p_node() != nullptr )
Expand Down
51 changes: 40 additions & 11 deletions libraries/app/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <graphene/app/application.hpp>
#include <graphene/app/plugin.hpp>

#include <graphene/chain/db_with.hpp>
#include <graphene/chain/genesis_state.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <graphene/chain/protocol/types.hpp>
Expand Down Expand Up @@ -394,12 +395,34 @@ void application_impl::startup()
_chain_db->enable_standby_votes_tracking( _options->at("enable-standby-votes-tracking").as<bool>() );
}

if( _options->count("replay-blockchain") )
if( _options->count("replay-blockchain") || _options->count("revalidate-blockchain") )
_chain_db->wipe( _data_dir / "blockchain", false );

try
{
_chain_db->open( _data_dir / "blockchain", initial_state, GRAPHENE_CURRENT_DB_VERSION );
// these flags are used in open() only, i. e. during replay
uint32_t skip;
if( _options->count("revalidate-blockchain") ) // see also handle_block()
{
if( !loaded_checkpoints.empty() )
wlog( "Warning - revalidate will not validate before last checkpoint" );
if( _options->count("force-validate") )
skip = graphene::chain::database::skip_nothing;
else
skip = graphene::chain::database::skip_transaction_signatures;
}
else // no revalidate, skip most checks
skip = graphene::chain::database::skip_witness_signature |
graphene::chain::database::skip_block_size_check |
graphene::chain::database::skip_merkle_check |
graphene::chain::database::skip_transaction_signatures |
graphene::chain::database::skip_transaction_dupe_check |
graphene::chain::database::skip_tapos_check |
graphene::chain::database::skip_witness_schedule_check;

graphene::chain::detail::with_skip_flags( *_chain_db, skip, [this,&initial_state] () {
_chain_db->open( _data_dir / "blockchain", initial_state, GRAPHENE_CURRENT_DB_VERSION );
});
}
catch( const fc::exception& e )
{
Expand Down Expand Up @@ -517,13 +540,17 @@ bool application_impl::handle_block(const graphene::net::block_message& blk_msg,
FC_ASSERT( (latency.count()/1000) > -5000, "Rejecting block with timestamp in the future" );

try {
// TODO: in the case where this block is valid but on a fork that's too old for us to switch to,
// you can help the network code out by throwing a block_older_than_undo_history exception.
// when the net code sees that, it will stop trying to push blocks from that chain, but
// leave that peer connected so that they can get sync blocks from us
bool result = _chain_db->push_block( blk_msg.block,
(_is_block_producer | _force_validate) ?
database::skip_nothing : database::skip_transaction_signatures );
const uint32_t skip = (_is_block_producer | _force_validate) ?
database::skip_nothing : database::skip_transaction_signatures;
bool result = valve.do_serial( [this,&blk_msg,skip] () {
_chain_db->precompute_parallel( blk_msg.block, skip ).wait();
}, [this,&blk_msg,skip] () {
// TODO: in the case where this block is valid but on a fork that's too old for us to switch to,
// you can help the network code out by throwing a block_older_than_undo_history exception.
// when the net code sees that, it will stop trying to push blocks from that chain, but
// leave that peer connected so that they can get sync blocks from us
return _chain_db->push_block( blk_msg.block, skip );
});

// the block was accepted, so we now know all of the transactions contained in the block
if (!sync_mode)
Expand Down Expand Up @@ -573,6 +600,7 @@ void application_impl::handle_transaction(const graphene::net::trx_message& tran
trx_count = 0;
}

_chain_db->precompute_parallel( transaction_message.trx ).wait();
_chain_db->push_transaction( transaction_message.trx );
} FC_CAPTURE_AND_RETHROW( (transaction_message) ) }

Expand Down Expand Up @@ -961,9 +989,10 @@ void application::set_program_options(boost::program_options::options_descriptio
"Path to create a Genesis State at. If a well-formed JSON file exists at the path, it will be parsed and any "
"missing fields in a Genesis State will be added, and any unknown fields will be removed. If no file or an "
"invalid file is found, it will be replaced with an example Genesis State.")
("replay-blockchain", "Rebuild object graph by replaying all blocks")
("replay-blockchain", "Rebuild object graph by replaying all blocks without validation")
("revalidate-blockchain", "Rebuild object graph by replaying all blocks with full validation")
("resync-blockchain", "Delete all blocks and re-sync with network from scratch")
("force-validate", "Force validation of all transactions")
("force-validate", "Force validation of all transactions during normal operation")
("genesis-timestamp", bpo::value<uint32_t>(),
"Replace timestamp from genesis.json with current time plus this many seconds (experts only!)")
;
Expand Down
4 changes: 4 additions & 0 deletions libraries/app/application_impl.hxx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#pragma once

#include <fc/network/http/websocket.hpp>
#include <fc/thread/parallel.hpp>

#include <graphene/app/application.hpp>
#include <graphene/app/api_access.hpp>
#include <graphene/chain/genesis_state.hpp>
Expand Down Expand Up @@ -194,6 +196,8 @@ class application_impl : public net::node_delegate
std::map<string, std::shared_ptr<abstract_plugin>> _available_plugins;

bool _is_finished_syncing = false;
private:
fc::serial_valve valve;
};

}}} // namespace graphene namespace app namespace detail
36 changes: 18 additions & 18 deletions libraries/app/database_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,10 @@ vector<vector<account_id_type>> database_api::get_key_references( vector<public_
*/
vector<vector<account_id_type>> database_api_impl::get_key_references( vector<public_key_type> keys )const
{
const auto& idx = _db.get_index_type<account_index>();
const auto& aidx = dynamic_cast<const base_primary_index&>(idx);
const auto& refs = aidx.get_secondary_index<graphene::chain::account_member_index>();

vector< vector<account_id_type> > final_result;
final_result.reserve(keys.size());

Expand All @@ -566,10 +570,6 @@ vector<vector<account_id_type>> database_api_impl::get_key_references( vector<pu
subscribe_to_item( a4 );
subscribe_to_item( a5 );

const auto& idx = _db.get_index_type<account_index>();
const auto& aidx = dynamic_cast<const primary_index<account_index>&>(idx);
const auto& refs = aidx.get_secondary_index<graphene::chain::account_member_index>();
auto itr = refs.account_to_key_memberships.find(key);
vector<account_id_type> result;

for( auto& a : {a1,a2,a3,a4,a5} )
Expand All @@ -585,6 +585,7 @@ vector<vector<account_id_type>> database_api_impl::get_key_references( vector<pu
}
}

auto itr = refs.account_to_key_memberships.find(key);
if( itr != refs.account_to_key_memberships.end() )
{
result.reserve( result.size() + itr->second.size() );
Expand Down Expand Up @@ -620,7 +621,7 @@ bool database_api_impl::is_public_key_registered(string public_key) const
return false;
}
const auto& idx = _db.get_index_type<account_index>();
const auto& aidx = dynamic_cast<const primary_index<account_index>&>(idx);
const auto& aidx = dynamic_cast<const base_primary_index&>(idx);
const auto& refs = aidx.get_secondary_index<graphene::chain::account_member_index>();
auto itr = refs.account_to_key_memberships.find(key);
bool is_known = itr != refs.account_to_key_memberships.end();
Expand Down Expand Up @@ -755,6 +756,10 @@ std::map<string,full_account> database_api::get_full_accounts( const vector<stri

std::map<std::string, full_account> database_api_impl::get_full_accounts( const vector<std::string>& names_or_ids, bool subscribe)
{
const auto& proposal_idx = _db.get_index_type<proposal_index>();
const auto& pidx = dynamic_cast<const base_primary_index&>(proposal_idx);
const auto& proposals_by_account = pidx.get_secondary_index<graphene::chain::required_approval_index>();

std::map<std::string, full_account> results;

for (const std::string& account_name_or_id : names_or_ids)
Expand Down Expand Up @@ -784,9 +789,6 @@ std::map<std::string, full_account> database_api_impl::get_full_accounts( const
acnt.cashback_balance = account->cashback_balance(_db);
}
// Add the account's proposals
const auto& proposal_idx = _db.get_index_type<proposal_index>();
const auto& pidx = dynamic_cast<const primary_index<proposal_index>&>(proposal_idx);
const auto& proposals_by_account = pidx.get_secondary_index<graphene::chain::required_approval_index>();
auto required_approvals_itr = proposals_by_account._account_to_proposals.find( account->id );
if( required_approvals_itr != proposals_by_account._account_to_proposals.end() )
{
Expand All @@ -797,11 +799,9 @@ std::map<std::string, full_account> database_api_impl::get_full_accounts( const


// Add the account's balances
auto balance_range = _db.get_index_type<account_balance_index>().indices().get<by_account_asset>().equal_range(boost::make_tuple(account->id));
std::for_each(balance_range.first, balance_range.second,
[&acnt](const account_balance_object& balance) {
acnt.balances.emplace_back(balance);
});
const auto& balances = _db.get_index_type< primary_index< account_balance_index > >().get_secondary_index< balances_by_account_index >().get_account_balances( account->id );
for( const auto balance : balances )
acnt.balances.emplace_back( *balance.second );

// Add the account's vesting balances
auto vesting_range = _db.get_index_type<vesting_balance_index>().indices().get<by_account>().equal_range(account->id);
Expand Down Expand Up @@ -869,7 +869,7 @@ vector<account_id_type> database_api::get_account_references( const std::string
vector<account_id_type> database_api_impl::get_account_references( const std::string account_id_or_name )const
{
const auto& idx = _db.get_index_type<account_index>();
const auto& aidx = dynamic_cast<const primary_index<account_index>&>(idx);
const auto& aidx = dynamic_cast<const base_primary_index&>(idx);
const auto& refs = aidx.get_secondary_index<graphene::chain::account_member_index>();
const account_id_type account_id = get_account_from_string(account_id_or_name)->id;
auto itr = refs.account_to_account_memberships.find(account_id);
Expand Down Expand Up @@ -953,10 +953,10 @@ vector<asset> database_api_impl::get_account_balances(const std::string& account
if (assets.empty())
{
// if the caller passes in an empty list of assets, return balances for all assets the account owns
const account_balance_index& balance_index = _db.get_index_type<account_balance_index>();
auto range = balance_index.indices().get<by_account_asset>().equal_range(boost::make_tuple(acnt));
for (const account_balance_object& balance : boost::make_iterator_range(range.first, range.second))
result.push_back(asset(balance.get_balance()));
const auto& balance_index = _db.get_index_type< primary_index< account_balance_index > >();
const auto& balances = balance_index.get_secondary_index< balances_by_account_index >().get_account_balances( acnt );
for( const auto balance : balances )
result.push_back( balance.second->get_balance() );
}
else
{
Expand Down
6 changes: 3 additions & 3 deletions libraries/app/include/graphene/app/api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,19 +266,19 @@ namespace graphene { namespace app {
* The transaction will be checked for validity in the local database prior to broadcasting. If it fails to
* apply locally, an error will be thrown and the transaction will not be broadcast.
*/
void broadcast_transaction(const signed_transaction& trx);
void broadcast_transaction(const precomputable_transaction& trx);

/** this version of broadcast transaction registers a callback method that will be called when the transaction is
* included into a block. The callback method includes the transaction id, block number, and transaction number in the
* block.
*/
void broadcast_transaction_with_callback( confirmation_callback cb, const signed_transaction& trx);
void broadcast_transaction_with_callback( confirmation_callback cb, const precomputable_transaction& trx);

/** this version of broadcast transaction registers a callback method that will be called when the transaction is
* included into a block. The callback method includes the transaction id, block number, and transaction number in the
* block.
*/
fc::variant broadcast_transaction_synchronous(const signed_transaction& trx);
fc::variant broadcast_transaction_synchronous(const precomputable_transaction& trx);

/**
* @brief Broadcast a signed block to the network
Expand Down
12 changes: 8 additions & 4 deletions libraries/chain/account_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ void verify_account_votes( const database& db, const account_options& options )
}
}


void_result account_create_evaluator::do_evaluate( const account_create_operation& op )
{ try {
database& d = db();
Expand Down Expand Up @@ -318,11 +317,16 @@ void_result account_update_evaluator::do_apply( const account_update_operation&
bool sa_before = acnt->has_special_authority();

// update account statistics
if( o.new_options.valid() && o.new_options->is_voting() != acnt->options.is_voting() )
if( o.new_options.valid() )
{
d.modify( acnt->statistics( d ), []( account_statistics_object& aso )
d.modify( acnt->statistics( d ), [&]( account_statistics_object& aso )
{
aso.is_voting = !aso.is_voting;
if(o.new_options->is_voting() != acnt->options.is_voting())
aso.is_voting = !aso.is_voting;

if((o.new_options->votes != acnt->options.votes ||
o.new_options->voting_account != acnt->options.voting_account))
aso.last_vote_time = d.head_block_time();
} );
}

Expand Down
56 changes: 53 additions & 3 deletions libraries/chain/account_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ set<account_id_type> account_member_index::get_account_members(const account_obj
result.insert(auth.first);
return result;
}
set<public_key_type, account_member_index::key_compare> account_member_index::get_key_members(const account_object& a)const
set<public_key_type, pubkey_comparator> account_member_index::get_key_members(const account_object& a)const
{
set<public_key_type, key_compare> result;
set<public_key_type, pubkey_comparator> result;
for( auto auth : a.owner.key_auths )
result.insert(auth.first);
for( auto auth : a.active.key_auths )
Expand Down Expand Up @@ -215,7 +215,7 @@ void account_member_index::object_modified(const object& after)


{
set<public_key_type, key_compare> after_key_members = get_key_members(a);
set<public_key_type, pubkey_comparator> after_key_members = get_key_members(a);

vector<public_key_type> removed; removed.reserve(before_key_members.size());
std::set_difference(before_key_members.begin(), before_key_members.end(),
Expand Down Expand Up @@ -269,4 +269,54 @@ void account_referrer_index::object_modified( const object& after )
{
}

const uint8_t balances_by_account_index::bits = 20;
const uint64_t balances_by_account_index::mask = (1ULL << balances_by_account_index::bits) - 1;

void balances_by_account_index::object_inserted( const object& obj )
{
const auto& abo = dynamic_cast< const account_balance_object& >( obj );
while( balances.size() < (abo.owner.instance.value >> bits) + 1 )
{
balances.reserve( (abo.owner.instance.value >> bits) + 1 );
balances.resize( balances.size() + 1 );
balances.back().resize( 1ULL << bits );
}
balances[abo.owner.instance.value >> bits][abo.owner.instance.value & mask][abo.asset_type] = &abo;
}

void balances_by_account_index::object_removed( const object& obj )
{
const auto& abo = dynamic_cast< const account_balance_object& >( obj );
if( balances.size() < (abo.owner.instance.value >> bits) + 1 ) return;
balances[abo.owner.instance.value >> bits][abo.owner.instance.value & mask].erase( abo.asset_type );
}

void balances_by_account_index::about_to_modify( const object& before )
{
ids_being_modified.emplace( before.id );
}

void balances_by_account_index::object_modified( const object& after )
{
FC_ASSERT( ids_being_modified.top() == after.id, "Modification of ID is not supported!");
ids_being_modified.pop();
}

const map< asset_id_type, const account_balance_object* >& balances_by_account_index::get_account_balances( const account_id_type& acct )const
{
static const map< asset_id_type, const account_balance_object* > _empty;

if( balances.size() < (acct.instance.value >> bits) + 1 ) return _empty;
return balances[acct.instance.value >> bits][acct.instance.value & mask];
}

const account_balance_object* balances_by_account_index::get_account_balance( const account_id_type& acct, const asset_id_type& asset )const
{
if( balances.size() < (acct.instance.value >> bits) + 1 ) return nullptr;
const auto& mine = balances[acct.instance.value >> bits][acct.instance.value & mask];
const auto itr = mine.find( asset );
if( mine.end() == itr ) return nullptr;
return itr->second;
}

} } // graphene::chain
Loading

0 comments on commit cb5250f

Please sign in to comment.