コード例 #1
0
   void transaction_evaluation_state::evaluate( const signed_transaction& trx_arg )
   { try {
      reset();

      auto trx_id = trx_arg.id();
      otransaction_location current_loc = _current_state->get_transaction_location( trx_id );
      if( !!current_loc )
         fail( BTS_DUPLICATE_TRANSACTION, "transaction has already been processed" );

      trx = trx_arg;
      auto digest = trx_arg.digest();
      for( auto sig : trx.signatures )
      {
         auto key = fc::ecc::public_key( sig, digest ).serialize();
         signed_keys.insert( address(key) );
         signed_keys.insert( address(pts_address(key,false,56) ) );
         signed_keys.insert( address(pts_address(key,true,56) )  );
         signed_keys.insert( address(pts_address(key,false,0) )  );
         signed_keys.insert( address(pts_address(key,true,0) )   );
      }
      for( auto op : trx.operations )
      {
         evaluate_operation( op );
      }
      post_evaluate();
      validate_required_fee();
      update_delegate_votes();
   } FC_RETHROW_EXCEPTIONS( warn, "", ("trx",trx_arg) ) }
コード例 #2
0
   void transaction_evaluation_state::evaluate( const signed_transaction& trx_arg, bool skip_signature_check, bool enforce_canonical )
   { try {
      _skip_signature_check = skip_signature_check;
      try {
        if( _current_state->now() >= trx_arg.expiration )
        {
           if( _current_state->now() > trx_arg.expiration || _current_state->get_head_block_num() >= BTS_V0_4_21_FORK_BLOCK_NUM )
           {
               const auto expired_by_sec = (_current_state->now() - trx_arg.expiration).to_seconds();
               FC_CAPTURE_AND_THROW( expired_transaction, (trx_arg)(_current_state->now())(expired_by_sec) );
           }
        }
        if( (_current_state->now() + BTS_BLOCKCHAIN_MAX_TRANSACTION_EXPIRATION_SEC) < trx_arg.expiration )
           FC_CAPTURE_AND_THROW( invalid_transaction_expiration, (trx_arg)(_current_state->now()) );

        auto trx_id = trx_arg.id();

        if( _current_state->is_known_transaction( trx_arg.expiration, trx_arg.digest( _chain_id ) ) )
          if (_current_state->get_head_block_num() >= FORK_25)
            FC_CAPTURE_AND_THROW( duplicate_transaction, (trx_id) );

        trx = trx_arg;
        if( !_skip_signature_check )
        {
           auto digest = trx_arg.digest( _chain_id );
           for( const auto& sig : trx.signatures )
           {
              auto key = fc::ecc::public_key( sig, digest, enforce_canonical ).serialize();
              signed_keys.insert( address(key) );
              signed_keys.insert( address(pts_address(key,false,56) ) );
              signed_keys.insert( address(pts_address(key,true,56) )  );
              signed_keys.insert( address(pts_address(key,false,0) )  );
              signed_keys.insert( address(pts_address(key,true,0) )   );
           }
        }
        current_op_index = 0;
        for( const auto& op : trx.operations )
        {
           evaluate_operation( op );
           ++current_op_index;
        }
        post_evaluate();
        validate_required_fee();
        update_delegate_votes();
      }
      catch ( const fc::exception& e )
      {
         validation_error = e;
         throw;
      }
   } FC_RETHROW_EXCEPTIONS( warn, "", ("trx",trx_arg) ) }
コード例 #3
0
ファイル: transaction.cpp プロジェクト: 8001800/graphene
 bool signed_by( const address& a ) {
    if( !available_address_sigs ) {
       available_address_sigs = std::map<address,public_key_type>();
       provided_address_sigs = std::map<address,public_key_type>();
       for( auto& item : available_keys ) {
        (*available_address_sigs)[ address(pts_address(item, false, 56) ) ] = item;
        (*available_address_sigs)[ address(pts_address(item, true, 56) ) ] = item;
        (*available_address_sigs)[ address(pts_address(item, false, 0) ) ] = item;
        (*available_address_sigs)[ address(pts_address(item, true, 0) ) ] = item;
        (*available_address_sigs)[ address(item) ] = item;
       }
       for( auto& item : provided_signatures ) {
        (*provided_address_sigs)[ address(pts_address(item.first, false, 56) ) ] = item.first;
        (*provided_address_sigs)[ address(pts_address(item.first, true, 56) ) ] = item.first;
        (*provided_address_sigs)[ address(pts_address(item.first, false, 0) ) ] = item.first;
        (*provided_address_sigs)[ address(pts_address(item.first, true, 0) ) ] = item.first;
        (*provided_address_sigs)[ address(item.first) ] = item.first;
       }
    }
    auto itr = provided_address_sigs->find(a);
    if( itr == provided_address_sigs->end() )
    {
       auto aitr = available_address_sigs->find(a);
       if( aitr != available_address_sigs->end() ) {
          auto pk = available_keys.find(aitr->second);
          if( pk != available_keys.end() )
             return provided_signatures[aitr->second] = true;
          return false;
       }
    }
    return provided_signatures[itr->second] = true;
 }
コード例 #4
0
   void transaction_evaluation_state::evaluate( const signed_transaction& trx_arg, bool skip_signature_check )
   { try {
      reset();
      _skip_signature_check = skip_signature_check;
      try {
        if( trx_arg.expiration < _current_state->now() )
        {
           auto expired_by_sec = (trx_arg.expiration - _current_state->now()).to_seconds();
           FC_CAPTURE_AND_THROW( expired_transaction, (trx_arg)(_current_state->now())(expired_by_sec) );
        }
        if( trx_arg.expiration > (_current_state->now() + BTS_BLOCKCHAIN_MAX_TRANSACTION_EXPIRATION_SEC) )
           FC_CAPTURE_AND_THROW( invalid_transaction_expiration, (trx_arg)(_current_state->now()) );

        auto trx_size = fc::raw::pack_size(trx_arg);
        if(  trx_size > BTS_BLOCKCHAIN_MAX_TRANSACTION_SIZE )
           FC_CAPTURE_AND_THROW( oversized_transaction, (trx_size ) );
       
        auto trx_id = trx_arg.id();

        if( _current_state->is_known_transaction( trx_id ) )
           FC_CAPTURE_AND_THROW( duplicate_transaction, (trx_id) );
       
        trx = trx_arg;
        if( !_skip_signature_check )
        {
           auto digest = trx_arg.digest( _chain_id );
           for( auto sig : trx.signatures )
           {
              auto key = fc::ecc::public_key( sig, digest ).serialize();
              signed_keys.insert( address(key) );
              signed_keys.insert( address(pts_address(key,false,56) ) );
              signed_keys.insert( address(pts_address(key,true,56) )  );
              signed_keys.insert( address(pts_address(key,false,0) )  );
              signed_keys.insert( address(pts_address(key,true,0) )   );
           }
        }
        for( auto op : trx.operations )
        {
           evaluate_operation( op );
        }
        post_evaluate();
        validate_required_fee();
        update_delegate_votes();
      } 
      catch ( const fc::exception& e )
      {
         validation_error = e;
         throw;
      }
   } FC_RETHROW_EXCEPTIONS( warn, "", ("trx",trx_arg) ) }
コード例 #5
0
void_result balance_claim_evaluator::do_evaluate(const balance_claim_operation& op)
{
   database& d = db();
   balance = &op.balance_to_claim(d);

   GRAPHENE_ASSERT(
             op.balance_owner_key == balance->owner ||
             pts_address(op.balance_owner_key, false, 56) == balance->owner ||
             pts_address(op.balance_owner_key, true, 56) == balance->owner ||
             pts_address(op.balance_owner_key, false, 0) == balance->owner ||
             pts_address(op.balance_owner_key, true, 0) == balance->owner,
             balance_claim_owner_mismatch,
             "Balance owner key was specified as '${op}' but balance's actual owner is '${bal}'",
             ("op", op.balance_owner_key)
             ("bal", balance->owner)
             );
   if( !(d.get_node_properties().skip_flags & (database::skip_authority_check |
                                               database::skip_transaction_signatures)) )

   FC_ASSERT(op.total_claimed.asset_id == balance->asset_type());

   if( balance->is_vesting_balance() )
   {
      GRAPHENE_ASSERT(
         balance->vesting_policy->is_withdraw_allowed(
            { balance->balance,
              d.head_block_time(),
              op.total_claimed } ),
         balance_claim_invalid_claim_amount,
         "Attempted to claim ${c} from a vesting balance with ${a} available",
         ("c", op.total_claimed)("a", balance->available(d.head_block_time()))
         );
      GRAPHENE_ASSERT(
         d.head_block_time() - balance->last_claim_date >= fc::days(1),
         balance_claim_claimed_too_often,
         "Genesis vesting balances may not be claimed more than once per day."
         );
      return {};
   }

   FC_ASSERT(op.total_claimed == balance->balance);
   return {};
}
コード例 #6
0
ファイル: transaction.cpp プロジェクト: NimroDeer/BitShares
std::unordered_set<bts::pts_address> signed_transaction::get_signed_pts_addresses()const
{
    auto dig = digest();
    std::unordered_set<pts_address> r;
    // add both compressed and uncompressed forms...
    for( auto itr = sigs.begin(); itr != sigs.end(); ++itr )
    {
        auto signed_key_data = fc::ecc::public_key( *itr, dig ).serialize();
        auto signed_key_point = fc::ecc::public_key( *itr, dig ).serialize_ecc_point();


        // note: 56 is the version bit of protoshares
        r.insert( pts_address(fc::ecc::public_key( signed_key_data),false,56) );
        r.insert( pts_address(fc::ecc::public_key( signed_key_data ),true,56) );
        // note: 5 comes from en.bitcoin.it/wiki/Vanitygen where version bit is 0
        r.insert( pts_address(fc::ecc::public_key( signed_key_data ),false,0) );
        r.insert( pts_address(fc::ecc::public_key( signed_key_data ),true,0) );
    }
    ilog( "${signed_addr}", ("signed_addr",r) );
    return r;
}
コード例 #7
0
 void transaction_evaluation_state::evaluate( const signed_transaction& trx_arg )
 { try {
    reset();
    try {
      if( trx_arg.expiration && *trx_arg.expiration < _current_state->now() )
         FC_CAPTURE_AND_THROW( expired_transaction, (trx_arg)(_current_state->now()) );
     
      auto trx_id = trx_arg.id();
      ilog( "id: ${id}", ("id",trx_id) );
      otransaction_record known_transaction= _current_state->get_transaction( trx_id );
      if( known_transaction )
         FC_CAPTURE_AND_THROW( duplicate_transaction, (known_transaction) );
     
      trx = trx_arg;
      auto digest = trx_arg.digest( _chain_id );
      for( auto sig : trx.signatures )
      {
         auto key = fc::ecc::public_key( sig, digest ).serialize();
         signed_keys.insert( address(key) );
         signed_keys.insert( address(pts_address(key,false,56) ) );
         signed_keys.insert( address(pts_address(key,true,56) )  );
         signed_keys.insert( address(pts_address(key,false,0) )  );
         signed_keys.insert( address(pts_address(key,true,0) )   );
      }
      for( auto op : trx.operations )
      {
         evaluate_operation( op );
      }
      post_evaluate();
      validate_required_fee();
      update_delegate_votes();
    } 
    catch ( const fc::exception& e )
    {
       validation_error = e;
       throw;
    }
 } FC_RETHROW_EXCEPTIONS( warn, "", ("trx",trx_arg) ) }
コード例 #8
0
   void wallet_db::store_key( const key_data& key_to_store )
   {
      auto key_itr = keys.find( key_to_store.get_address() );
      if( key_itr != keys.end() )
      {
         key_data& old_data = key_itr->second;
         old_data = key_to_store;

         if( key_to_store.has_private_key())
         {
            auto oacct = lookup_account( key_to_store.account_address );
            FC_ASSERT(oacct.valid(), "expecting an account to existing at this point");
            oacct->is_my_account = true;
            store_record( *oacct );
            cache_account( *oacct );
            ilog( "WALLET: storing private key for ${key} under account '${account_name}' address: (${account})",
                  ("key",key_to_store.public_key)
                  ("account",key_to_store.account_address)
                 ("account_name",get_account_name(key_to_store.account_address)) );
         }
         else
         {
            /*
            ilog( "WALLET: storing public key ${key} under account named '${account_name}' address: (${account})",
                  ("key",key_to_store.public_key)
                  ("account",key_to_store.account_address)
                  ("account_name",get_account_name(key_to_store.account_address)) );
                  */
         }
         ilog( "storing key" );

         store_record( key_itr->second, true );
      }
      else
      {
         auto r = wallet_key_record( key_to_store, new_wallet_record_index() );
         store_record( keys[key_to_store.get_address()] = r, true );

         auto key = key_to_store.public_key;
         auto bts_addr = key_to_store.get_address();
         btc_to_bts_address[ address(key) ] = bts_addr;
         btc_to_bts_address[ address(pts_address(key,false,56) )] = bts_addr;
         btc_to_bts_address[ address(pts_address(key,true,56) ) ] = bts_addr;
         btc_to_bts_address[ address(pts_address(key,false,0) ) ] = bts_addr;
         btc_to_bts_address[ address(pts_address(key,true,0) )  ] = bts_addr;
         ilog( "indexing key ${k}", ("k",address(pts_address(key,false,56) )  ) );
         ilog( "indexing key ${k}", ("k",address(pts_address(key,true,56) )  ) );
      }
   }
コード例 #9
0
ファイル: wallet_db.cpp プロジェクト: FlappycoinDEV/bitshares
   void wallet_db::repair_records( const fc::sha512& password )
   { try {
       FC_ASSERT( is_open() );

       vector<generic_wallet_record> records;
       for( auto iter = my->_records.begin(); iter.valid(); ++iter )
           records.push_back( iter.value() );

       // Repair key_data.account_address when possible
       uint32_t count = 0;
       for( generic_wallet_record& record : records )
       {
           try
           {
               if( wallet_record_type_enum( record.type ) == account_record_type )
               {
                   std::cout << "\rRepairing account record " << std::to_string( ++count ) << std::flush;
                   wallet_account_record account_record = record.as<wallet_account_record>();
                   store_account( account_record );
               }
           }
           catch( const fc::exception& )
           {
           }
       }

       // Repair key_data.public_key when I have the private key and remove if I don't have the private key
       count = 0;
       for( generic_wallet_record& record : records )
       {
           try
           {
               if( wallet_record_type_enum( record.type ) == key_record_type )
               {
                   std::cout << "\rRepairing key record     " << std::to_string( ++count ) << std::flush;
                   wallet_key_record key_record = record.as<wallet_key_record>();
                   const address key_address = key_record.get_address();
                   if( key_record.has_private_key() )
                   {
                       const private_key_type private_key = key_record.decrypt_private_key( password );
                       const public_key_type public_key = private_key.get_public_key();
                       if( key_record.public_key != public_key )
                       {
                           keys.erase( key_address );
                           btc_to_bts_address.erase( key_address );
                           btc_to_bts_address.erase( address( pts_address( key_record.public_key, false, 0  ) ) );
                           btc_to_bts_address.erase( address( pts_address( key_record.public_key, true,  0  ) ) );
                           btc_to_bts_address.erase( address( pts_address( key_record.public_key, false, 56 ) ) );
                           btc_to_bts_address.erase( address( pts_address( key_record.public_key, true,  56 ) ) );

                           key_record.public_key = public_key;
                           my->load_key_record( key_record );
                       }
                   }
                   else
                   {
                       keys.erase( key_address );
                       btc_to_bts_address.erase( key_address );
                       btc_to_bts_address.erase( address( pts_address( key_record.public_key, false, 0  ) ) );
                       btc_to_bts_address.erase( address( pts_address( key_record.public_key, true,  0  ) ) );
                       btc_to_bts_address.erase( address( pts_address( key_record.public_key, false, 56 ) ) );
                       btc_to_bts_address.erase( address( pts_address( key_record.public_key, true,  56 ) ) );
                       remove_item( key_record.wallet_record_index );
                       continue;
                   }
                   store_key( key_record );
               }
           }
           catch( const fc::exception& )
           {
           }
       }

       // Repair transaction_data.record_id
       count = 0;
       for( generic_wallet_record& record : records )
       {
           try
           {
               if( wallet_record_type_enum( record.type ) == transaction_record_type )
               {
                   std::cout << "\rRepairing transaction record     " << std::to_string( ++count ) << std::flush;
                   wallet_transaction_record transaction_record = record.as<wallet_transaction_record>();
                   if( transaction_record.trx.id() != signed_transaction().id()  )
                   {
                       const transaction_id_type record_id = transaction_record.trx.id();
                       if( transaction_record.record_id != record_id )
                       {
                           transactions.erase( transaction_record.record_id );
                           id_to_transaction_record_index.erase( transaction_record.record_id );

                           transaction_record.record_id = record_id;
                           my->load_transaction_record( transaction_record );
                       }
                   }
                   store_transaction( transaction_record );
               }
           }
           catch( const fc::exception& )
           {
           }
       }
       std::cout << "\rWallet records repaired.                                  " << std::flush << "\n";
   } FC_CAPTURE_AND_RETHROW() }
コード例 #10
0
ファイル: wallet_db.cpp プロジェクト: drltc/bitshares_toolkit
   void wallet_db::repair_records( const fc::sha512& password )
   { try {
       FC_ASSERT( is_open() );

       vector<generic_wallet_record> records;
       for( auto iter = my->_records.begin(); iter.valid(); ++iter )
           records.push_back( iter.value() );

       // Repair account_data.is_my_account and key_data.account_address
       for( generic_wallet_record& record : records )
       {
           try
           {
               if( wallet_record_type_enum( record.type ) == account_record_type )
               {
                   wallet_account_record account_record = record.as<wallet_account_record>();
                   store_account( account_record );
               }
           }
           catch( ... )
           {
           }
       }

       // Repair key_data.public_key when I have the private key and
       // repair key_data.account_address and account_data.is_my_account
       for( generic_wallet_record& record : records )
       {
           try
           {
               if( wallet_record_type_enum( record.type ) == key_record_type )
               {
                   wallet_key_record key_record = record.as<wallet_key_record>();
                   if( key_record.has_private_key() )
                   {
                       const private_key_type private_key = key_record.decrypt_private_key( password );
                       const public_key_type public_key = private_key.get_public_key();
                       if( key_record.public_key != public_key )
                       {
                           const address key_address = key_record.get_address();
                           keys.erase( key_address );
                           btc_to_bts_address.erase( key_address );
                           btc_to_bts_address.erase( address( pts_address( key_record.public_key, false, 0  ) ) );
                           btc_to_bts_address.erase( address( pts_address( key_record.public_key, true,  0  ) ) );
                           btc_to_bts_address.erase( address( pts_address( key_record.public_key, false, 56 ) ) );
                           btc_to_bts_address.erase( address( pts_address( key_record.public_key, true,  56 ) ) );

                           key_record.public_key = public_key;
                           my->load_key_record( key_record );
                       }
                   }
                   store_key( key_record );
               }
           }
           catch( ... )
           {
           }
       }

       // Repair transaction_data.record_id
       for( generic_wallet_record& record : records )
       {
           try
           {
               if( wallet_record_type_enum( record.type ) == transaction_record_type )
               {
                   wallet_transaction_record transaction_record = record.as<wallet_transaction_record>();
                   if( transaction_record.trx.id() != signed_transaction().id()  )
                   {
                       const transaction_id_type record_id = transaction_record.trx.permanent_id();
                       if( transaction_record.record_id != record_id )
                       {
                           transactions.erase( transaction_record.record_id );
                           id_to_transaction_record_index.erase( transaction_record.record_id );

                           transaction_record.record_id = record_id;
                           my->load_transaction_record( transaction_record );
                       }
                   }
                   store_transaction( transaction_record );
               }
           }
           catch( ... )
           {
           }
       }
   } FC_CAPTURE_AND_RETHROW() }