コード例 #1
0
        public override bool getBlocks(List <Hash> blockHashes, List <BlockDetails> blocks)
        {
            if (state.load() != State.INITIALIZED)
            {
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.NOT_INITIALIZED));
            }

            if (blockHashes.Count == 0)
            {
                return(true);
            }

            logger.functorMethod(DEBUGGING) << "Get blocks by hash request came.";
            NodeRequest new request((INodeOriginal.Callback cb) =>
            {
                node.getBlocks(blockHashes, blocks, cb);
            });
            std::error_code ec = request.performBlocking();

            if (ec != null)
            {
                logger.functorMethod(ERROR) << "Can't get blocks by hash: " << ec.message();
                throw std::system_error(ec);
            }

            Debug.Assert(blocks.Count == blockHashes.Count);
            return(true);
        }
コード例 #2
0
//C++ TO C# CONVERTER TODO TASK: The original C++ template specifier was replaced with a C# generic specifier, which may not produce the same behavior:
//ORIGINAL LINE: template <typename RequestType, typename ResponseType, typename RequestHandler>
        private HandlerFunction jsonHandler <RequestType, ResponseType, RequestHandler>(RequestHandler handler)
        {
//C++ TO C# CONVERTER TODO TASK: Only lambda expressions having all locals passed by reference can be converted to C#:
//ORIGINAL LINE: return [handler, this] (const Common::JsonValue& jsonRpcParams, Common::JsonValue& jsonResponse) mutable
            return((Common.JsonValue jsonRpcParams.functorMethod, Common.JsonValue jsonResponse.functorMethod) => mutable
            {
                RequestType request = new default(RequestType);
                ResponseType response = new default(ResponseType);

                try
                {
//C++ TO C# CONVERTER TODO TASK: There is no equivalent to 'const_cast' in C#:
                    CryptoNote.JsonInputValueSerializer inputSerializer = new CryptoNote.JsonInputValueSerializer(const_cast <Common.JsonValue&>(jsonRpcParams.functorMethod));
                    SerializeRequest(request, inputSerializer.functorMethod);
                }
                catch (System.Exception)
                {
                    makeGenericErrorReponse(jsonResponse.functorMethod, "Invalid Request", -32600);
                    return;
                }

                std::error_code ec = handler(request, response);
                if (ec != null)
                {
                    makeErrorResponse(ec, jsonResponse.functorMethod);
                    return;
                }

                CryptoNote.JsonOutputStreamSerializer outputSerializer = new CryptoNote.JsonOutputStreamSerializer();
                CryptoNote.GlobalMembers.serialize(response, outputSerializer.functorMethod);
                fillJsonResponse(outputSerializer.getValue.functorMethod(), jsonResponse.functorMethod);
            });
コード例 #3
0
        public override bool isSynchronized()
        {
            if (state.load() != State.INITIALIZED)
            {
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.NOT_INITIALIZED));
            }

            logger.functorMethod(DEBUGGING) << "Synchronization status request came.";
            bool syncStatus = false;

            NodeRequest new request((INodeOriginal.Callback cb) =>
            {
                node.isSynchronized(ref syncStatus, cb);
            });
            std::error_code ec = request.performBlocking();

            if (ec != null)
            {
                logger.functorMethod(ERROR) << "Can't get synchronization status: " << ec.message();
                throw std::system_error(ec);
            }

            synchronized.store(syncStatus);
            return(syncStatus);
        }
コード例 #4
0
 public void onError(std::error_code ec, uint height)
 {
     if (height != GlobalMembers.WALLET_UNCONFIRMED_TRANSACTION_HEIGHT)
     {
         transfers.detach(height);
     }
     m_observerManager.notify(ITransfersObserver.onError, this, height, ec);
 }
コード例 #5
0
 public void rename(string newPath, std::error_code ec)
 {
     m_file.rename(newPath, ec);
     if (ec == null)
     {
         m_path = newPath;
     }
 }
コード例 #6
0
 public void close(std::error_code ec)
 {
     m_file.close(ec);
     if (ec == null)
     {
         m_prefixSize = 0;
         m_suffixSize = 0;
         m_path       = "";
     }
 }
コード例 #7
0
        public void close()
        {
            std::error_code ec = new std::error_code();

            close(ec);
            if (ec != null)
            {
                throw std::system_error(ec, "FileMappedVector::close");
            }
        }
コード例 #8
0
ファイル: NodeFactory.cs プロジェクト: ooosbkf/turtlecoin-net
        public void waitForInitEnd()
        {
            std::error_code ec = initFuture.get();

            if (ec != null)
            {
                throw std::system_error(ec);
            }
            return;
        }
コード例 #9
0
        public void open(string path)
        {
            std::error_code ec = new std::error_code();

            open(path, ref ec);
            if (ec != null)
            {
                throw std::system_error(ec, "MemoryMappedFile::open");
            }
        }
コード例 #10
0
        public void close()
        {
            std::error_code ec = new std::error_code();

            close(ref ec);
            if (ec != null)
            {
                throw std::system_error(ec, "MemoryMappedFile::close");
            }
        }
コード例 #11
0
        public void create(string path, uint64_t size, bool overwrite)
        {
            std::error_code ec = new std::error_code();

            create(path, new uint64_t(size), overwrite, ref ec);
            if (ec != null)
            {
                throw std::system_error(ec, "MemoryMappedFile::create");
            }
        }
コード例 #12
0
        private std::error_code preprocessOutputs(TransactionBlockInfo blockInfo, ITransactionReader tx, PreprocessInfo info)
        {
            Dictionary <PublicKey, List <uint> > outputs = new Dictionary <PublicKey, List <uint> >();

            try
            {
                GlobalMembers.findMyOutputs(tx, m_viewSecret, m_spendKeys, outputs);
            }
            catch (System.Exception e)
            {
                m_logger.functorMethod(WARNING, BRIGHT_RED) << "Failed to process transaction: " << e.Message << ", transaction hash " << Common.GlobalMembers.podToHex(tx.GetTransactionHash());
                return(std::error_code());
            }

            if (outputs.Count == 0)
            {
                return(std::error_code());
            }

            std::error_code errorCode = new std::error_code();
            var             txHash    = tx.GetTransactionHash();

            if (blockInfo.height != GlobalMembers.WALLET_UNCONFIRMED_TRANSACTION_HEIGHT)
            {
//C++ TO C# CONVERTER TODO TASK: There is no equivalent to 'reinterpret_cast' in C#:
//C++ TO C# CONVERTER TODO TASK: The following line was determined to be a copy assignment (rather than a reference assignment) - this should be verified and a 'CopyFrom' method should be created:
//ORIGINAL LINE: errorCode = getGlobalIndices(reinterpret_cast<const Hash&>(txHash), info.globalIdxs);
                errorCode.CopyFrom(getGlobalIndices(reinterpret_cast <const Hash&>(txHash), info.globalIdxs));
                if (errorCode != null)
                {
                    return(errorCode);
                }
            }

            foreach (var kv in outputs)
            {
                var it = m_subscriptions.find(kv.first);
//C++ TO C# CONVERTER TODO TASK: Iterators are only converted within the context of 'while' and 'for' loops:
                if (it != m_subscriptions.end())
                {
                    auto transfers = info.outputs[kv.first];
//C++ TO C# CONVERTER TODO TASK: The following line was determined to be a copy assignment (rather than a reference assignment) - this should be verified and a 'CopyFrom' method should be created:
//ORIGINAL LINE: errorCode = createTransfers(it->second->getKeys(), blockInfo, tx, kv.second, info.globalIdxs, transfers, m_logger);
//C++ TO C# CONVERTER TODO TASK: Iterators are only converted within the context of 'while' and 'for' loops:
                    errorCode.CopyFrom(CryptoNote.GlobalMembers.createTransfers(it.second.getKeys(), blockInfo, tx, kv.second, info.globalIdxs, transfers, m_logger.functorMethod));
                    if (errorCode != null)
                    {
                        return(errorCode);
                    }
                }
            }

            return(std::error_code());
        }
コード例 #13
0
        public void flush(uint8_t data, uint64_t size)
        {
            Debug.Assert(isOpened());

            std::error_code ec = new std::error_code();

            flush(data, new uint64_t(size), ref ec);
            if (ec != null)
            {
                throw std::system_error(ec, "MemoryMappedFile::flush");
            }
        }
コード例 #14
0
        public void rename(string newPath)
        {
            Debug.Assert(isOpened());

            std::error_code ec = new std::error_code();

            rename(newPath, ref ec);
            if (ec != null)
            {
                throw std::system_error(ec, "MemoryMappedFile::rename");
            }
        }
コード例 #15
0
        public void open(string path, ref std::error_code ec)
        {
            if (isOpened())
            {
                close(ref ec);
                if (ec != null)
                {
                    return;
                }
            }

//C++ TO C# CONVERTER TODO TASK: Only lambda expressions having all locals passed by reference can be converted to C#:
//ORIGINAL LINE: Tools::ScopeExit failExitHandler([this, &ec]
            Tools.ScopeExit failExitHandler(() =>
            {
                ec = std::error_code(errno, std::system_category());
                std::error_code ignore = new std::error_code();
                close(ref ignore);
            });

            m_file = global::open(path, O_RDWR, S_IRUSR | S_IWUSR);
            if (m_file == -1)
            {
                return;
            }

            stat fileStat = new stat();
            int  result   = global::fstat(m_file, fileStat);

            if (result == -1)
            {
                return;
            }

//C++ TO C# CONVERTER TODO TASK: The following line was determined to be a copy assignment (rather than a reference assignment) - this should be verified and a 'CopyFrom' method should be created:
//ORIGINAL LINE: m_size = static_cast<uint64_t>(fileStat.st_size);
            m_size.CopyFrom((uint64_t)fileStat.st_size);

//C++ TO C# CONVERTER TODO TASK: There is no equivalent to 'reinterpret_cast' in C#:
            m_data = reinterpret_cast <uint8_t>(global::mmap(null, (size_t)m_size, PROT_READ | PROT_WRITE, MAP_SHARED, m_file, 0));
            if (m_data == MAP_FAILED)
            {
                return;
            }

            m_path = path;
            ec     = std::error_code();

            failExitHandler.cancel();
        }
コード例 #16
0
//C++ TO C# CONVERTER TODO TASK: The original C++ template specifier was replaced with a C# generic specifier, which may not produce the same behavior:
//ORIGINAL LINE: template<class F>
//C++ TO C# CONVERTER TODO TASK: 'rvalue references' have no equivalent in C#:
        private void atomicUpdate0 <F>(ulong newCapacity, ulong newPrefixSize, ulong newSuffixSize, F&& func)
        {
            if (m_file.path() != m_path)
            {
                throw new System.Exception("Vector is mapped to a .bak file due to earlier errors");
            }

            boost::filesystem.path bakPath = m_path + ".bak";
            boost::filesystem.path tmpPath = boost::filesystem.unique_path(m_path + ".tmp.%%%%-%%%%");

            if (boost::filesystem.exists(bakPath))
            {
                boost::filesystem.remove(bakPath);
            }

            Tools.ScopeExit tmpFileDeleter(() =>
            {
                boost::system.error_code ignore = new boost::system.error_code();
                boost::filesystem.remove(tmpPath, ignore);
            });

            // Copy file. It is slow but atomic operation
            FileMappedVector <T> tmpVector = new FileMappedVector <T>();

            tmpVector.create(tmpPath.string(), new ulong(newCapacity), new ulong(newPrefixSize), new ulong(newSuffixSize));
            func(tmpVector);
            tmpVector.flush();

            // Swap files
            std::error_code ec     = new std::error_code();
            std::error_code ignore = new std::error_code();

            m_file.rename(bakPath.string());
            tmpVector.rename(m_path, ec);
            if (ec != null)
            {
                // Try to restore and ignore errors
                m_file.rename(m_path, ignore);
                throw std::system_error(ec, "Failed to swap temporary and vector files");
            }

            m_path = bakPath.string();
            swap(tmpVector);
            tmpFileDeleter.cancel();

            // Remove .bak file and ignore errors
            tmpVector.close(ignore);
            boost::system.error_code boostError = new boost::system.error_code();
            boost::filesystem.remove(bakPath, boostError);
        }
コード例 #17
0
        public void rename(string newPath, ref std::error_code ec)
        {
            Debug.Assert(isOpened());

            int result = global::rename(m_path, newPath);

            if (result == 0)
            {
                m_path = newPath;
                ec     = std::error_code();
            }
            else
            {
                ec = std::error_code(errno, std::system_category());
            }
        }
コード例 #18
0
        public override std::error_code onPoolUpdated(List <std::unique_ptr <ITransactionReader> > addedTransactions, List <Hash> deletedTransactions)
        {
            TransactionBlockInfo unconfirmedBlockInfo = new TransactionBlockInfo();

            unconfirmedBlockInfo.timestamp = 0;
            unconfirmedBlockInfo.height    = GlobalMembers.WALLET_UNCONFIRMED_TRANSACTION_HEIGHT;

            std::error_code processingError = new std::error_code();

            foreach (var cryptonoteTransaction in addedTransactions)
            {
                m_poolTxs.emplace(cryptonoteTransaction.getTransactionHash());
//C++ TO C# CONVERTER TODO TASK: The following line was determined to be a copy assignment (rather than a reference assignment) - this should be verified and a 'CopyFrom' method should be created:
//ORIGINAL LINE: processingError = processTransaction(unconfirmedBlockInfo, *cryptonoteTransaction.get());
                processingError.CopyFrom(processTransaction(unconfirmedBlockInfo, *cryptonoteTransaction.get()));
                if (processingError != null)
                {
                    foreach (var sub in m_subscriptions)
                    {
                        sub.second.onError(processingError, GlobalMembers.WALLET_UNCONFIRMED_TRANSACTION_HEIGHT);
                    }

                    return(processingError);
                }
            }

            foreach (var deletedTxHash in deletedTransactions)
            {
                m_poolTxs.erase(deletedTxHash);

                m_observerManager.notify(IBlockchainConsumerObserver.onTransactionDeleteBegin, this, deletedTxHash);
                foreach (var sub in m_subscriptions)
                {
//C++ TO C# CONVERTER TODO TASK: There is no equivalent to 'reinterpret_cast' in C#:
                    sub.second.deleteUnconfirmedTransaction(*reinterpret_cast <const Hash>(deletedTxHash));
                }

                m_observerManager.notify(IBlockchainConsumerObserver.onTransactionDeleteEnd, this, deletedTxHash);
            }

            return(std::error_code());
        }
コード例 #19
0
        public void close(ref std::error_code ec)
        {
            int result;

            if (m_data != null)
            {
                flush(m_data, new uint64_t(m_size), ref ec);
                if (ec != null)
                {
                    return;
                }

                result = global::munmap(m_data, (size_t)m_size);
                if (result == 0)
                {
                    m_data = null;
                }
                else
                {
                    ec = std::error_code(errno, std::system_category());
                    return;
                }
            }

            if (m_file != -1)
            {
                result = global::close(m_file);
                if (result == 0)
                {
                    m_file = -1;
                    ec     = std::error_code();
                }
                else
                {
                    ec = std::error_code(errno, std::system_category());
                    return;
                }
            }

            ec = std::error_code();
        }
コード例 #20
0
        public override bool getPoolState(List <Hash> knownPoolTransactionHashes, Hash knownBlockchainTopHash, ref bool isBlockchainActual, List <TransactionDetails> newTransactions, List <Hash> removedTransactions)
        {
            if (state.load() != State.INITIALIZED)
            {
                throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.NOT_INITIALIZED));
            }

            logger.functorMethod(DEBUGGING) << "Get pool state request came.";
            List <std::unique_ptr <ITransactionReader> > rawNewTransactions = new List <std::unique_ptr <ITransactionReader> >();

            NodeRequest new request((INodeOriginal.Callback callback) =>
            {
                List <Hash> hashes = new List <Hash>();
                foreach (Hash hash in knownPoolTransactionHashes)
                {
                    hashes.Add(std::move(hash));
                }

                node.getPoolSymmetricDifference(std::move(hashes), reinterpret_cast <Hash&>(knownBlockchainTopHash), ref isBlockchainActual, rawNewTransactions, removedTransactions, callback);
            });
            std::error_code ec = request.performBlocking();

            if (ec != null)
            {
                logger.functorMethod(ERROR) << "Can't get pool state: " << ec.message();
                throw std::system_error(ec);
            }

            List <Hash> newTransactionsHashes = new List <Hash>();

            foreach (var rawTransaction in rawNewTransactions)
            {
                Hash transactionHash = rawTransaction.getTransactionHash();
                newTransactionsHashes.Add(std::move(transactionHash));
            }

            return(getTransactions(newTransactionsHashes, newTransactions));
        }
コード例 #21
0
        public override std::error_code read(IReadBatch batch)
        {
            if (state.load() != State.INITIALIZED)
            {
                throw new System.Exception("Not initialized.");
            }

            rocksdb.ReadOptions readOptions = new rocksdb.ReadOptions();

            List <string>        rawKeys   = new List <string>(batch.getRawKeys());
            List <rocksdb.Slice> keySlices = new List <rocksdb.Slice>();

            keySlices.Capacity = rawKeys.Count;
            foreach (string key in rawKeys)
            {
                keySlices.emplace_back(new rocksdb.Slice(key));
            }

            List <string> values = new List <string>();

            values.Capacity = rawKeys.Count;
            List <rocksdb.Status> statuses = db.MultiGet(readOptions, keySlices, values);

            std::error_code error        = new std::error_code();
            List <bool>     resultStates = new List <bool>();

            foreach (rocksdb  in :Status & status : statuses)
            {
                if (!status.ok() && !status.IsNotFound())
                {
                    return(GlobalMembers.make_error_code(CryptoNote.error.DataBaseErrorCodes.INTERNAL_ERROR));
                }
                resultStates.Add(status.ok());
            }

            batch.submitRawResult(values, resultStates);
            return(std::error_code());
        }
コード例 #22
0
        public void flush(uint8_t data, uint64_t size, ref std::error_code ec)
        {
            Debug.Assert(isOpened());

            uintptr_t pageSize = (uintptr_t)sysconf(_SC_PAGESIZE);
//C++ TO C# CONVERTER TODO TASK: There is no equivalent to 'reinterpret_cast' in C#:
            uintptr_t dataAddr   = reinterpret_cast <uintptr_t>(data);
            uintptr_t pageOffset = (dataAddr / pageSize) * pageSize;

//C++ TO C# CONVERTER TODO TASK: There is no equivalent to 'reinterpret_cast' in C#:
            int result = global::msync(reinterpret_cast <object>(pageOffset), (size_t)(dataAddr % pageSize + size), MS_SYNC);

            if (result == 0)
            {
                result = global::fsync(m_file);
                if (result == 0)
                {
                    ec = std::error_code();
                    return;
                }
            }

            ec = std::error_code(errno, std::system_category());
        }
コード例 #23
0
        protected static void makeErrorResponse(std::error_code ec, Common.JsonValue resp)
        {
            JsonValue error = new JsonValue(JsonValue.OBJECT);

            JsonValue code = new JsonValue();

            code = (long)CryptoNote.JsonRpc.errParseError; //Application specific error code

            JsonValue message = new JsonValue();

            message = ec.message();

            JsonValue data    = new JsonValue(JsonValue.OBJECT);
            JsonValue appCode = new JsonValue();

            appCode = (long)ec.value();
            data.insert("application_code", appCode);

            error.insert("code", code);
            error.insert("message", message);
            error.insert("data", data);

            resp.insert.functorMethod("error", error);
        }
コード例 #24
0
ファイル: NodeFactory.cs プロジェクト: ooosbkf/turtlecoin-net
 public void initCompleted(std::error_code result)
 {
     initPromise.set_value(result);
 }
コード例 #25
0
        public override uint onNewBlocks(CompleteBlock[] blocks, uint startHeight, uint count)
        {
            Debug.Assert(blocks);
            Debug.Assert(count > 0);

//C++ TO C# CONVERTER TODO TASK: C# does not allow declaring types within methods:
//	struct Tx
//	{
//	  TransactionBlockInfo blockInfo;
//	  const ITransactionReader* tx;
//	  bool isLastTransactionInBlock;
//	};

//C++ TO C# CONVERTER TODO TASK: C# does not allow declaring types within methods:
//	struct PreprocessedTx : Tx, PreprocessInfo
//	{
//	};

            List <PreprocessedTx> preprocessedTransactions = new List <PreprocessedTx>();
            object preprocessedTransactionsMutex           = new object();

            uint workers = std::thread.hardware_concurrency();

            if (workers == 0)
            {
                workers = 2;
            }

            BlockingQueue <Tx> inputQueue = new BlockingQueue <Tx>(workers * 2);

            std::atomic <bool> stopProcessing  = new std::atomic <bool>(false);
            std::atomic <uint> emptyBlockCount = new std::atomic <uint>(0);

//C++ TO C# CONVERTER TODO TASK: Lambda expressions cannot be assigned to 'var':
            var pushingThread = std::async(std::launch.async, () =>
            {
                for (uint i = 0; i < count && stopProcessing == null; ++i)
                {
                    auto block = blocks[i].block;

                    if (!block.is_initialized())
                    {
                        ++emptyBlockCount;
                        continue;
                    }

                    // filter by syncStartTimestamp
                    if (m_syncStart.timestamp != 0 && block.timestamp < m_syncStart.timestamp)
                    {
                        ++emptyBlockCount;
                        continue;
                    }

                    TransactionBlockInfo blockInfo = new TransactionBlockInfo();
                    blockInfo.height           = startHeight + i;
                    blockInfo.timestamp        = block.timestamp;
                    blockInfo.transactionIndex = 0; // position in block

                    foreach (var tx in blocks[i].transactions)
                    {
                        var pubKey = tx.GetTransactionPublicKey();
                        if (pubKey == NULL_PUBLIC_KEY)
                        {
                            ++blockInfo.transactionIndex;
                            continue;
                        }

                        bool isLastTransactionInBlock = blockInfo.transactionIndex + 1 == blocks[i].transactions.size();
                        Tx item = new Tx(blockInfo, tx.get(), isLastTransactionInBlock);
                        inputQueue.push(new Tx(item));
                        ++blockInfo.transactionIndex;
                    }
                }

                inputQueue.close();
            });

//C++ TO C# CONVERTER TODO TASK: Lambda expressions cannot be assigned to 'var':
            var processingFunction = () =>
            {
                Tx item            = new Tx();
                std::error_code ec = new std::error_code();
                while (stopProcessing == null && inputQueue.pop(ref item))
                {
                    PreprocessedTx output = new PreprocessedTx();
                    (Tx)output = item;

                    ec.CopyFrom(preprocessOutputs(item.blockInfo, *item.tx, output));
                    if (ec != null)
                    {
                        stopProcessing = true;
                        break;
                    }

                    lock (preprocessedTransactionsMutex)
                    {
                        preprocessedTransactions.Add(std::move(output));
                    }
                }
                return(ec);
            };

            List <std::future <std::error_code> > processingThreads = new List <std::future <std::error_code> >();

            for (uint i = 0; i < workers; ++i)
            {
                processingThreads.Add(std::async(std::launch.async, processingFunction));
            }

            std::error_code processingError = new std::error_code();

            foreach (var f in processingThreads)
            {
                try
                {
                    std::error_code ec = f.get();
                    if (processingError == null && ec != null)
                    {
//C++ TO C# CONVERTER TODO TASK: The following line was determined to be a copy assignment (rather than a reference assignment) - this should be verified and a 'CopyFrom' method should be created:
//ORIGINAL LINE: processingError = ec;
                        processingError.CopyFrom(ec);
                    }
                }
                catch (std::system_error e)
                {
                    processingError = e.code();
                }
                catch (System.Exception)
                {
                    processingError = std::make_error_code(std::errc.operation_canceled);
                }
            }

            if (processingError != null)
            {
                forEachSubscription((TransfersSubscription sub) =>
                {
                    sub.onError(processingError, startHeight);
                });

                return(0);
            }

//C++ TO C# CONVERTER TODO TASK: The following line was determined to contain a copy constructor call - this should be verified and a copy constructor should be created:
//ORIGINAL LINE: ClassicVector<Crypto::Hash> blockHashes = getBlockHashes(blocks, count);
            List <Crypto.Hash> blockHashes = GlobalMembers.getBlockHashes(new CryptoNote.CompleteBlock(blocks), count);

            m_observerManager.notify(IBlockchainConsumerObserver.onBlocksAdded, this, blockHashes);

            // sort by block height and transaction index in block
//C++ TO C# CONVERTER TODO TASK: The 'Compare' parameter of std::sort produces a boolean value, while the .NET Comparison parameter produces a tri-state result:
//ORIGINAL LINE: std::sort(preprocessedTransactions.begin(), preprocessedTransactions.end(), [](const PreprocessedTx& a, const PreprocessedTx& b)
            preprocessedTransactions.Sort((PreprocessedTx a, PreprocessedTx b) =>
            {
                return(std::tie(a.blockInfo.height, a.blockInfo.transactionIndex) < std::tie(b.blockInfo.height, b.blockInfo.transactionIndex));
            });

            uint processedBlockCount = (uint)emptyBlockCount;

            try
            {
                foreach (var tx in preprocessedTransactions)
                {
                    processTransaction(tx.blockInfo, *tx.tx, tx);

                    if (tx.isLastTransactionInBlock)
                    {
                        ++processedBlockCount;
                        m_logger.functorMethod(TRACE) << "Processed block " << (int)processedBlockCount << " of " << (int)count << ", last processed block index " << tx.blockInfo.height << ", hash " << blocks[processedBlockCount - 1].blockHash;

                        var newHeight = startHeight + processedBlockCount - 1;
//C++ TO C# CONVERTER TODO TASK: Only lambda expressions having all locals passed by reference can be converted to C#:
//ORIGINAL LINE: forEachSubscription([newHeight](TransfersSubscription& sub)
                        forEachSubscription((TransfersSubscription sub) =>
                        {
                            sub.advanceHeight(newHeight);
                        });
                    }
                }
            }
            catch (MarkTransactionConfirmedException e)
            {
                m_logger.functorMethod(ERROR, BRIGHT_RED) << "Failed to process block transactions: failed to confirm transaction " << e.getTxHash() << ", remove this transaction from all containers and transaction pool";
                forEachSubscription((TransfersSubscription sub) =>
                {
                    sub.deleteUnconfirmedTransaction(e.getTxHash());
                });

                m_poolTxs.erase(e.getTxHash());
            }
            catch (System.Exception e)
            {
                m_logger.functorMethod(ERROR, BRIGHT_RED) << "Failed to process block transactions, exception: " << e.Message;
            }
            catch
            {
                m_logger.functorMethod(ERROR, BRIGHT_RED) << "Failed to process block transactions, unknown exception";
            }

            if (processedBlockCount < count)
            {
                uint detachIndex = startHeight + processedBlockCount;
                m_logger.functorMethod(ERROR, BRIGHT_RED) << "Not all block transactions are processed, fully processed block count: " << (int)processedBlockCount << " of " << (int)count << ", last processed block hash " << (processedBlockCount > 0 ? blocks[processedBlockCount - 1].blockHash : GlobalMembers.NULL_HASH) << ", detach block index " << (int)detachIndex << " to remove partially processed block";
//C++ TO C# CONVERTER TODO TASK: Only lambda expressions having all locals passed by reference can be converted to C#:
//ORIGINAL LINE: forEachSubscription([detachIndex](TransfersSubscription& sub)
                forEachSubscription((TransfersSubscription sub) =>
                {
                    sub.onBlockchainDetach(detachIndex);
                });
            }

            return(processedBlockCount);
        }
コード例 #26
0
        public void Dispose()
        {
            std::error_code ignore = new std::error_code();

            close(ref ignore);
        }