Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 66 additions & 6 deletions libraries/chain/database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -834,7 +834,9 @@ bool database::_push_block(const signed_block& new_block)

try
{
ilog("Pushing new block #${n} from ${w} with timestamp ${t} at time ${c}", ("n", new_block.block_num())("w", new_block.witness)("t", new_block.timestamp)("c", fc::time_point::now()));
if (new_block.block_num() % 10000 == 0) {
ilog("Pushing new block #${n} from ${w} with timestamp ${t} at time ${c}", ("n", new_block.block_num())("w", new_block.witness)("t", new_block.timestamp)("c", fc::time_point::now()));
}
auto session = start_undo_session();
apply_block(new_block, skip);
session.push();
Expand Down Expand Up @@ -1403,7 +1405,7 @@ void database::init_genesis( uint64_t init_supply )
auth.money.weight_threshold = 0;
});

ilog( "!!!!!! Preparing to create genesis account..." );
ilog( "Preparing to create genesis account..." );
create< dynamic_global_property_object >( [&]( dynamic_global_property_object& p )
{
p.mining_target = fc::sha256(XGT_MINING_TARGET_START);
Expand Down Expand Up @@ -1702,10 +1704,11 @@ void database::_apply_block( const signed_block& next_block )
// process_required_actions( req_actions );
// process_optional_actions( opt_actions );

// Ensure no duplicate mining rewards
/// @since 1.1.2 reject blocks with duplicate rewards
/// Ensure no duplicate mining rewards
/// @since 1.2.0 reject blocks with duplicate rewards
/// @since 1.3.0 deprecated
uint32_t head_num = head_block_num();
if (head_num >= 907200)
if (head_num >= 907200 && head_num < 2116800)
{
std::set< wallet_name_type > rewarded_wallets;
for( const auto& trx : next_block.transactions )
Expand All @@ -1721,14 +1724,71 @@ void database::_apply_block( const signed_block& next_block )
auto it = rewarded_wallets.find(wallet_name);
if (it != rewarded_wallets.end())
{
wlog("!!!!!! Wallet ${w} already rewarded, discarding duplicate operation!", ("w", wallet_name));
// Wallet already rewarded, discarding duplicate operation
continue;
}
rewarded_wallets.insert(wallet_name);
}
}
}

/// @since 1.3.0 reward the first miner, on the current ("next") block
if (head_num >= 2116800)
{
optional< wallet_name_type > rewarded_miner;
for( const auto& trx : next_block.transactions )
{
if ( rewarded_miner )
break;
const auto& operations = trx.operations;
for (auto& op : operations)
{
if ( rewarded_miner )
break;
if ( !is_pow_operation(op) )
continue;
const pow_operation& o = op.template get< pow_operation >();
const wallet_name_type& wallet_name = o.get_worker_name();

const auto& dgp = get_dynamic_global_properties();
uint32_t target_pow = get_pow_summary_target();

const auto& work = o.work.get< sha2_pow >();
FC_ASSERT( work.pow_summary < target_pow, "Insufficient work difficulty. Work: ${w}, Target: ${t}", ("w",work.pow_summary)("t", target_pow) );
FC_ASSERT( work.prev_block == next_block.previous, "Op prev block id ${m} doesn't match prev block id ${n} do not match.", ("m",work.prev_block)("n",next_block.previous) );
FC_ASSERT( next_block.witness == wallet_name, "Block miner name ${m} and op miner name (${n}) do not match.", ("m",next_block.witness)("n",wallet_name) );
wallet_name_type worker_account = work.input.worker_account;

// TODO: Check for 0
int halvings = (XGT_STARTING_OFFSET + dgp.head_block_number) / XGT_MINING_REWARD_HALVING_INTERVAL;
// TODO: Assert no overflow
long divisor = 1L << halvings;
asset base_reward = XGT_MINING_REWARD;
double value = base_reward.amount.value * (1.0 / static_cast<double>(divisor));
long price = static_cast<long>(floor(value));
asset reward = asset(price, base_reward.symbol);
ilog("Mining reward for ${w} amount ${r}", ("w",worker_account)("r",reward));

const wallet_object* w = find_account( worker_account );
const witness_object* cur_witness = find_witness( worker_account );
if (w == nullptr)
{
wlog( "Wallet does not exist for worker account ${w}", ("w",worker_account) );
throw operation_validate_exception();
}
if (cur_witness == nullptr)
{
wlog( "Witness does not exist for worker account ${w}", ("w",worker_account) );
throw operation_validate_exception();
}

adjust_balance(worker_account, reward);

rewarded_miner = optional< wallet_name_type >(wallet_name);
}
}
}

// Adjust mining difficulty
const uint32_t frequency = XGT_MINING_RECALC_EVERY_N_BLOCKS;
if( next_block_num == 1)
Expand Down
4 changes: 4 additions & 0 deletions libraries/chain/xgt_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,10 @@ void pow_evaluator::do_apply( const pow_operation& o )
{
database& db = this->db();

uint32_t head_num = db.head_block_num();
if (head_num >= 2116800)
return;

const auto& dgp = db.get_dynamic_global_properties();
uint32_t target_pow = db.get_pow_summary_target();

Expand Down
16 changes: 13 additions & 3 deletions libraries/plugins/chain/chain_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,23 @@ namespace asio = boost::asio;

struct generate_block_request
{
generate_block_request( const fc::time_point_sec w, const wallet_name_type& wo, const fc::ecc::private_key& priv_key, uint32_t s ) :
generate_block_request(
const fc::time_point_sec w,
const wallet_name_type& wo,
const fc::ecc::private_key& priv_key,
fc::optional< xgt::chain::signed_transaction > br,
uint32_t s
) :
when( w ),
witness_recovery( wo ),
block_signing_private_key( priv_key ),
block_reward( br ),
skip( s ) {}

const fc::time_point_sec when;
const wallet_name_type& witness_recovery;
const fc::ecc::private_key& block_signing_private_key;
fc::optional< xgt::chain::signed_transaction > block_reward;
uint32_t skip;
signed_block block;
};
Expand Down Expand Up @@ -98,7 +106,7 @@ class chain_plugin_impl
std::string to_state = "";
statefile::state_format_info state_format;

uint32_t allow_future_time = 5;
uint32_t allow_future_time = 48;

bool running = true;
std::shared_ptr< std::thread > write_processor_thread;
Expand Down Expand Up @@ -183,6 +191,7 @@ struct write_request_visitor
req->when,
req->witness_recovery,
req->block_signing_private_key,
fc::optional< xgt::chain::signed_transaction >(req->block_reward),
req->skip
);

Expand Down Expand Up @@ -733,9 +742,10 @@ xgt::chain::signed_block chain_plugin::generate_block(
const fc::time_point_sec when,
const wallet_name_type& witness_recovery,
const fc::ecc::private_key& block_signing_private_key,
fc::optional< xgt::chain::signed_transaction > block_reward,
uint32_t skip )
{
generate_block_request req( when, witness_recovery, block_signing_private_key, skip );
generate_block_request req( when, witness_recovery, block_signing_private_key, block_reward, skip );
boost::promise< void > prom;
write_context cxt;
cxt.req_ptr = &req;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class abstract_block_producer {
fc::time_point_sec when,
const xgt::chain::wallet_name_type& witness_recovery,
const fc::ecc::private_key& block_signing_private_key,
fc::optional< xgt::chain::signed_transaction > block_reward,
uint32_t skip = xgt::chain::database::skip_nothing) = 0;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class chain_plugin : public plugin< chain_plugin >
const fc::time_point_sec when,
const wallet_name_type& witness_recovery,
const fc::ecc::private_key& block_signing_private_key,
fc::optional< xgt::chain::signed_transaction > block_reward,
uint32_t skip = database::skip_nothing
);

Expand Down
6 changes: 5 additions & 1 deletion libraries/plugins/debug_node/debug_node_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,11 @@ void debug_node_plugin::debug_generate_blocks(
break;
}

bp.generate_block( scheduled_time, scheduled_witness_name, *debug_private_key, args.skip );
// For expediency, this is just a hacked together block; a less-fake version would be a
// PoW operation.
protocol::signed_transaction fake_block_reward;

bp.generate_block( scheduled_time, scheduled_witness_name, *debug_private_key, fake_block_reward, args.skip );
++produced;
slot = new_slot;
}
Expand Down
13 changes: 9 additions & 4 deletions libraries/plugins/webserver/webserver_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,7 @@ class webserver_plugin_impl
webserver_plugin_impl(thread_pool_size_t thread_pool_size) :
thread_pool_work( this->thread_pool_ios )
{
if (http_endpoint || unix_endpoint) {
for( uint32_t i = 0; i < thread_pool_size; ++i )
thread_pool.create_thread( boost::bind( &asio::io_service::run, &thread_pool_ios ) );
}
this->thread_pool_size = thread_pool_size;
}

void start_webserver();
Expand All @@ -140,6 +137,7 @@ class webserver_plugin_impl
optional< boost::asio::local::stream_protocol::endpoint > unix_endpoint;
websocket_local_server_type unix_server;

thread_pool_size_t thread_pool_size;
boost::thread_group thread_pool;
asio::io_service thread_pool_ios;
asio::io_service::work thread_pool_work;
Expand All @@ -150,6 +148,10 @@ class webserver_plugin_impl

void webserver_plugin_impl::start_webserver()
{
if (http_endpoint || unix_endpoint)
for( uint32_t i = 0; i < thread_pool_size; ++i )
thread_pool.create_thread( boost::bind( &asio::io_service::run, &thread_pool_ios ) );

if( http_endpoint )
{
http_thread = std::make_shared<std::thread>( [&]()
Expand Down Expand Up @@ -361,6 +363,9 @@ void webserver_plugin::plugin_initialize( const variables_map& options )
my->unix_endpoint = ep;
ilog( "configured http to listen on ${ep}", ("ep", unix_endpoint ));
}

if (my->http_endpoint || my->unix_endpoint) {
}
}

void webserver_plugin::plugin_startup()
Expand Down
59 changes: 52 additions & 7 deletions libraries/plugins/witness/block_producer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@

namespace xgt { namespace plugins { namespace witness {

chain::signed_block block_producer::generate_block(fc::time_point_sec when, const chain::wallet_name_type& witness_recovery, const fc::ecc::private_key& block_signing_private_key, uint32_t skip)
chain::signed_block block_producer::generate_block(
fc::time_point_sec when,
const chain::wallet_name_type& witness_recovery,
const fc::ecc::private_key& block_signing_private_key,
fc::optional< xgt::chain::signed_transaction > trx,
uint32_t skip
)
{
chain::signed_block result;
try
Expand All @@ -29,7 +35,7 @@ chain::signed_block block_producer::generate_block(fc::time_point_sec when, cons
{
try
{
result = _generate_block( when, witness_recovery, block_signing_private_key );
result = _generate_block( when, witness_recovery, block_signing_private_key, trx );
}
FC_CAPTURE_AND_RETHROW( (witness_recovery) )
});
Expand All @@ -44,7 +50,12 @@ chain::signed_block block_producer::generate_block(fc::time_point_sec when, cons
return result;
}

chain::signed_block block_producer::_generate_block(fc::time_point_sec when, const chain::wallet_name_type& witness, const fc::ecc::private_key& block_signing_private_key)
chain::signed_block block_producer::_generate_block(
fc::time_point_sec when,
const chain::wallet_name_type& witness,
const fc::ecc::private_key& block_signing_private_key,
fc::optional< xgt::chain::signed_transaction > block_reward
)
{ try {
uint32_t skip = _db.get_node_properties().skip_flags;
// const auto& witness_obj = _db.get_witness( witness );
Expand All @@ -70,7 +81,7 @@ chain::signed_block block_producer::_generate_block(fc::time_point_sec when, con

adjust_hardfork_version_vote( _db.get_witness( witness ), pending_block );

apply_pending_transactions( witness, when, pending_block );
apply_pending_transactions( witness, when, pending_block, block_reward );

// We have temporarily broken the invariant that
// _pending_tx_session is the result of applying _pending_tx, as
Expand Down Expand Up @@ -118,9 +129,11 @@ void block_producer::adjust_hardfork_version_vote(const chain::witness_object& w
}

void block_producer::apply_pending_transactions(
const chain::wallet_name_type& witness_recovery,
fc::time_point_sec when,
chain::signed_block& pending_block)
const chain::wallet_name_type& witness_recovery,
fc::time_point_sec when,
chain::signed_block& pending_block,
fc::optional< xgt::chain::signed_transaction > block_reward
)
{
size_t total_block_size = fc::raw::pack_size( pending_block );
total_block_size += sizeof( uint32_t ); // Transaction vector length
Expand Down Expand Up @@ -153,7 +166,39 @@ void block_producer::apply_pending_transactions(
dgp.current_witness = witness_recovery;
});


uint64_t postponed_tx_count = 0;


// postpone transaction if it would make block too big

if (block_reward)
{
uint64_t new_total_size = total_block_size + fc::raw::pack_size( *block_reward );
if (new_total_size >= maximum_transaction_partition_size)
{
postponed_tx_count++;
}
else
{
try
{
auto temp_session = _db.start_undo_session();
_db.apply_transaction(*block_reward, _db.get_node_properties().skip_flags);
temp_session.squash();

total_block_size = new_total_size;
pending_block.transactions.push_back(*block_reward);
}
catch (const fc::exception& e)
{
// Do nothing, transaction will not be re-applied
//wlog( "Transaction was not processed while generating block due to ${e}", ("e", e) );
//wlog( "The transaction was ${t}", ("t", tx) );
}
}
}

// pop pending state (reset to head block state)
for( const chain::signed_transaction& tx : _db._pending_tx )
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,28 @@ class block_producer : public chain::abstract_block_producer {
fc::time_point_sec when,
const chain::wallet_name_type& witness_recovery,
const fc::ecc::private_key& block_signing_private_key,
uint32_t skip = chain::database::skip_nothing);
fc::optional< xgt::chain::signed_transaction > trx,
uint32_t skip = chain::database::skip_nothing
);

private:
chain::database& _db;

chain::signed_block _generate_block(
fc::time_point_sec when,
const chain::wallet_name_type& witness_recovery,
const fc::ecc::private_key& block_signing_private_key);
const fc::ecc::private_key& block_signing_private_key,
fc::optional< xgt::chain::signed_transaction > block_reward
);

void adjust_hardfork_version_vote( const chain::witness_object& witness, chain::signed_block& pending_block );

void apply_pending_transactions(
const chain::wallet_name_type& witness_recovery,
fc::time_point_sec when,
chain::signed_block& pending_block);
chain::signed_block& pending_block,
fc::optional< xgt::chain::signed_transaction > trx
);
};

} } } // xgt::plugins::witness
Loading