コード例 #1
0
std::error_code createTransfers(
  const AccountKeys& account,
  const TransactionBlockInfo& blockInfo,
  const ITransactionReader& tx,
  const std::vector<uint32_t>& outputs,
  const std::vector<uint32_t>& globalIdxs,
  std::vector<TransactionOutputInformationIn>& transfers) {

  auto txPubKey = tx.getTransactionPublicKey();

  for (auto idx : outputs) {

    if (idx >= tx.getOutputCount()) {
      return std::make_error_code(std::errc::argument_out_of_domain);
    }

    auto outType = tx.getOutputType(size_t(idx));

    if (
      outType != TransactionTypes::OutputType::Key) {
      continue;
    }

    TransactionOutputInformationIn info;

    info.type = outType;
    info.transactionPublicKey = txPubKey;
    info.outputInTransaction = idx;
    info.globalOutputIndex = (blockInfo.height == WALLET_UNCONFIRMED_TRANSACTION_HEIGHT) ?
      UNCONFIRMED_TRANSACTION_GLOBAL_OUTPUT_INDEX : globalIdxs[idx];

    if (outType == TransactionTypes::OutputType::Key) {
      uint64_t amount;
      KeyOutput out;
      tx.getOutput(idx, out, amount);

      CryptoNote::KeyPair in_ephemeral;
      CryptoNote::generate_key_image_helper(
        account,
        txPubKey,
        idx,
        in_ephemeral,
        info.keyImage);

      assert(out.key == reinterpret_cast<const PublicKey&>(in_ephemeral.publicKey));

      info.amount = amount;
      info.outputKey = out.key;

    }

    transfers.push_back(info);
  }

  return std::error_code();
}
コード例 #2
0
std::error_code TransfersConsumer::processOutputs(const BlockInfo& blockInfo, TransfersSubscription& sub, 
  const ITransactionReader& tx, const std::vector<uint32_t>& outputs, const std::vector<uint64_t>& globalIdxs) {

  if (blockInfo.height != UNCONFIRMED_TRANSACTION_HEIGHT) {
    TransactionInformation subscribtionTxInfo;
    int64_t txBalance;
    if (sub.getContainer().getTransactionInformation(tx.getTransactionHash(), subscribtionTxInfo, txBalance)) {
      if (subscribtionTxInfo.blockHeight == UNCONFIRMED_TRANSACTION_HEIGHT) {
        // pool->blockchain
        sub.markTransactionConfirmed(blockInfo, tx.getTransactionHash(), globalIdxs);
        return std::error_code();
      } else {
        // - Subscription already has this transaction as confirmed, so why are we here?
        // - Because, for instance, some another subscription doesn't have this transactions, so it is given to us again.
        return std::error_code();
      }
    }
  }
  
  std::vector<TransactionOutputInformationIn> transfers;

  auto txPubKey = tx.getTransactionPublicKey();

  for (auto idx : outputs) {

    if (idx >= tx.getOutputCount()) {
      return std::make_error_code(std::errc::argument_out_of_domain);
    }

    auto outType = tx.getOutputType(size_t(idx));

    if (
      outType != TransactionTypes::OutputType::Key &&
      outType != TransactionTypes::OutputType::Multisignature) {
      continue;
    }

    TransactionOutputInformationIn info;

    info.type = outType;
    info.transactionPublicKey = txPubKey;
    info.outputInTransaction = idx;
    info.globalOutputIndex =
      (blockInfo.height == UNCONFIRMED_TRANSACTION_HEIGHT) ?
      UNCONFIRMED_TRANSACTION_GLOBAL_OUTPUT_INDEX :
      globalIdxs[idx];

    if (outType == TransactionTypes::OutputType::Key) {
      TransactionTypes::OutputKey out;
      tx.getOutput(idx, out);

      cryptonote::KeyPair in_ephemeral;
      cryptonote::generate_key_image_helper(
        reinterpret_cast<const cryptonote::account_keys&>(sub.getKeys()),
        reinterpret_cast<const crypto::public_key&>(txPubKey),
        idx,
        in_ephemeral,
        reinterpret_cast<crypto::key_image&>(info.keyImage));

      assert(out.key == reinterpret_cast<const PublicKey&>(in_ephemeral.pub));

      info.amount = out.amount;
      info.outputKey = out.key;

    } else if (outType == TransactionTypes::OutputType::Multisignature) {
      TransactionTypes::OutputMultisignature out;
      tx.getOutput(idx, out);

      info.amount = out.amount;
      info.requiredSignatures = out.requiredSignatures;
    }

    transfers.push_back(info);
  }

  sub.addTransaction(blockInfo, tx, transfers);

  return std::error_code();
}