// Copyright (c) 2011-2016 The Cryptonote developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #pragma once #include "IBlockchainSynchronizer.h" #include "ITransfersSynchronizer.h" #include "TransfersSubscription.h" #include "TypeHelpers.h" #include "crypto/crypto.h" #include "IObservableImpl.h" #include namespace CryptoNote { class INode; class TransfersConsumer: public IObservableImpl { public: TransfersConsumer(const CryptoNote::Currency& currency, INode& node, const Crypto::SecretKey& viewSecret); ITransfersSubscription& addSubscription(const AccountSubscription& subscription); // returns true if no subscribers left bool removeSubscription(const AccountPublicAddress& address); ITransfersSubscription* getSubscription(const AccountPublicAddress& acc); void getSubscriptions(std::vector& subscriptions); void initTransactionPool(const std::unordered_set& uncommitedTransactions); // IBlockchainConsumer virtual SynchronizationStart getSyncStart() override; virtual void onBlockchainDetach(uint32_t height) override; virtual bool onNewBlocks(const CompleteBlock* blocks, uint32_t startHeight, uint32_t count) override; virtual std::error_code onPoolUpdated(const std::vector>& addedTransactions, const std::vector& deletedTransactions) override; virtual const std::unordered_set& getKnownPoolTxIds() const override; virtual std::error_code addUnconfirmedTransaction(const ITransactionReader& transaction) override; virtual void removeUnconfirmedTransaction(const Crypto::Hash& transactionHash) override; private: template void forEachSubscription(F action) { for (const auto& kv : m_subscriptions) { action(*kv.second); } } struct PreprocessInfo { std::unordered_map> outputs; std::vector globalIdxs; }; std::error_code preprocessOutputs(const TransactionBlockInfo& blockInfo, const ITransactionReader& tx, PreprocessInfo& info); std::error_code processTransaction(const TransactionBlockInfo& blockInfo, const ITransactionReader& tx); void processTransaction(const TransactionBlockInfo& blockInfo, const ITransactionReader& tx, const PreprocessInfo& info); void processOutputs(const TransactionBlockInfo& blockInfo, TransfersSubscription& sub, const ITransactionReader& tx, const std::vector& outputs, const std::vector& globalIdxs, bool& contains, bool& updated); std::error_code getGlobalIndices(const Crypto::Hash& transactionHash, std::vector& outsGlobalIndices); void updateSyncStart(); SynchronizationStart m_syncStart; const Crypto::SecretKey m_viewSecret; // map { spend public key -> subscription } std::unordered_map> m_subscriptions; std::unordered_set m_spendKeys; std::unordered_set m_poolTxs; INode& m_node; const CryptoNote::Currency& m_currency; }; }