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); }
public override bool getTransactionsByPaymentId(Hash paymentId, List <TransactionDetails> transactions) { if (state.load() != State.INITIALIZED) { throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.NOT_INITIALIZED)); } logger.functorMethod(DEBUGGING) << "Get transactions by payment id " << paymentId << " request came."; List <Crypto.Hash> transactionHashes = new List <Crypto.Hash>(); NodeRequest new request((INodeOriginal.Callback cb) => { return(node.getTransactionHashesByPaymentId(paymentId, transactionHashes, cb)); }); var ec = request.performBlocking(); if (ec != null) { logger.functorMethod(ERROR) << "Can't get transaction hashes: " << ec.message(); throw std::system_error(ec); } if (transactionHashes.Count == 0) { return(false); } return(getTransactions(transactionHashes, transactions)); }
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); }
private std::error_code write(IWriteBatch batch, bool sync) { rocksdb.WriteOptions writeOptions = new rocksdb.WriteOptions(); writeOptions.sync = sync; rocksdb.WriteBatch rocksdbBatch = new rocksdb.WriteBatch(); List <Tuple <string, string> > rawData = new List <Tuple <string, string> >(batch.extractRawDataToInsert()); foreach (Tuple <string, string> kvPair in rawData) { rocksdbBatch.Put(new rocksdb.Slice(kvPair.Item1), new rocksdb.Slice(kvPair.Item2)); } List <string> rawKeys = new List <string>(batch.extractRawKeysToRemove()); foreach (string key in rawKeys) { rocksdbBatch.Delete(new rocksdb.Slice(key)); } rocksdb.Status status = db.Write(writeOptions, rocksdbBatch); if (!status.ok()) { logger(ERROR) << "Can't write to DB. " << status.ToString(); return(GlobalMembers.make_error_code(CryptoNote.error.DataBaseErrorCodes.INTERNAL_ERROR)); } else { return(std::error_code()); } }
public override ulong getRewardBlocksWindow() { if (state.load() != State.INITIALIZED) { throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.NOT_INITIALIZED)); } return(parameters.CRYPTONOTE_REWARD_BLOCKS_WINDOW); }
public override bool addObserver(IBlockchainObserver observer) { if (state.load() != State.INITIALIZED) { throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.NOT_INITIALIZED)); } observersCounter.fetch_add(1); return(observerManager.add(observer)); }
public override std::error_code writeSync(IWriteBatch batch) { if (state.load() != State.INITIALIZED) { throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.DataBaseErrorCodes.NOT_INITIALIZED)); } return(write(batch, true)); }
public override void shutdown() { if (state.load() != State.INITIALIZED) { logger.functorMethod(ERROR) << "Shutdown called on not initialized BlockchainExplorer."; throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.NOT_INITIALIZED)); } node.removeObserver(this); asyncContextCounter.waitAsyncContextsFinish(); state.store(State.NOT_INITIALIZED); }
public void shutdown() { if (state.load() != State.INITIALIZED) { throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.DataBaseErrorCodes.NOT_INITIALIZED)); } logger(INFO) << "Closing DB."; db.Flush(new rocksdb.FlushOptions()); db.SyncWAL(); db.reset(); state.store(State.NOT_INITIALIZED); }
//C++ TO C# CONVERTER TODO TASK: C# has no equivalent to ' = delete': // RocksDBWrapper(const RocksDBWrapper&) = delete; //C++ TO C# CONVERTER TODO TASK: C# has no equivalent to ' = delete': // RocksDBWrapper(RocksDBWrapper&&) = delete; //C++ TO C# CONVERTER TODO TASK: C# has no equivalent to ' = delete': // RocksDBWrapper& operator =(const RocksDBWrapper&) = delete; //C++ TO C# CONVERTER TODO TASK: C# has no equivalent to ' = delete': // RocksDBWrapper& operator =(RocksDBWrapper&&) = delete; public void init(DataBaseConfig config) { if (state.load() != State.NOT_INITIALIZED) { throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.DataBaseErrorCodes.ALREADY_INITIALIZED)); } string dataDir = getDataDir(config); logger(INFO) << "Opening DB in " << dataDir; rocksdb.DB dbPtr; rocksdb.Options dbOptions = getDBOptions(config); rocksdb.Status status = rocksdb.DB.Open(dbOptions, dataDir, dbPtr); if (status.ok()) { logger(INFO) << "DB opened in " << dataDir; } else if (!status.ok() && status.IsInvalidArgument()) { logger(INFO) << "DB not found in " << dataDir << ". Creating new DB..."; dbOptions.create_if_missing = true; rocksdb.Status status = rocksdb.DB.Open(dbOptions, dataDir, dbPtr); if (!status.ok()) { logger(ERROR) << "DB Error. DB can't be created in " << dataDir << ". Error: " << status.ToString(); throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.DataBaseErrorCodes.INTERNAL_ERROR)); } } else if (status.IsIOError()) { logger(ERROR) << "DB Error. DB can't be opened in " << dataDir << ". Error: " << status.ToString(); throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.DataBaseErrorCodes.IO_ERROR)); } else { logger(ERROR) << "DB Error. DB can't be opened in " << dataDir << ". Error: " << status.ToString(); throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.DataBaseErrorCodes.INTERNAL_ERROR)); } db.reset(dbPtr); state.store(State.INITIALIZED); }
/* This method is used by WalletService to determine if the mixin amount is correct * for the current block height */ public static Tuple <bool, string, std::error_code> validate(uint mixin, uint height) { var(minMixin, maxMixin) = getMixinAllowableRange(height); std::stringstream str = new std::stringstream(); if (mixin < minMixin) { str << "Mixin of " << (int)mixin << " under minimum mixin threshold of " << minMixin; return(new Tuple <bool, string, std::error_code>(false, str.str(), GlobalMembers.make_error_code(CryptoNote.error.MIXIN_BELOW_THRESHOLD))); } else if (mixin > maxMixin) { str << "Mixin of " << (int)mixin << " above maximum mixin threshold of " << maxMixin; return(new Tuple <bool, string, std::error_code>(false, str.str(), GlobalMembers.make_error_code(CryptoNote.error.MIXIN_ABOVE_THRESHOLD))); } return(new Tuple <bool, string, std::error_code>(true, string(), std::error_code())); }
public override bool getBlocks(ulong timestampBegin, ulong timestampEnd, uint blocksNumberLimit, List <BlockDetails> blocks, ref uint blocksNumberWithinTimestamps) { if (state.load() != State.INITIALIZED) { throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.NOT_INITIALIZED)); } if (timestampBegin > timestampEnd) { throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.REQUEST_ERROR), "timestampBegin must not be greater than timestampEnd"); } logger.functorMethod(DEBUGGING) << "Get blocks by timestamp " << timestampBegin << " - " << timestampEnd << " request came."; List <Hash> blockHashes = new List <Hash>(); NodeRequest new request((INodeOriginal.Callback cb) => { node.getBlockHashesByTimestamps(new ulong(timestampBegin), timestampEnd - timestampBegin + 1, blockHashes, cb); }); var ec = request.performBlocking(); if (ec != null) { logger.functorMethod(ERROR) << "Can't get blocks hashes by timestamps: " << ec.message(); throw std::system_error(ec); } blocksNumberWithinTimestamps = (uint)blockHashes.Count; if (blocksNumberLimit < blocksNumberWithinTimestamps) { //C++ TO C# CONVERTER TODO TASK: There is no direct equivalent to the STL vector 'erase' method in C#: blockHashes.erase(std::next(blockHashes.GetEnumerator(), blocksNumberLimit), blockHashes.end()); } if (blockHashes.Count == 0) { throw new System.Exception("block hashes not found"); } return(getBlocks(blockHashes, blocks)); }
public override ulong getFullRewardMaxBlockSize(ushort majorVersion) { if (state.load() != State.INITIALIZED) { throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.NOT_INITIALIZED)); } if (majorVersion >= BLOCK_MAJOR_VERSION_3) { return(parameters.CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE); } else if (majorVersion == BLOCK_MAJOR_VERSION_2) { return(parameters.CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2); } else { return(parameters.CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1); } }
public static HttpResponse.HTTP_STATUS parseResponseStatusFromString(string status) { if (status == "200 OK" || status == "200 Ok") { return(CryptoNote.HttpResponse.STATUS_200); } else if (status == "404 Not Found") { return(CryptoNote.HttpResponse.STATUS_404); } else if (status == "500 Internal Server Error") { return(CryptoNote.HttpResponse.STATUS_500); } else { throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.HttpParserErrorCodes.UNEXPECTED_SYMBOL), "Unknown HTTP status code is given"); } return(CryptoNote.HttpResponse.STATUS_200); //unaccessible }
public override void init() { if (state.load() != State.NOT_INITIALIZED) { logger.functorMethod(ERROR) << "Init called on already initialized BlockchainExplorer."; throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.ALREADY_INITIALIZED)); } if (!getBlockchainTop(ref knownBlockchainTop, false)) { logger.functorMethod(ERROR) << "Can't get blockchain top."; throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.INTERNAL_ERROR)); } List <Crypto.Hash> knownPoolTransactionHashes = new List <Crypto.Hash>(); bool isBlockchainActual; List <TransactionDetails> newTransactions = new List <TransactionDetails>(); List <Crypto.Hash> removedTransactions = new List <Crypto.Hash>(); StateRollback stateRollback = new StateRollback(state); //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: if (!getPoolState(knownPoolTransactionHashes, knownBlockchainTop.hash, isBlockchainActual, newTransactions, removedTransactions)) if (!getPoolState(knownPoolTransactionHashes, new Crypto.Hash(knownBlockchainTop.hash), ref isBlockchainActual, newTransactions, removedTransactions)) { logger.functorMethod(ERROR) << "Can't get pool state."; throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.INTERNAL_ERROR)); } Debug.Assert(removedTransactions.Count == 0); if (node.addObserver(this)) { stateRollback.commit(); } else { logger.functorMethod(ERROR) << "Can't add observer to node."; throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.BlockchainExplorerErrorCodes.INTERNAL_ERROR)); } }
private void readWord(std::istream stream, string word) { char c; stream.get(c); while (stream.good() && c != ' ' && c != '\r') { word += c; stream.get(c); } GlobalMembers.throwIfNotGood(stream); if (c == '\r') { stream.get(c); if (c != '\n') { throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.HttpParserErrorCodes.UNEXPECTED_SYMBOL)); } } }
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)); }
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()); }
public void destroy(DataBaseConfig config) { if (state.load() != State.NOT_INITIALIZED) { throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.DataBaseErrorCodes.ALREADY_INITIALIZED)); } string dataDir = getDataDir(config); logger(WARNING) << "Destroying DB in " << dataDir; rocksdb.Options dbOptions = getDBOptions(config); rocksdb.Status status = rocksdb.DestroyDB(dataDir, dbOptions); if (status.ok()) { logger(WARNING) << "DB destroyed in " << dataDir; } else { logger(ERROR) << "DB Error. DB can't be destroyed in " << dataDir << ". Error: " << status.ToString(); throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.DataBaseErrorCodes.INTERNAL_ERROR)); } }
private bool readHeader(std::istream stream, string name, string value) { char c; bool isName = true; stream.get(c); while (stream.good() && c != '\r') { if (c == ':') { if (stream.peek() == ' ') { stream.get(c); } if (string.IsNullOrEmpty(name)) { throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.HttpParserErrorCodes.EMPTY_HEADER)); } if (isName) { isName = false; stream.get(c); continue; } } if (isName) { name += c; stream.get(c); } else { value += c; stream.get(c); } } GlobalMembers.throwIfNotGood(stream); stream.get(c); if (c != '\n') { throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.HttpParserErrorCodes.UNEXPECTED_SYMBOL)); } std::transform(name.GetEnumerator(), name.end(), name.GetEnumerator(), global::tolower); c = stream.peek(); if (c == '\r') { stream.get(c).get(c); if (c != '\n') { throw std::system_error(GlobalMembers.make_error_code(CryptoNote.error.HttpParserErrorCodes.UNEXPECTED_SYMBOL)); } return(false); //no more headers } return(true); }