예제 #1
0
 /**
  *  This is called every time a message is received from c, there are only two
  *  messages supported:  seek to time and broadcast.  When a message is 
  *  received it goes into the database which all of the connections are 
  *  reading from and sending to their clients.
  *
  *  The difficulty required adjusts every 5 minutes with the goal of maintaining
  *  an average data rate of 1.5 kb/sec from all connections.
  */
 virtual void on_connection_message( chain_connection& c, const message& m )
 {
      if( m.type == chain_message_type::subscribe_msg )
      {
         auto sm = m.as<subscribe_message>();
         ilog( "recv: ${m}", ("m",sm) );
         c.set_last_block_id( sm.last_block );
         c.exec_sync_loop();
      }
      else if( m.type == block_message::type )
      {
         try {
            auto blk = m.as<block_message>();
            chain.push_block( blk.block_data );
            for( auto itr = blk.block_data.trxs.begin(); itr != blk.block_data.trxs.end(); ++itr )
            {
               pending.erase( itr->id() );
            }
            broadcast_block( blk.block_data );
         }
         catch ( const fc::exception& e )
         {
            trx_err_message reply;
            reply.err = e.to_detail_string();
            wlog( "${e}", ("e", e.to_detail_string() ) );
            c.send( message( reply ) );
            c.close();
         }
      }
      else if( m.type == chain_message_type::trx_msg )
      {
         auto trx = m.as<trx_message>();
         ilog( "recv: ${m}", ("m",trx) );
         try 
         {
            chain.evaluate_signed_transaction( trx.signed_trx ); // throws exception if invalid trx.
            if( pending.insert( std::make_pair(trx.signed_trx.id(),trx.signed_trx) ).second )
            {
               fc::async( [=]() { broadcast( m ); } );
            }
         } 
         catch ( const fc::exception& e )
         {
            trx_err_message reply;
            reply.signed_trx = trx.signed_trx;
            reply.err = e.to_detail_string();
            wlog( "${e}", ("e", e.to_detail_string() ) );
            c.send( message( reply ) );
            c.close();
         }
      }
      else
      {
          trx_err_message reply;
          reply.err = "unsupported message type";
          wlog( "unsupported message type" );
          c.send( message( reply ) );
          c.close();
      }
 }
예제 #2
0
      void chain_connect_loop()
      {
         _chain_connected = false;
         while( true ) //!_quit_promise->ready() )
         {
            //for( auto itr = _config->default_mail_nodes.begin(); itr != _config->default_mail_nodes.end(); ++itr )
            {
                 try {
                    //ilog( "mail connect ${e}", ("e",*itr) );
                    _chain_con.connect(fc::ip::endpoint::from_string("127.0.0.1:4567"));
                  //  _chain_con.set_last_sync_time( _profile->get_last_sync_time() );

                    subscribe_message msg;
                    msg.version        = 0;
                    if( chain.head_block_num() != uint32_t(-1) )
                       msg.last_block     = chain.head_block_id();
                    _chain_con.send( mail::message( msg ) );
                    _chain_connected = true;
                    return;
                 } 
                 catch ( const fc::exception& e )
                 {
                    wlog( "${e}", ("e",e.to_detail_string()));
                 }
            }
            fc::usleep( fc::seconds(5) );
         }
      }
예제 #3
0
      void chain_connect_loop()
      {
         _chain_connected = false;
         while( !chain_connect_loop_complete.canceled() )
         {
            for( auto itr = _config.unique_node_list.begin(); itr != _config.unique_node_list.end(); ++itr )
            {
                 try {
                    std::cout<< "\rconnecting to bitshares network: "<<itr->first<<"\n";
                    // TODO: pass public key to connection so we can avoid man-in-the-middle attacks
                    _chain_con.connect( fc::ip::endpoint::from_string(itr->first) );

                    subscribe_message msg;
                    msg.version        = 0;
                    if( chain.head_block_num() != uint32_t(-1) )
                    {
                       msg.last_block     = chain.head_block_id();
                    }
                    _chain_con.send( mail::message( msg ) );
                    std::cout<< "\rconnected to bitshares network\n";
                    _chain_connected = true;
                    return;
                 } 
                 catch ( const fc::exception& e )
                 {
                    std::cout<< "\runable to connect to bitshares network at this time.\n";
                    wlog( "${e}", ("e",e.to_detail_string()));
                 }
            }

            // sleep in .5 second increments so we can quit quickly without hanging
            for( uint32_t i = 0; i < 30 && !chain_connect_loop_complete.canceled(); ++i )
               fc::usleep( fc::microseconds(500000) );
         }
      }
예제 #4
0
 /**
  *  This is called every time a message is received from c, there are only two
  *  messages supported:  seek to time and broadcast.  When a message is
  *  received it goes into the database which all of the connections are
  *  reading from and sending to their clients.
  *
  *  The difficulty required adjusts every 5 minutes with the goal of maintaining
  *  an average data rate of 1.5 kb/sec from all connections.
  */
 virtual void on_connection_message( chain_connection& c, const message& m )
 {
      if( m.msg_type == chain_message_type::subscribe_msg )
      {
         auto sm = m.as<subscribe_message>();
         ilog( "recv: ${m}", ("m",sm) );
         c.set_last_block_id( sm.last_block );
         c.exec_sync_loop();
      }
      else if( m.msg_type == block_message::type )
      {
         try {
            auto blk = m.as<block_message>();
            _chain->push_block( blk.block_data );
            for( auto trx : blk.block_data.trxs )
            {
               _pending.erase( trx.id() );
            }
            broadcast_block( blk.block_data );
         }
         catch ( const fc::exception& e )
         {
            trx_err_message reply;
            reply.err = e.to_detail_string();
            wlog( "${e}", ("e", e.to_detail_string() ) );
            c.send( message( reply ) );
            c.close();
         }
      }
      else if( m.msg_type == chain_message_type::trx_msg )
      {
         auto trx = m.as<trx_message>();
         ilog( "recv: ${m}", ("m",trx) );
         try
         {
            _chain->evaluate_transaction( trx.signed_trx ); // throws if error
            if( _pending.insert( std::make_pair(trx.signed_trx.id(),trx.signed_trx) ).second )
            {
               ilog( "new transaction, broadcasting" );
               fc::async( [=]() { broadcast( m ); } );
            }
            else
            {
               wlog( "duplicate transaction, ignoring" );
            }
         }
         catch ( const fc::exception& e )
         {
            trx_err_message reply;
            reply.signed_trx = trx.signed_trx;
            reply.err = e.to_detail_string();
            wlog( "${e}", ("e", e.to_detail_string() ) );
            c.send( message( reply ) );
            c.close();
         }
      }
      else
      {
          trx_err_message reply;
          reply.err = "unsupported message type";
          wlog( "unsupported message type" );
          c.send( message( reply ) );
          c.close();
      }
 }