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 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 void receiveResponse(std::istream stream, HttpResponse response) { string httpVersion; readWord(stream, httpVersion); string status; char c; stream.get(c); while (stream.good() && c != '\r') { //Till the end status += c; stream.get(c); } GlobalMembers.throwIfNotGood(stream); if (c == '\r') { stream.get(c); if (c != '\n') { throw new System.Exception("Parser error: '\\n' symbol is expected"); } } response.setStatus(parseResponseStatusFromString(status)); string name; string value; while (readHeader(stream, name, value)) { response.addHeader(name, value); name = ""; value = ""; } response.addHeader(name, value); var headers = response.getHeaders(); uint length = 0; var it = headers.find("content-length"); //C++ TO C# CONVERTER TODO TASK: Iterators are only converted within the context of 'while' and 'for' loops: if (it != headers.end()) { //C++ TO C# CONVERTER TODO TASK: Iterators are only converted within the context of 'while' and 'for' loops: length = Convert.ToUInt32(it.second); } string body; if (length != null) { readBody(stream, body, new uint(length)); } response.setBody(body); }
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 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 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 void setStatus(HTTP_STATUS s) { status = s; if (status != HttpResponse.STATUS_200) { setBody(GlobalMembers.getErrorBody(status)); } }
public override void load(std::istream @is) { m_sync.load(@is); StdInputStream inputStream = new StdInputStream(@is); CryptoNote.BinaryInputStreamSerializer s = new CryptoNote.BinaryInputStreamSerializer(inputStream); uint version = 0; s.functorMethod(version, "version"); if (version > GlobalMembers.TRANSFERS_STORAGE_ARCHIVE_VERSION) { throw new System.Exception("TransfersSyncronizer version mismatch"); } //C++ TO C# CONVERTER TODO TASK: C# does not allow declaring types within methods: // struct ConsumerState // { // PublicKey viewKey; // string state; // ClassicVector<System.Tuple<AccountPublicAddress, string>> subscriptionStates; // }; List <ConsumerState> updatedStates = new List <ConsumerState>(); try { ulong subscriptionCount = 0; s.beginArray(ref subscriptionCount, "consumers"); while (subscriptionCount-- != 0) { s.beginObject(""); PublicKey viewKey = new PublicKey(); s.functorMethod(viewKey, "view_key"); string blob; s.functorMethod(blob, "state"); var subIter = m_consumers.find(viewKey); //C++ TO C# CONVERTER TODO TASK: Iterators are only converted within the context of 'while' and 'for' loops: if (subIter != m_consumers.end()) { //C++ TO C# CONVERTER TODO TASK: Iterators are only converted within the context of 'while' and 'for' loops: var consumerState = m_sync.getConsumerState(subIter.second.get()); Debug.Assert(consumerState); { // store previous state var prevConsumerState = GlobalMembers.getObjectState(*consumerState); // load consumer state GlobalMembers.setObjectState(*consumerState, blob); updatedStates.Add(ConsumerState({ viewKey, std::move(prevConsumerState) })); }
public static override bool functorMethod(string value, Common.StringView name) { writeElementPrefix(new ushort(GlobalMembers.BIN_KV_SERIALIZE_TYPE_STRING), new Common.StringView(name)); auto @out = stream(); GlobalMembers.writeArraySize(@out, value.Length); write(@out, value.data(), value.Length); return(true); }
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()); }
public override bool Binary(object value, ulong size, Common.StringView name) { if (size > 0) { writeElementPrefix(new ushort(GlobalMembers.BIN_KV_SERIALIZE_TYPE_STRING), new Common.StringView(name)); auto @out = stream(); GlobalMembers.writeArraySize(@out, new ulong(size)); write(@out, value, size); } return(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); }
private void readBody(std::istream stream, string body, uint bodyLen) { uint read = 0; while (stream.good() && read < bodyLen) { body += stream.get(); ++read; } GlobalMembers.throwIfNotGood(stream); }
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); }
public override uint addOutput(ulong amount, AccountPublicAddress to) { checkIfSigning(); KeyOutput outKey = new KeyOutput(); GlobalMembers.derivePublicKey(to, txSecretKey(), transaction.outputs.Count, outKey.key); TransactionOutput @out = new TransactionOutput(amount, outKey); transaction.outputs.emplace_back(@out); invalidateHash(); return(transaction.outputs.Count - 1); }
public bool start_sync(CryptoNoteConnectionContext context) { logger.functorMethod(Logging.Level.TRACE) << context << "Starting synchronization"; if (context.m_state == CryptoNoteConnectionContext.state_synchronizing) { Debug.Assert(context.m_needed_objects.Count == 0); Debug.Assert(context.m_requested_objects.Count == 0); NOTIFY_REQUEST_CHAIN.request r = boost::value_initialized <NOTIFY_REQUEST_CHAIN.request>(); r.block_ids = new List <Crypto.Hash>(m_core.BuildSparseChain()); logger.functorMethod(Logging.Level.TRACE) << context << "-->>NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.Count; GlobalMembers.post_notify <NOTIFY_REQUEST_CHAIN>(m_p2p, r, context); } return(true); }
public void requestMissingPoolTransactions(CryptoNoteConnectionContext context) { if (context.version < 1) { return; } NOTIFY_REQUEST_TX_POOL.request notification = new NOTIFY_REQUEST_TX_POOL.request(); notification.txs = m_core.GetPoolTransactionHashes(); bool ok = GlobalMembers.post_notify <NOTIFY_REQUEST_TX_POOL>(m_p2p, notification, context); if (!ok) { logger.functorMethod(Logging.Level.WARNING, Logging.BRIGHT_YELLOW) << "Failed to post notification NOTIFY_REQUEST_TX_POOL to " << context.m_connection_id; } }
//C++ TO C# CONVERTER WARNING: 'const' methods are not available in C#: //ORIGINAL LINE: std::ostream& printHttpResponse(std::ostream& os) const private std::ostream printHttpResponse(std::ostream os) { os << "HTTP/1.1 " << GlobalMembers.getStatusString(status) << "\r\n"; foreach (var pair in headers) { os << pair.first << ": " << pair.second << "\r\n"; } os << "\r\n"; if (!string.IsNullOrEmpty(body)) { os << body; } return(os); }
private void writeElementPrefix(ushort type, Common.StringView name) { Debug.Assert(m_stack.Count); checkArrayPreamble(new ushort(type)); Level level = m_stack[m_stack.Count - 1]; if (level.state != State.Array) { if (!name.isEmpty()) { auto s = stream(); GlobalMembers.writeElementName(s, new Common.StringView(name)); write(s, type, 1); } ++level.count; } }
//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); }
public override void EndObject() { Debug.Assert(m_objectsStack.Count); var level = std::move(m_stack[m_stack.Count - 1]); m_stack.RemoveAt(m_stack.Count - 1); var objStream = std::move(m_objectsStack[m_objectsStack.Count - 1]); m_objectsStack.RemoveAt(m_objectsStack.Count - 1); auto @out = stream(); writeElementPrefix(new ushort(GlobalMembers.BIN_KV_SERIALIZE_TYPE_OBJECT), level.name); GlobalMembers.writeArraySize(@out, level.count); write(@out, objStream.data(), objStream.size()); }
private void checkArrayPreamble(ushort type) { if (m_stack.Count == 0) { return; } Level level = m_stack[m_stack.Count - 1]; if (level.state == State.ArrayPrefix) { auto s = stream(); GlobalMembers.writeElementName(s, level.name); char c = GlobalMembers.BIN_KV_SERIALIZE_FLAG_ARRAY | type; write(s, c, 1); GlobalMembers.writeArraySize(s, new ulong(level.count)); level.state = State.Array; } }
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)); }
/* 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 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 void dump(IOutputStream target) { Debug.Assert(m_objectsStack.Count == 1); Debug.Assert(m_stack.Count == 1); KVBinaryStorageBlockHeader hdr = new KVBinaryStorageBlockHeader(); //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: hdr.m_signature_a = PORTABLE_STORAGE_SIGNATUREA; hdr.m_signature_a.CopyFrom(GlobalMembers.PORTABLE_STORAGE_SIGNATUREA); //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: hdr.m_signature_b = PORTABLE_STORAGE_SIGNATUREB; hdr.m_signature_b.CopyFrom(GlobalMembers.PORTABLE_STORAGE_SIGNATUREB); //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: hdr.m_ver = PORTABLE_STORAGE_FORMAT_VER; hdr.m_ver.CopyFrom(GlobalMembers.PORTABLE_STORAGE_FORMAT_VER); Common.write(target, hdr, sizeof(CryptoNote.KVBinaryStorageBlockHeader)); GlobalMembers.writeArraySize(target, new ulong(m_stack[0].count)); write(target, stream().data(), stream().size()); }
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)); } }