Exemplo n.º 1
0
Arquivo: user.cpp Projeto: kire321/d4d
int User::to_minutes(time_duration duration)
{
    return duration.total_seconds() / 60;
}
Exemplo n.º 2
0
	inline int total_seconds(time_duration td)
	{ return td.total_seconds(); }
Exemplo n.º 3
0
int64_t localTime() {
  static const ptime epoch(date(1970, 1, 1));
  const time_duration diff = second_clock::local_time() - epoch;
  return diff.total_seconds();
}
Exemplo n.º 4
0
namespace obelisk {

using namespace bc;
using namespace boost::posix_time;
using std::placeholders::_1;
using std::placeholders::_2;
using std::placeholders::_3;
using std::placeholders::_4;

const time_duration retry_start_duration = seconds(30);

void log_to_file(std::ofstream& file, log_level level,
    const std::string& domain, const std::string& body, bool log_requests)
{
    if (body.empty())
        return;
    if (!log_requests && domain == LOG_REQUEST)
        return;
    file << level_repr(level);
    if (!domain.empty())
        file << " [" << domain << "]";
    file << ": " << body << std::endl;
}
void log_to_both(std::ostream& device, std::ofstream& file, log_level level,
    const std::string& domain, const std::string& body, bool log_requests)
{
    if (body.empty())
        return;
    if (!log_requests && domain == LOG_REQUEST)
        return;
    std::ostringstream output;
    output << level_repr(level);
    if (!domain.empty())
        output << " [" << domain << "]";
    output << ": " << body;
    device << output.str() << std::endl;
    file << output.str() << std::endl;
}

void output_file(std::ofstream& file, log_level level,
    const std::string& domain, const std::string& body, bool log_requests)
{
    log_to_file(file, level, domain, body, log_requests);
}
void output_both(std::ofstream& file, log_level level,
    const std::string& domain, const std::string& body, bool log_requests)
{
    log_to_both(std::cout, file, level, domain, body, log_requests);
}

void error_file(std::ofstream& file, log_level level,
    const std::string& domain, const std::string& body, bool log_requests)
{
    log_to_file(file, level, domain, body, log_requests);
}
void error_both(std::ofstream& file, log_level level,
    const std::string& domain, const std::string& body, bool log_requests)
{
    log_to_both(std::cerr, file, level, domain, body, log_requests);
}

node_impl::node_impl()
  : network_pool_(1), disk_pool_(6), mem_pool_(1),
    hosts_(network_pool_),
    handshake_(network_pool_),
    network_(network_pool_),
    protocol_(network_pool_, hosts_, handshake_, network_),
    chain_(disk_pool_),
    poller_(mem_pool_, chain_),
    txpool_(mem_pool_, chain_),
    indexer_(mem_pool_),
    session_(mem_pool_, {
        handshake_, protocol_, chain_, poller_, txpool_}),
    retry_start_timer_(mem_pool_.service())
{
}

bool node_impl::start(config_type& config)
{
    auto file_mode = std::ofstream::out | std::ofstream::app;
    outfile_.open(config.output_file, file_mode);
    errfile_.open(config.error_file, file_mode);
    log_debug().set_output_function(
        std::bind(output_file, std::ref(outfile_),
            _1, _2, _3, config.log_requests));
    log_info().set_output_function(
        std::bind(output_both, std::ref(outfile_),
            _1, _2, _3, config.log_requests));
    log_warning().set_output_function(
        std::bind(error_file, std::ref(errfile_),
            _1, _2, _3, config.log_requests));
    log_error().set_output_function(
        std::bind(error_both, std::ref(errfile_),
            _1, _2, _3, config.log_requests));
    log_fatal().set_output_function(
        std::bind(error_both, std::ref(errfile_),
            _1, _2, _3, config.log_requests));
    protocol_.subscribe_channel(
        std::bind(&node_impl::monitor_tx, this, _1, _2));
    // Start blockchain.
    std::promise<std::error_code> ec_chain;
    auto blockchain_started =
        [&](const std::error_code& ec)
    {
        ec_chain.set_value(ec);
    };
    chain_.start(config.blockchain_path, blockchain_started);
    // Query the error_code and wait for startup completion.
    std::error_code ec = ec_chain.get_future().get();
    if (ec)
    {
        log_error() << "Couldn't start blockchain: " << ec.message();
        return false;
    }
    chain_.subscribe_reorganize(
        std::bind(&node_impl::reorganize, this, _1, _2, _3, _4));
    // Transaction pool
    txpool_.start();
    // Outgoing connections setting in config file before we
    // start p2p network subsystem.
    int outgoing_connections = boost::lexical_cast<int>(
        config.outgoing_connections);
    protocol_.set_max_outbound(outgoing_connections);
    protocol_.set_hosts_filename(config.hosts_file);
    if (!config.listener_enabled)
        protocol_.disable_listener();
    for (const auto node: config.nodes)
    {
        log_info() << "Adding node: " << node.hostname << " " << node.port;
        protocol_.maintain_connection(node.hostname, node.port);
    }
    start_session();
    return true;
}
void node_impl::start_session()
{
    // Start session
    auto session_started = [this](const std::error_code& ec)
    {
        if (ec)
            wait_and_retry_start(ec);
    };
    session_.start(session_started);
}
void node_impl::wait_and_retry_start(const std::error_code& ec)
{
    BITCOIN_ASSERT(ec);
    log_error() << "Unable to start session: " << ec.message();
    log_error() << "Retrying in "
        << retry_start_duration.seconds() << " seconds.";
    retry_start_timer_.expires_from_now(retry_start_duration);
    retry_start_timer_.async_wait(
        std::bind(&node_impl::start_session, this));
}

bool node_impl::stop()
{
    // Stop session
    std::promise<std::error_code> ec_session;
    auto session_stopped =
        [&](const std::error_code& ec)
    {
        ec_session.set_value(ec);
    };
    session_.stop(session_stopped);
    // Query the error_code and wait for startup completion.
    std::error_code ec = ec_session.get_future().get();
    if (ec)
        log_error() << "Problem stopping session: " << ec.message();
    // Stop the threadpools.
    network_pool_.stop();
    disk_pool_.stop();
    mem_pool_.stop();
    network_pool_.join();
    disk_pool_.join();
    mem_pool_.join();
    chain_.stop();
    return true;
}

void node_impl::subscribe_blocks(block_notify_callback notify_block)
{
    notify_blocks_.push_back(notify_block);
}
void node_impl::subscribe_transactions(transaction_notify_callback notify_tx)
{
    notify_txs_.push_back(notify_tx);
}

blockchain& node_impl::blockchain()
{
    return chain_;
}
transaction_pool& node_impl::transaction_pool()
{
    return txpool_;
}
transaction_indexer& node_impl::transaction_indexer()
{
    return indexer_;
}
protocol& node_impl::protocol()
{
    return protocol_;
}
threadpool& node_impl::memory_related_threadpool()
{
    return mem_pool_;
}

void node_impl::monitor_tx(const std::error_code& ec, channel_ptr node)
{
    if (ec)
    {
        log_warning() << "Couldn't start connection: " << ec.message();
        return;
    }
    node->subscribe_transaction(
        std::bind(&node_impl::recv_transaction, this, _1, _2, node));
    protocol_.subscribe_channel(
        std::bind(&node_impl::monitor_tx, this, _1, _2));
}

void node_impl::recv_transaction(const std::error_code& ec,
    const transaction_type& tx, channel_ptr node)
{
    if (ec)
    {
        log_error() << "recv_transaction: " << ec.message();
        return;
    }
    auto handle_deindex = [](const std::error_code& ec)
    {
        if (ec)
            log_error() << "Deindex error: " << ec.message();
    };
    // Called when the transaction becomes confirmed in a block.
    auto handle_confirm = [this, tx, handle_deindex](
        const std::error_code& ec)
    {
        log_debug() << "Confirm transaction: " << ec.message()
            << " " << hash_transaction(tx);
        // Always try to deindex tx.
        // The error could be error::forced_removal from txpool.
        indexer_.deindex(tx, handle_deindex);
    };
    txpool_.store(tx, handle_confirm,
        std::bind(&node_impl::handle_mempool_store, this, _1, _2, tx, node));
    node->subscribe_transaction(
        std::bind(&node_impl::recv_transaction, this, _1, _2, node));
}

void node_impl::handle_mempool_store(
    const std::error_code& ec, const index_list& unconfirmed,
    const transaction_type& tx, channel_ptr node)
{
    if (ec)
    {
        log_warning()
            << "Failed to store transaction in mempool "
            << hash_transaction(tx) << ": " << ec.message();
        return;
    }
    auto handle_index = [](const std::error_code& ec)
    {
        if (ec)
            log_error() << "Index error: " << ec.message();
    };
    indexer_.index(tx, handle_index);
    log_info() << "Accepted transaction: " << hash_transaction(tx);
    for (auto notify: notify_txs_)
        notify(tx);
}

void node_impl::reorganize(const std::error_code& ec,
    size_t fork_point,
    const bc::blockchain::block_list& new_blocks,
    const bc::blockchain::block_list& replaced_blocks)
{
    // Don't bother publishing blocks when in the initial blockchain download.
    if (fork_point > 235866)
        for (size_t i = 0; i < new_blocks.size(); ++i)
        {
            size_t height = fork_point + i + 1;
            const block_type& blk = *new_blocks[i];
            for (auto notify: notify_blocks_)
                notify(height, blk);
        }
    chain_.subscribe_reorganize(
        std::bind(&node_impl::reorganize, this, _1, _2, _3, _4));
}

} // namespace obelisk
Exemplo n.º 5
0
string TimerStructs::toStringSec(time_duration & duration) {
	return padded2DString(duration.seconds());
}
Exemplo n.º 6
0
int64_t str2time(const string& str) {
  static const ptime epoch(date(1970, 1, 1));
  const ptime string_time = from_iso_string(str);
  const time_duration diff = string_time - epoch;
  return diff.total_seconds();
}
Exemplo n.º 7
0
string TimerStructs::toStringMin(time_duration & duration) {
	return padded2DString(duration.minutes());
}
Exemplo n.º 8
0
string TimerStructs::toStringHour(time_duration & duration) {
	return padded2DString(duration.hours());
}
Exemplo n.º 9
0
		void ParametersMap::insert(
			const std::string& parameterName,
			const time_duration& value
		){
			insert(parameterName, value.is_not_a_date_time() ? string() : to_simple_string(value));
		}
Exemplo n.º 10
0
Lightmap::Lightmap(Heightmap *orghm, int level, int shadowLevelDif, LightingInfo *li)
{
	const ptime startTicks = microsec_clock::local_time();
	tilesize.x = orghm->w-1;
	tilesize.y = orghm->h-1;
	name = "lightmap";

	Heightmap *hm;
	int w;

	for(;;) {
		hm = orghm->GetLevel(-level);
		w=hm->w-1;

		GLint maxw;
		glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxw);

		if (w > maxw) level ++;
		else break;
	}

	shadowLevelDif=0;
	Heightmap *shadowhm = orghm->GetLevel(-(level+shadowLevelDif));
	int shadowScale=1<<shadowLevelDif;
	int shadowW=shadowhm->w-1;
	assert (w/shadowW == shadowScale);
	//float org2c = w/float(orghm->w-1);
	//float c2org = (float)(orghm->w-1)/w;

	float *centerhm = new float[w*w];
	Vector3 *shading = new Vector3[w*w];
	for (int y=0;y<w;y++)
		for (int x=0;x<w;x++) {
			centerhm[y*w+x] =/* hm->scale * */ 0.25f * ( (int)hm->at(x,y)+ (int)hm->at(x+1,y)+ (int)hm->at(x,y+1) + (int)hm->at(x+1,y+1) ); //+ hm->offset;
			shading[y*w+x] = li->ambient;
		}

	uchar *lightMap = new uchar[shadowW*shadowW];
	for (std::vector<StaticLight>::const_iterator l=li->staticLights.begin();l!=li->staticLights.end();++l)
	{
		float lightx;
		float lighty;

		if (l->directional) {
			lightx = l->position.x;
			lighty = l->position.y;
		} else {
			lightx = (int)(l->position.x / shadowhm->squareSize);
			lighty = (int)(l->position.z / shadowhm->squareSize);
		}
		CalculateShadows(lightMap, shadowW, lightx, lighty,
			l->position.y, centerhm, w, shadowScale, l->directional);

		for (int y=0;y<w;y++)
		{
			for (int x=0;x<w;x++)
			{
				if (!lightMap[(y*shadowW+x)/shadowScale])
					continue;

				Vector3 wp;
				if (l->directional)
					wp = l->position;
				else
					wp = l->position - Vector3((x+0.5f)*hm->squareSize,centerhm[y*w+x],(y+0.5f)*hm->squareSize);

				uchar* normal = hm->GetNormal (x,y);
				Vector3 normv((2 * (int)normal[0] - 256)/255.0f, (2 * (int)normal[1] - 256)/255.0f, (2 * (int)normal[2] - 256)/255.0f);

				wp.ANormalize();
				float dot = wp.dot(normv);
				if(dot < 0.0f) dot = 0.0f;
				if(dot > 1.0f) dot = 1.0f;
				dot *= lightMap[(y*shadowW+x)/shadowScale]*(1.0f/255.0f);
				shading[y*w+x] += l->color * dot;
			}
		}

	}
	delete[] lightMap;

	glGenTextures(1,&shadingTex);
	glBindTexture (GL_TEXTURE_2D, shadingTex);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

	uchar *shadingTexData=new uchar[w*w*4];
	for(int y=0;y<w;y++) {
		for (int x=0;x<w;x++) {
			shadingTexData[(y*w+x)*4+0] = (uchar)(min(1.0f, shading[y*w+x].x) * 255);
			shadingTexData[(y*w+x)*4+1] = (uchar)(min(1.0f, shading[y*w+x].y) * 255);
			shadingTexData[(y*w+x)*4+2] = (uchar)(min(1.0f, shading[y*w+x].z) * 255);
			shadingTexData[(y*w+x)*4+3] = CReadMap::EncodeHeight(centerhm[w*y+x]);
		}
	}

	SaveImage ("lightmap.png", 4, IL_UNSIGNED_BYTE, w,w, shadingTexData);

	glBuildMipmaps(GL_TEXTURE_2D, 4, w,w, GL_RGBA, GL_UNSIGNED_BYTE, shadingTexData);
	delete[] shadingTexData;

	id = shadingTex;

	delete[] shading;
	delete[] centerhm;

	const time_duration numTicks = microsec_clock::local_time() - startTicks;
	d_trace ("Lightmap generation: %2.3f seconds\n", numTicks.total_milliseconds() * 0.001f);
}
namespace server {

using namespace bc::chain;
using namespace bc::node;
using namespace boost::posix_time;
using boost::format;
using std::placeholders::_1;
using std::placeholders::_2;
using std::placeholders::_3;
using std::placeholders::_4;

const time_duration retry_start_duration = seconds(30);
constexpr auto append = std::ofstream::out | std::ofstream::app;

server_node::server_node(settings_type& config)
  : outfile_(config.debug_file.string(), append), 
    errfile_(config.error_file.string(), append),

    // Threadpools, the number of threads they spawn and priorities.
    network_pool_(1, thread_priority::normal),
    disk_pool_(6, thread_priority::low),
    mem_pool_(1, thread_priority::low),

    // Networking related services.
    hosts_(network_pool_, config.hosts_file.string(), 1000),
    handshake_(network_pool_),
    network_(network_pool_),
    protocol_(network_pool_, hosts_, handshake_, network_, 
        config.out_connections),

    // Blockchain database service.
    chain_(disk_pool_, config.blockchain_path.string(),
        { config.history_height }, 20),

    // Poll new blocks, tx memory pool and tx indexer.
    poller_(mem_pool_, chain_),
    txpool_(mem_pool_, chain_, config.tx_pool_capacity),
    indexer_(mem_pool_),

    // Session manager service.
    session_(mem_pool_, handshake_, protocol_, chain_, poller_, txpool_),
    retry_start_timer_(mem_pool_.service())
{
}

bool server_node::start(settings_type& config)
{
    // Set up logging for node background threads (add to config).
    const auto skip_log = if_else(config.log_requests, "", LOG_REQUEST);
    initialize_logging(outfile_, errfile_, bc::cout, bc::cerr, skip_log);

    // Start blockchain.
    if (!chain_.start())
    {
        log_error(LOG_NODE) << "Couldn't start blockchain.";
        return false;
    }

    chain_.subscribe_reorganize(
        std::bind(&server_node::reorganize, this, _1, _2, _3, _4));

    // Start transaction pool
    txpool_.start();

    // Outgoing connections setting in config file before we
    // start p2p network subsystem.
    protocol_.set_hosts_filename(config.hosts_file.string());
    if (!config.listener_enabled)
        protocol_.disable_listener();

    for (const auto& endpoint: config.peers)
    {
        const auto host = endpoint.get_host();
        const auto port = endpoint.get_port();
        log_info(LOG_NODE) << "Adding node: " << host << " " << port;
        protocol_.maintain_connection(host, port);
    }

    start_session();
    return true;
}
void server_node::start_session()
{
    // Start session
    const auto session_started = [this](const std::error_code& ec)
    {
        if (ec)
            wait_and_retry_start(ec);
    };
    session_.start(session_started);
}
void server_node::wait_and_retry_start(const std::error_code& ec)
{
    BITCOIN_ASSERT(ec);
    log_error(LOG_NODE) << "Unable to start session: " << ec.message();
    log_error(LOG_NODE) << "Retrying in "
        << retry_start_duration.seconds() << " seconds.";
    retry_start_timer_.expires_from_now(retry_start_duration);
    retry_start_timer_.async_wait(
        std::bind(&server_node::start_session, this));
}

bool server_node::stop()
{
    // Stop session
    std::promise<std::error_code> ec_session;
    const auto session_stopped = [&ec_session](const std::error_code& ec)
    {
        ec_session.set_value(ec);
    };
    session_.stop(session_stopped);
    // Query the error_code and wait for startup completion.
    const auto ec = ec_session.get_future().get();
    if (ec)
        log_error(LOG_NODE) << "Problem stopping session: " << ec.message();

    // Safely close blockchain database.
    chain_.stop();

    // Stop the threadpools.
    network_pool_.stop();
    disk_pool_.stop();
    mem_pool_.stop();
    // Join threadpools. Wait for them to finish.
    network_pool_.join();
    disk_pool_.join();
    mem_pool_.join();
    return true;
}

void server_node::subscribe_blocks(block_notify_callback notify_block)
{
    notify_blocks_.push_back(notify_block);
}
void server_node::subscribe_transactions(transaction_notify_callback notify_tx)
{
    notify_txs_.push_back(notify_tx);
}

blockchain& server_node::blockchain()
{
    return chain_;
}
transaction_pool& server_node::transaction_pool()
{
    return txpool_;
}
transaction_indexer& server_node::transaction_indexer()
{
    return indexer_;
}
network::protocol& server_node::protocol()
{
    return protocol_;
}
threadpool& server_node::memory_related_threadpool()
{
    return mem_pool_;
}

void server_node::monitor_tx(const std::error_code& ec, network::channel_ptr node)
{
    if (ec)
    {
        log_warning(LOG_NODE) << "Couldn't start connection: " << ec.message();
        return;
    }
    // Subscribe to transaction messages from this node.
    node->subscribe_transaction(
        std::bind(&server_node::recv_transaction, this, _1, _2, node));
    // Stay subscribed to new connections.
    protocol_.subscribe_channel(
        std::bind(&server_node::monitor_tx, this, _1, _2));
}

void server_node::recv_transaction(const std::error_code& ec,
    const transaction_type& tx, network::channel_ptr node)
{
    if (ec)
    {
        log_warning(LOG_NODE) << "recv_transaction: " << ec.message();
        return;
    }
    const auto handle_deindex = [](const std::error_code& ec)
    {
        if (ec)
            log_error(LOG_NODE) << "Deindex error: " << ec.message();
    };
    // Called when the transaction becomes confirmed in a block.
    const auto handle_confirm = [this, tx, handle_deindex](
        const std::error_code& ec)
    {
        log_debug(LOG_NODE) << "Confirm transaction: " << ec.message()
            << " " << encode_hash(hash_transaction(tx));
        // Always try to deindex tx.
        // The error could be error::forced_removal from txpool.
        indexer_.deindex(tx, handle_deindex);
    };
    // Validate the transaction from the network.
    // Attempt to store in the transaction pool and check the result.
    txpool_.store(tx, handle_confirm,
        std::bind(&server_node::handle_mempool_store, this, _1, _2, tx, node));
    // Resubscribe to transaction messages from this node.
    node->subscribe_transaction(
        std::bind(&server_node::recv_transaction, this, _1, _2, node));
}

void server_node::handle_mempool_store(
    const std::error_code& ec, const index_list& /* unconfirmed */,
    const transaction_type& tx, network::channel_ptr /* node */)
{
    if (ec)
    {
        log_warning(LOG_NODE) << "Failed to store transaction in mempool "
            << encode_hash(hash_transaction(tx)) << ": " << ec.message();
        return;
    }
    const auto handle_index = [](const std::error_code& ec)
    {
        if (ec)
            log_error(LOG_NODE) << "Index error: " << ec.message();
    };
    indexer_.index(tx, handle_index);
    log_info(LOG_NODE) << "Accepted transaction: "
        << encode_hash(hash_transaction(tx));
    for (const auto notify: notify_txs_)
        notify(tx);
}

void server_node::reorganize(const std::error_code& /* ec */,
    size_t fork_point,
    const blockchain::block_list& new_blocks,
    const blockchain::block_list& /* replaced_blocks */)
{
    // magic number (height) - how does this apply to testnet?
    // Don't bother publishing blocks when in the initial blockchain download.
    if (fork_point > 235866)
        for (size_t i = 0; i < new_blocks.size(); ++i)
        {
            size_t height = fork_point + i + 1;
            const block_type& blk = *new_blocks[i];
            for (const auto notify: notify_blocks_)
                notify(height, blk);
        }
    chain_.subscribe_reorganize(
        std::bind(&server_node::reorganize, this, _1, _2, _3, _4));
}

// TODO: use existing libbitcoin-node implementation.
void server_node::fullnode_fetch_history(server_node& node,
    const incoming_message& request, queue_send_callback queue_send)
{
    uint32_t from_height;
    payment_address payaddr;
    if (!unwrap_fetch_history_args(payaddr, from_height, request))
        return;

    fetch_history(node.blockchain(), node.transaction_indexer(), payaddr,
        std::bind(send_history_result, _1, _2, request, queue_send),
        from_height);
}


} // namespace server