コード例 #1
1
        /* ===================================================== */   
        void handle_message( const connection_ptr& con, const message& m )
        { 
          try {
           chan_data& cdat = get_channel_data(con);
 
           ilog( "${msg_type}", ("msg_type", (bitname::message_type)m.msg_type ) );
           
           switch( (bitname::message_type)m.msg_type )
           {
               case name_inv_msg:
                 handle_name_inv( con, cdat, m.as<name_inv_message>() );
                 break;
               case block_inv_msg:
                 handle_block_inv( con, cdat, m.as<block_inv_message>() );
                 break;
               case get_name_inv_msg:
                 handle_get_name_inv( con, cdat, m.as<get_name_inv_message>() );
                 break;
               case get_headers_msg:
                 handle_get_headers( con, cdat, m.as<get_headers_message>() );
                 break;
               case get_block_msg:
                 handle_get_block( con, cdat, m.as<get_block_message>() );
                 break;
               case get_block_index_msg:
                 handle_get_block_index( con, cdat, m.as<get_block_index_message>() );
                 break;
               case get_name_header_msg:
                 handle_get_name( con, cdat, m.as<get_name_header_message>() );
                 break;
               case name_header_msg:
                 handle_name( con, cdat, m.as<name_header_message>() );
                 break;
               case block_index_msg:
                 handle_block_index( con, cdat, m.as<block_index_message>() );
                 break;
               case block_msg:
                 handle_block( con, cdat, m.as<block_message>() );
                 break;
               case headers_msg:
                 handle_headers( con, cdat, m.as<headers_message>() );
                 break;
               default:
                 FC_THROW_EXCEPTION( exception, "unknown bitname message type ${msg_type}", ("msg_type", m.msg_type ) );
           }
          } 
          catch ( fc::exception& e )
          {
            wlog( "${e}  ${from}", ("e",e.to_detail_string())("from",con->remote_endpoint()) );
          }
        }  // handle_message
コード例 #2
0
 /**
  *   For any given message id, there are many potential hosts from which it could be fetched.  We
  *   want to distribute the load across all hosts equally and therefore, the best one to fetch from
  *   is the host that we have fetched the least from and that has fetched the most from us.
  *
  */
 void fetch_from_best_connection( const std::vector<connection_ptr>& cons, const mini_pow& id )
 {
    // if request is made, move id from unknown_msgs to requested_msgs 
    // TODO: update this algorithm to be something better. 
    for( uint32_t i = 0; i < cons.size(); ++i )
    {
        bitchat_chan_data& cd = get_channel_data(cons[i]); 
        if( cd.known_inv.find( id ) !=  cd.known_inv.end() )
        {
           requested_msgs[id] = fc::time_point::now();
           unknown_msgs.erase(id);
           cons[i]->send( network::message( get_priv_message( id ), chan_id ) );
           return;
        }
    }
 }
コード例 #3
0
          /* ===================================================== 
           *  When a new node connects it must locate the best block chain that extends the
           *  current known chain.  
           **/   
          void request_block_headers( const connection_ptr& con )
          { try {
              ilog( "requesting block headers from ${ep}", ("ep",con->remote_endpoint() ));
              chan_data& cdat = get_channel_data(con);
              if( cdat.requested_headers ) 
                  return;

              get_headers_message  request;
              const std::vector<name_id_type>& ids = _name_db.get_header_ids();
              uint32_t delta = 1;
              for( int32_t i = ids.size() - 1; i >= 0;  )
              {
                 request.locator_hashes.push_back(ids[i]);
                 i -= delta;
                 delta *= 2;
              }
              cdat.requested_headers = fc::time_point::now();
              con->send( network::message(request,_chan_id) );
          } FC_RETHROW_EXCEPTIONS( warn, "") }
コード例 #4
0
          virtual void handle_message( const connection_ptr& c, const bts::network::message& m )
          {
              bitchat_chan_data& cdat = get_channel_data(c);

              switch( (bitchat::message_type)m.msg_type )
              {
                  case inv_msg:
                     handle_inv( c, cdat, m.as<inv_message>()  );
                     break;
                  case get_inv_msg:
                     handle_get_inv( c, cdat, m.as<get_inv_message>()  );
                     break;
                  case get_priv_msg:
                     handle_get_priv( c, cdat, m.as<get_priv_message>()  );
                     break;
                  case encrypted_msg:
                     handle_priv_msg( c, cdat, m.as<encrypted_message>()  );
                     break;
                  default:
                     wlog( "unknown bitchat message type ${t}", ("t",m.msg_type) );
              }
          }
コード例 #5
0
          /**
           *  Send any new inventory items that we have received since the last
           *  broadcast to all connections that do not know about the inv item.
           */
          void broadcast_inv()
          {
              if( new_msgs.size() )
              {
                auto cons = peers->get_connections( chan_id );
                for( auto c = cons.begin(); c != cons.end(); ++c )
                {
                  inv_message msg;

                  bitchat_chan_data& cd = get_channel_data( *c );
                  for( uint32_t i = 0; i < new_msgs.size(); ++i )
                  {
                     if( cd.known_inv.insert( new_msgs[i] ).second )
                     {
                        msg.items.push_back( new_msgs[i] );
                     }
                  }
                  (*c)->send( network::message(msg,chan_id) );
                }
                new_msgs.clear();
              }
          }
コード例 #6
0
// very_complex_array = archiver.values(key, names[], start, end, ...)
xmlrpc_value *get_values(xmlrpc_env *env, xmlrpc_value *args, void *user)
{
#ifdef LOGFILE
    LOG_MSG("archiver.get_values\n");
#endif
    xmlrpc_value *names;
    xmlrpc_int32 key, start_sec, start_nano, end_sec, end_nano, count, how;
    xmlrpc_int32 actual_count;
    // Extract arguments
    xmlrpc_parse_value(env, args, "(iAiiiiii)",
                       &key, &names,
                       &start_sec, &start_nano, &end_sec, &end_nano,
                       &count, &how);    
    if (env->fault_occurred)
        return 0;
#ifdef LOGFILE
    LOG_MSG("how=%d, count=%d\n", (int) how, (int) count);
#endif
    if (count <= 1)
        count = 1;
    actual_count = count;
    if (count > 10000) // Upper limit to avoid outrageous requests.
        actual_count = 10000;
    // Build start/end
    epicsTime start, end;
    pieces2epicsTime(start_sec, start_nano, start);
    pieces2epicsTime(end_sec, end_nano, end);    
    // Pull names into vector for SpreadsheetReader and just because.
    xmlrpc_value *name_val;
    char *name;
    int i;
    xmlrpc_int32 name_count = xmlrpc_array_size(env, names);
    stdVector<stdString> name_vector;
    name_vector.reserve(name_count);
    for (i=0; i<name_count; ++i)
    {   // no new ref!
        name_val = xmlrpc_array_get_item(env, names, i);
        if (env->fault_occurred)
            return 0;
        xmlrpc_parse_value(env, name_val, "s", &name);
        if (env->fault_occurred)
            return 0;
        name_vector.push_back(stdString(name));
    }
    // Build results
    switch (how)
    {
        case HOW_RAW:
            return get_channel_data(env, key, name_vector, start, end,
                                    actual_count, ReaderFactory::Raw, 0.0);
        case HOW_SHEET:
            return get_sheet_data(env, key, name_vector, start, end,
                                  actual_count, ReaderFactory::Raw, 0.0);
        case HOW_AVERAGE:
            return get_sheet_data(env, key, name_vector, start, end,
                                  actual_count,
                                  ReaderFactory::Average, (end-start)/count);
        case HOW_PLOTBIN:
            // 'count' = # of bins, resulting in up to 4*count samples
            return get_channel_data(env, key, name_vector, start, end,
                                    actual_count*4,
                                    ReaderFactory::Plotbin, (end-start)/count);
        case HOW_LINEAR:
            return get_sheet_data(env, key, name_vector, start, end,
                                  actual_count,
                                  ReaderFactory::Linear, (end-start)/count);
    }
    xmlrpc_env_set_fault_formatted(env, ARCH_DAT_ARG_ERROR,
                                   "Invalid how=%d", how);
    return 0;
}
コード例 #7
0
 virtual void handle_subscribe( const connection_ptr& c )
 {
     get_channel_data(c); // creates it... 
     request_latest_blocks();
 }