/** * 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(); } }
/** * 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(); } }