Exemplo n.º 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
Exemplo n.º 2
0
  variant variant_from_stream( T& in, uint32_t max_depth )
  {
     if( max_depth == 0 )
         FC_THROW_EXCEPTION( parse_error_exception, "Too many nested items in JSON input!" );
     skip_white_space(in);
     signed char c = in.peek();
     switch( c )
     {
        case '"':
           return stringFromStream( in );
        case '{':
           return objectFromStream<T, parser_type>( in, max_depth - 1 );
        case '[':
           return arrayFromStream<T, parser_type>( in, max_depth - 1 );
        case '-':
        case '.':
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
           return number_from_stream<T, parser_type>( in );
        // null, true, false, or 'warning' / string
        case 'n':
        case 't':
        case 'f':
           return token_from_stream( in );
        case 0x04: // ^D end of transmission
        case EOF:
           FC_THROW_EXCEPTION( eof_exception, "unexpected end of file" );
        case 0:
           if( parser_type == fc::json::broken_nul_parser )
              return variant();
           FALLTHROUGH
        default:
           FC_THROW_EXCEPTION( parse_error_exception, "Unexpected char '${c}' in \"${s}\"",
                               ("c", c)("s", stringFromToken(in)) );
     }
 }
//    public_key public_key::mult( const fc::sha256& digest ) const
//    {
//        // get point from this public key
//        const EC_POINT* master_pub   = EC_KEY_get0_public_key( my->_key );
//        ec_group group(EC_GROUP_new_by_curve_name(NID_secp256k1));
//
//        ssl_bignum z;
//        BN_bin2bn((unsigned char*)&digest, sizeof(digest), z);
//
//        // multiply by digest
//        ssl_bignum one;
//        BN_one(one);
//        bn_ctx ctx(BN_CTX_new());
//
//        ec_point result(EC_POINT_new(group));
//        EC_POINT_mul(group, result, z, master_pub, one, ctx);
//
//        public_key rtn;
//        rtn.my->_key = EC_KEY_new_by_curve_name( NID_secp256k1 );
//        EC_KEY_set_public_key(rtn.my->_key,result);
//
//        return rtn;
//    }
    public_key public_key::add( const fc::sha256& digest )const
    {
      try {
        ec_group group(EC_GROUP_new_by_curve_name(NID_secp256k1));
        bn_ctx ctx(BN_CTX_new());

        fc::bigint digest_bi( (char*)&digest, sizeof(digest) );

        ssl_bignum order;
        EC_GROUP_get_order(group, order, ctx);
        if( digest_bi > fc::bigint(order) )
        {
          FC_THROW_EXCEPTION( exception, "digest > group order" );
        }


        public_key digest_key = private_key::regenerate(digest).get_public_key();
        const EC_POINT* digest_point   = EC_KEY_get0_public_key( digest_key.my->_key );

        // get point from this public key
        const EC_POINT* master_pub   = EC_KEY_get0_public_key( my->_key );

//        ssl_bignum z;
//        BN_bin2bn((unsigned char*)&digest, sizeof(digest), z);

        // multiply by digest
//        ssl_bignum one;
//        BN_one(one);

        ec_point result(EC_POINT_new(group));
        EC_POINT_add(group, result, digest_point, master_pub, ctx);

        if (EC_POINT_is_at_infinity(group, result))
        {
          FC_THROW_EXCEPTION( exception, "point at  infinity" );
        }


        public_key rtn;
        rtn.my->_key = EC_KEY_new_by_curve_name( NID_secp256k1 );
        EC_KEY_set_public_key(rtn.my->_key,result);
        return rtn;
      } FC_RETHROW_EXCEPTIONS( debug, "digest: ${digest}", ("digest",digest) );
    }
Exemplo n.º 4
0
      /**
       * @brief allows the application to validate an item prior to broadcasting to peers.
       *
       * @param sync_mode true if the message was fetched through the sync process, false during normal operation
       * @returns true if this message caused the blockchain to switch forks, false if it did not
       *
       * @throws exception if error validating the item, otherwise the item is safe to broadcast on.
       */
      virtual bool handle_block(const graphene::net::block_message& blk_msg, bool sync_mode,
                                std::vector<fc::uint160_t>& contained_transaction_message_ids) override
      { try {

         auto latency = graphene::time::now() - blk_msg.block.timestamp;
         if (!sync_mode || blk_msg.block.block_num() % 10000 == 0)
         {
            const auto& witness = blk_msg.block.witness(*_chain_db);
            const auto& witness_account = witness.witness_account(*_chain_db);
            auto last_irr = _chain_db->get_dynamic_global_properties().last_irreversible_block_num;
            ilog("Got block: #${n} time: ${t} latency: ${l} ms from: ${w}  irreversible: ${i} (-${d})", 
                 ("t",blk_msg.block.timestamp)
                 ("n", blk_msg.block.block_num())
                 ("l", (latency.count()/1000))
                 ("w",witness_account.name)
                 ("i",last_irr)("d",blk_msg.block.block_num()-last_irr) );
         }

         try {
            // TODO: in the case where this block is valid but on a fork that's too old for us to switch to,
            // you can help the network code out by throwing a block_older_than_undo_history exception.
            // when the net code sees that, it will stop trying to push blocks from that chain, but
            // leave that peer connected so that they can get sync blocks from us
            bool result = _chain_db->push_block(blk_msg.block, (_is_block_producer | _force_validate) ? database::skip_nothing : database::skip_transaction_signatures);

            // the block was accepted, so we now know all of the transactions contained in the block
            if (!sync_mode)
            {
               // if we're not in sync mode, there's a chance we will be seeing some transactions
               // included in blocks before we see the free-floating transaction itself.  If that
               // happens, there's no reason to fetch the transactions, so  construct a list of the
               // transaction message ids we no longer need.
               // during sync, it is unlikely that we'll see any old
               for (const processed_transaction& transaction : blk_msg.block.transactions)
               {
                  graphene::net::trx_message transaction_message(transaction);
                  contained_transaction_message_ids.push_back(graphene::net::message(transaction_message).id());
               }
            }

            return result;
         } catch ( const graphene::chain::unlinkable_block_exception& e ) {
            // translate to a graphene::net exception
            elog("Error when pushing block:\n${e}", ("e", e.to_detail_string()));
            FC_THROW_EXCEPTION(graphene::net::unlinkable_block_exception, "Error when pushing block:\n${e}", ("e", e.to_detail_string()));
         } catch( const fc::exception& e ) {
            elog("Error when pushing block:\n${e}", ("e", e.to_detail_string()));
            throw;
         }

         if( !_is_finished_syncing && !sync_mode )
         {
            _is_finished_syncing = true;
            _self->syncing_finished();
         }
      } FC_CAPTURE_AND_RETHROW( (blk_msg)(sync_mode) ) }
Exemplo n.º 5
0
 static void add( fc::sha256::encoder &hasher, std::string const &data )
 {
     if( data.size() < 253 ) {
         char len = data.size();
         hasher.write( &len, sizeof(len) );
     } else {
         FC_THROW_EXCEPTION( fc::invalid_arg_exception, "String '" + data + "' too long" );
     }
     hasher.write( data.c_str(), data.size() );
 }
Exemplo n.º 6
0
 std::vector<fc::ecc::private_key> import_electrum_wallet( const fc::path& wallet_dat, const std::string& passphrase )
 { try {
     std::vector<fc::ecc::private_key> keys;
     electrumwallet wallet( wallet_dat.to_native_ansi_path());
     if( !wallet.ok() ) FC_THROW_EXCEPTION( exception, "invalid electrum wallet");
     wallet.derivekeys( passphrase );
     return wallet.keys();
   }
   FC_RETHROW_EXCEPTIONS( warn, "" )
 }
Exemplo n.º 7
0
 void private_key::sign( const sha1& digest, array<char,2048/8>& sig )const
 {
    FC_ASSERT( (size_t(RSA_size(my->rsa)) <= sizeof(sig)), "Invalid RSA size" ); 
    uint32_t slen = 0;
    if( 1 != RSA_sign( NID_sha1, (uint8_t*)&digest,
                       20, (unsigned char*)&sig, &slen, my->rsa ) )
    {
        FC_THROW_EXCEPTION( exception, "rsa sign failed with ${message}", ("message",fc::string(ERR_error_string( ERR_get_error(),NULL))) );
    }
 }
Exemplo n.º 8
0
void client_impl::debug_advance_time(int32_t delta_time, const std::string& unit /* = "seconds" */)
{
   if (unit == "blocks")
      delta_time *= BTS_BLOCKCHAIN_BLOCK_INTERVAL_SEC;
   else if (unit == "rounds")
      delta_time *= BTS_BLOCKCHAIN_NUM_DELEGATES * BTS_BLOCKCHAIN_BLOCK_INTERVAL_SEC;
   else if (unit != "seconds")
      FC_THROW_EXCEPTION(fc::invalid_arg_exception, "unit must be \"seconds\", \"blocks\", or \"rounds\", was: \"${unit}\"", ("unit", unit));
   bts::blockchain::advance_time(delta_time);
}
Exemplo n.º 9
0
        void remove( const Key& k )
        {
          try
          {
             FC_ASSERT( _db != nullptr );

             std::vector<char> kslice = fc::raw::pack( k );
             ldb::Slice ks( kslice.data(), kslice.size() );
             auto status = _db->Delete( ldb::WriteOptions(), ks );
             if( status.IsNotFound() )
             {
               FC_THROW_EXCEPTION( key_not_found_exception, "unable to find key ${key}", ("key",k) );
             }
             if( !status.ok() )
             {
                 FC_THROW_EXCEPTION( exception, "database error: ${msg}", ("msg", status.ToString() ) );
             }
          } FC_RETHROW_EXCEPTIONS( warn, "error removing ${key}", ("key",k) );
        }
Exemplo n.º 10
0
/**
 * class to represent an in-wasm-memory char array that must be null terminated
 */
inline null_terminated_ptr null_terminated_ptr_impl(interpreter_interface* interface, uint32_t ptr)
{
   char *value = interface->get_validated_pointer(ptr, 1);
   const char* p = value;
   const char* const top_of_memory = interface->memory.data + interface->current_memory_size;
   while(p < top_of_memory)
      if(*p++ == '\0')
         return null_terminated_ptr(value);

   FC_THROW_EXCEPTION(wasm_execution_error, "unterminated string");
}
Exemplo n.º 11
0
        iterator begin() 
        { try {
           iterator itr( _db->NewIterator( ldb::ReadOptions() ) );
           itr._it->SeekToFirst();

           if( itr._it->status().IsNotFound() )
           {
             FC_THROW_EXCEPTION( key_not_found_exception, "" );
           }
           if( !itr._it->status().ok() )
           {
               FC_THROW_EXCEPTION( exception, "database error: ${msg}", ("msg", itr._it->status().ToString() ) );
           }

           if( itr.valid() )
           {
              return itr;
           }
           return iterator();
        } FC_RETHROW_EXCEPTIONS( warn, "error seeking to first" ) }
Exemplo n.º 12
0
   pts_address::pts_address( const std::string& base58str )
   {
      std::vector<char> v = fc::from_base58( fc::string(base58str) );
      if( v.size() )
         memcpy( addr.data, v.data(), std::min<size_t>( v.size(), sizeof(addr) ) );

      if( !is_valid() )
      {
         FC_THROW_EXCEPTION( exception, "invalid pts_address ${a}", ("a", base58str) );  
      }
   }
Exemplo n.º 13
0
        Value fetch( const Key& key )
        { try {
           FC_ASSERT( is_open(), "Database is not open!" );

           ldb::Slice key_slice( (char*)&key, sizeof(key) );
           std::string value;
           auto status = _db->Get( _read_options, key_slice, &value );
           if( status.IsNotFound() )
           {
             FC_THROW_EXCEPTION( fc::key_not_found_exception, "unable to find key ${key}", ("key",key) );
           }
           if( !status.ok() )
           {
               FC_THROW_EXCEPTION( level_pod_map_failure, "database error: ${msg}", ("msg", status.ToString() ) );
           }
           fc::datastream<const char*> datastream(value.c_str(), value.size());
           Value tmp;
           fc::raw::unpack(datastream, tmp);
           return tmp;
        } FC_RETHROW_EXCEPTIONS( warn, "error fetching key ${key}", ("key",key) ); }
Exemplo n.º 14
0
 Value fetch( const Key& key )
 {
   try {
      ldb::Slice key_slice( (char*)&key, sizeof(key) );
      std::string value;
      auto status = _db->Get( ldb::ReadOptions(), key_slice, &value );
      if( status.IsNotFound() )
      {
        FC_THROW_EXCEPTION( key_not_found_exception, "unable to find key ${key}", ("key",key) );
      }
      if( !status.ok() )
      {
          FC_THROW_EXCEPTION( exception, "database error: ${msg}", ("msg", status.ToString() ) );
      }
      fc::datastream<const char*> datastream(value.c_str(), value.size());
      Value tmp;
      fc::raw::unpack(datastream, tmp);
      return tmp;
   } FC_RETHROW_EXCEPTIONS( warn, "error fetching key ${key}", ("key",key) );
 }
Exemplo n.º 15
0
        Value fetch( const Key& k )
        { try {
           FC_ASSERT( is_open(), "Database is not open!" );

           std::vector<char> kslice = fc::raw::pack( k );
           ldb::Slice ks( kslice.data(), kslice.size() );
           std::string value;
           auto status = _db->Get( ldb::ReadOptions(), ks, &value );
           if( status.IsNotFound() )
           {
             FC_THROW_EXCEPTION( fc::key_not_found_exception, "unable to find key ${key}", ("key",k) );
           }
           if( !status.ok() )
           {
               FC_THROW_EXCEPTION( db_exception, "database error: ${msg}", ("msg", status.ToString() ) );
           }
           fc::datastream<const char*> ds(value.c_str(), value.size());
           Value tmp;
           fc::raw::unpack(ds, tmp);
           return tmp;
        } FC_RETHROW_EXCEPTIONS( warn, "error fetching key ${key}", ("key",k) ); }
Exemplo n.º 16
0
 asset& asset::operator -= ( const asset& o )
 {
    FC_ASSERT( asset_id == o.asset_id );
    auto old = *this;;
    amount -= o.amount;
    if( amount > old.amount ) 
    {
       FC_THROW_EXCEPTION( addition_underthrow, "asset addition underflow  ${a} - ${b} = ${c}", 
                           ("a", old)("b",o)("c",*this) );
    }
    return *this;
 }
Exemplo n.º 17
0
 fc::variant parseInt( const std::string& token, size_t start )
 {
     static const CharValueTable ctbl;
     static const uint64_t INT64_MAX_PLUS_ONE = static_cast<uint64_t>(INT64_MAX) + 1;
     
     size_t i = start, n = token.length();
     if( i >= n )
         FC_THROW_EXCEPTION( parse_error_exception, "zero-length integer" );
     
     uint64_t val = 0;
     uint64_t maxb4mul = UINT64_MAX / base;
     
     while(true)
     {
         char c = token[i];
         uint8_t vc = ctbl[c];
         if( vc == 0xFF )
             FC_THROW_EXCEPTION( parse_error_exception, "illegal character {c} in integer of base {b}", ("c", c)("b", base) );
         if( val > maxb4mul )
             FC_THROW_EXCEPTION( parse_error_exception, "integer literal overflow" );
         val *= base;
         uint64_t newval = val + vc;
         if( newval < val )
             FC_THROW_EXCEPTION( parse_error_exception, "integer literal overflow" );
         val = newval;
         i++;
         if( i >= n )
             break;
     }
     if( token[0] == '-' )
     {
         if( val > INT64_MAX_PLUS_ONE )
             FC_THROW_EXCEPTION( parse_error_exception, "negative integer literal overflow" );
         // special cased to avoid trying to compute -INT64_MIN which is probably undefined or something
         if( val == INT64_MAX_PLUS_ONE )
             return fc::variant( INT64_MIN );
         return fc::variant( -static_cast<int64_t>(val) );
     }
     return fc::variant( val );
 }
Exemplo n.º 18
0
block_id_type block_database::fetch_block_id( uint32_t block_num )const
{
   index_entry e;
   auto index_pos = sizeof(e)*block_num;
   _block_num_to_pos.seekg( 0, _block_num_to_pos.end );
   if ( _block_num_to_pos.tellg() <= index_pos )
      FC_THROW_EXCEPTION(fc::key_not_found_exception, "Block number ${block_num} not contained in block database", ("block_num", block_num));

   _block_num_to_pos.seekg( index_pos );
   _block_num_to_pos.read( (char*)&e, sizeof(e) );

   return e.block_id;
}
Exemplo n.º 19
0
        iterator begin()
        { try {
           FC_ASSERT( is_open(), "Database is not open!" );

           iterator itr( _db->NewIterator( _iter_options ) );
           itr._it->SeekToFirst();

           if( itr._it->status().IsNotFound() )
           {
             FC_THROW_EXCEPTION( fc::key_not_found_exception, "" );
           }
           if( !itr._it->status().ok() )
           {
               FC_THROW_EXCEPTION( level_pod_map_failure, "database error: ${msg}", ("msg", itr._it->status().ToString() ) );
           }

           if( itr.valid() )
           {
              return itr;
           }
           return iterator();
        } FC_RETHROW_EXCEPTIONS( warn, "error seeking to first" ) }
Exemplo n.º 20
0
      electrumwallet( std::string path ):encryption(false),seed_version(""),masterkey("")
      {
         std::ifstream in(path, std::ios_base::in);
         std::string storage;
         in.unsetf( std::ios::skipws );
         std::copy( std::istream_iterator<char>(in),
                    std::istream_iterator<char>(),
                    std::back_inserter(storage) );

         bts::parser<std::string::const_iterator> grammar;
         bts::python_dict_type_t dict;

         std::string::const_iterator iter = storage.begin();
         std::string::const_iterator end = storage.end();
         bool r = phrase_parse( iter, end, grammar, ascii::space, dict );

         if( r && iter == end )
         {
            for( auto &item : dict.items )
            {
               boost::to_lower( item.first );
               if( item.first == "use_encryption" )
               {
                  auto useenc = boost::get<std::string>( item.second );
                  boost::to_lower(useenc);
                  if ( useenc == "true" )
                     encryption = true;
               }
               else if( item.first == "seed_version" )
               {
                  seed_version = boost::get<std::string>( item.second );
               }
               else if( item.first == "seed" )
               {
                  seed = boost::get<std::string>( item.second );
               }
               else if( item.first == "master_public_key" )
               {
                  masterkey = boost::get<std::string>( item.second );
               }
               else if( item.first == "accounts" )
               {
                  accounts.items = boost::get<bts::python_dict_type_t>( item.second ).items;
               }
            }
         }
         else
         {
            FC_THROW_EXCEPTION( exception, "failed to parse electrum wallet" );
         }
      }
Exemplo n.º 21
0
 public_key::public_key( const public_key_data& dat )
 {
   const char* front = &dat.data[0];
   if( *front == 0 ){}
   else
   {
      my->_key = EC_KEY_new_by_curve_name( NID_secp256k1 );
      my->_key = o2i_ECPublicKey( &my->_key, (const unsigned char**)&front, sizeof(public_key_data) );
      if( !my->_key )
      {
        FC_THROW_EXCEPTION( exception, "error decoding public key", ("s", ERR_error_string( ERR_get_error(), nullptr) ) );
      }
   }
 }
Exemplo n.º 22
0
 bytes public_key::encrypt( const char* b, size_t l )const
 {
    FC_ASSERT( my && my->rsa );
    bytes out( RSA_size(my->rsa) ); //, char(0) );
    int rtn = RSA_public_encrypt( l,
                                   (unsigned char*)b,
                                   (unsigned char*)out.data(),
                                   my->rsa, RSA_PKCS1_OAEP_PADDING );
    if( rtn >= 0 ) {
       out.resize(rtn);
       return out;
    }
    FC_THROW_EXCEPTION( exception, "openssl: ${message}", ("message",fc::string(ERR_error_string( ERR_get_error(),NULL))) );
 }
Exemplo n.º 23
0
        void store( const Key& k, const Value& v, bool sync = false )
        { try {
           FC_ASSERT( is_open(), "Database is not open!" );

           ldb::Slice ks( (char*)&k, sizeof(k) );
           auto vec = fc::raw::pack(v);
           ldb::Slice vs( vec.data(), vec.size() );

           auto status = _db->Put( sync ? _sync_options : _write_options, ks, vs );
           if( !status.ok() )
           {
               FC_THROW_EXCEPTION( level_pod_map_failure, "database error: ${msg}", ("msg", status.ToString() ) );
           }
        } FC_RETHROW_EXCEPTIONS( warn, "error storing ${key} = ${value}", ("key",k)("value",v) ); }
Exemplo n.º 24
0
  asset& asset::operator += ( const asset& o )
  {
     FC_ASSERT( unit == o.unit );

     auto old = *this;
     amount += o.amount;

     if( amount < old.amount ) 
     {
       FC_THROW_EXCEPTION( exception, "asset addition overflowed  ${a} + ${b} = ${c}", 
                            ("a", old)("b",o)("c",*this) );
     }
     return *this;
  }
Exemplo n.º 25
0
            fc::variant interactive_open_wallet()
            {
              if( _client->get_wallet()->is_open() ) return fc::variant( true );

              std::cout << "A wallet must be open to execute this command. You can:\n";
              std::cout << "(o) Open an existing wallet\n";
              std::cout << "(c) Create a new wallet\n";
              std::cout << "(q) Abort command\n";

              std::string choice = _self->get_line("Choose [o/c/q]: ");

              if (choice == "c")
              {
                std::string wallet_name = _self->get_line("new wallet name [default]: ");
                if (wallet_name.empty()) wallet_name = "default";

                fc::variants arguments { wallet_name };
                try
                {
                    return execute_interactive_command( "wallet_create", arguments );
                }
                catch( const fc::canceled_exception& )
                {
                }
              }
              else if (choice == "o")
              {
                std::string wallet_name = _self->get_line("wallet name [default]: ");
                if (wallet_name.empty()) wallet_name = "default";

                fc::variants arguments { wallet_name };
                try
                {
                    return execute_interactive_command( "wallet_open", arguments );
                }
                catch( const fc::canceled_exception& )
                {
                }
              }
              else if (choice == "q")
              {
                FC_THROW_EXCEPTION(canceled_exception, "");
              }
              else
              {
                  std::cout << "Wrong answer!\n";
              }

              return fc::variant( false );
            }
Exemplo n.º 26
0
block_id_type block_database::fetch_block_id( uint32_t block_num )const
{
   assert( block_num != 0 );
   index_entry e;
   int64_t index_pos = sizeof(e) * int64_t(block_num);
   _block_num_to_pos.seekg( 0, _block_num_to_pos.end );
   if ( _block_num_to_pos.tellg() <= index_pos )
      FC_THROW_EXCEPTION(fc::key_not_found_exception, "Block number ${block_num} not contained in block database", ("block_num", block_num));

   _block_num_to_pos.seekg( index_pos );
   _block_num_to_pos.read( (char*)&e, sizeof(e) );

   FC_ASSERT( e.block_id != block_id_type(), "Empty block_id in block_database (maybe corrupt on disk?)" );
   return e.block_id;
}
Exemplo n.º 27
0
 void store( const Key& k, const Value& v )
 {
   try
   {
      ldb::Slice ks( (char*)&k, sizeof(k) );
      auto vec = fc::raw::pack(v);
      ldb::Slice vs( vec.data(), vec.size() );
      
      auto status = _db->Put( ldb::WriteOptions(), ks, vs );
      if( !status.ok() )
      {
          FC_THROW_EXCEPTION( exception, "database error: ${msg}", ("msg", status.ToString() ) );
      }
   } FC_RETHROW_EXCEPTIONS( warn, "error storing ${key} = ${value}", ("key",k)("value",v) );
 }
Exemplo n.º 28
0
   std::string stringFromStream( T& in )
   {
      fc::stringstream token;
      try
      {
         char c = in.peek();

         if( c != '"' )
            FC_THROW_EXCEPTION( parse_error_exception,
                                            "Expected '\"' but read '${char}'",
                                            ("char", string(&c, (&c) + 1) ) );
         in.get();
         while( true )
         {

            switch( c = in.peek() )
            {
               case '\\':
                  token << parseEscape( in );
                  break;
               case 0x04:
                  FC_THROW_EXCEPTION( parse_error_exception, "EOF before closing '\"' in string '${token}'",
                                                   ("token", token.str() ) );
               case '"':
                  in.get();
                  return token.str();
               default:
                  token << c;
                  in.get();
            }
         }
         FC_THROW_EXCEPTION( parse_error_exception, "EOF before closing '\"' in string '${token}'",
                                          ("token", token.str() ) );
       } FC_RETHROW_EXCEPTIONS( warn, "while parsing token '${token}'",
                                          ("token", token.str() ) );
   }
Exemplo n.º 29
0
      /**
       * @brief allows the application to validate an item prior to broadcasting to peers.
       *
       * @param sync_mode true if the message was fetched through the sync process, false during normal operation
       * @returns true if this message caused the blockchain to switch forks, false if it did not
       *
       * @throws exception if error validating the item, otherwise the item is safe to broadcast on.
       */
      virtual bool handle_block(const graphene::net::block_message& blk_msg, bool sync_mode,
                                std::vector<fc::uint160_t>& contained_transaction_message_ids) override
      { try {

         if (sync_mode && blk_msg.block.block_num() % 10000 == 0)
         {
            ilog("Syncing Blockchain --- Got block: #${n} time: ${t}",
                 ("t",blk_msg.block.timestamp)
                 ("n", blk_msg.block.block_num()) );
         }

         time_point_sec now = graphene::time::now();

         uint64_t max_accept_time = now.sec_since_epoch();
         max_accept_time += allow_future_time;
         FC_ASSERT( blk_msg.block.timestamp.sec_since_epoch() <= max_accept_time );

         try {
            // TODO: in the case where this block is valid but on a fork that's too old for us to switch to,
            // you can help the network code out by throwing a block_older_than_undo_history exception.
            // when the net code sees that, it will stop trying to push blocks from that chain, but
            // leave that peer connected so that they can get sync blocks from us
            bool result = _chain_db->push_block(blk_msg.block, (_is_block_producer | _force_validate) ? database::skip_nothing : database::skip_transaction_signatures);

            if( !sync_mode && blk_msg.block.transactions.size() )
            {
               ilog( "Got ${t} transactions from network on block ${b}",
                  ("t", blk_msg.block.transactions.size())
                  ("b", blk_msg.block.block_num()) );
            }

            return result;
         } catch ( const steemit::chain::unlinkable_block_exception& e ) {
            // translate to a graphene::net exception
            elog("Error when pushing block:\n${e}", ("e", e.to_detail_string()));
            FC_THROW_EXCEPTION(graphene::net::unlinkable_block_exception, "Error when pushing block:\n${e}", ("e", e.to_detail_string()));
         } catch( const fc::exception& e ) {
            elog("Error when pushing block:\n${e}", ("e", e.to_detail_string()));
            throw;
         }


         if( !_is_finished_syncing && !sync_mode )
         {
            _is_finished_syncing = true;
            _self->syncing_finished();
         }
      } FC_CAPTURE_AND_RETHROW( (blk_msg)(sync_mode) ) }
Exemplo n.º 30
0
        void store( const Key& k, const Value& v, bool sync = false )
        { try {
           FC_ASSERT( is_open(), "Database is not open!" );

           std::vector<char> kslice = fc::raw::pack( k );
           ldb::Slice ks( kslice.data(), kslice.size() );

           auto vec = fc::raw::pack(v);
           ldb::Slice vs( vec.data(), vec.size() );

           auto status = _db->Put( ldb::WriteOptions(), ks, vs );
           if( !status.ok() )
           {
               FC_THROW_EXCEPTION( db_exception, "database error: ${msg}", ("msg", status.ToString() ) );
           }
        } FC_RETHROW_EXCEPTIONS( warn, "error storing ${key} = ${value}", ("key",k)("value",v) ); }