Status Login::passwordAuthSet(DataSlice passwordAuth) { std::lock_guard<std::mutex> lock(mutex_); passwordAuth_ = DataChunk(passwordAuth.begin(), passwordAuth.end()); return Status(); }
/** * Encodes data in an arbitrary power-of-2 base. * @param Bytes number of bytes per chunk of characters. * @param Chars number of characters per chunk. */ template<unsigned Bytes, unsigned Chars> std::string chunkEncode(DataSlice data, const char *alphabet) { std::string out; auto chunks = (data.size() + Bytes - 1) / Bytes; // Rounding up out.reserve(Chars * chunks); constexpr unsigned shift = 8 * Bytes / Chars; // Bits per character uint16_t buffer = 0; // Bits waiting to be written out, MSB first int bits = 0; // Number of bits currently in the buffer auto i = data.begin(); while (i != data.end() || 0 < bits) { // Reload the buffer if we need more bits: if (i != data.end() && bits < shift) { buffer |= *i++ << (8 - bits); bits += 8; } // Write out the most-significant bits in the buffer: out += alphabet[buffer >> (16 - shift)]; buffer <<= shift; bits -= shift; } // Pad the final string to a multiple of the chunk size: out.append(-out.size() % Chars, '='); return out; }
Status broadcastTx(Wallet &self, DataSlice rawTx) { // Create communication resources: auto syncer = std::make_shared<Syncer>(); auto s1 = std::make_shared<DelayedStatus>(); auto s2 = std::make_shared<DelayedStatus>(); auto s3 = std::make_shared<DelayedStatus>(); // Launch the broadcasts: DataChunk tx(rawTx.begin(), rawTx.end()); if (!self.bOverrideBitcoinServers) { std::thread(broadcastTask<blockchainPostTx>, syncer, s1, tx).detach(); std::thread(broadcastTask<insightPostTx>, syncer, s2, tx).detach(); } // Queue up an async broadcast over the TxUpdater: auto updaterDone = [syncer, s3](Status s) { { std::lock_guard<std::mutex> lock(syncer->mutex); s3->status = s; s3->done = true; if (s) ABC_DebugLog("Stratum broadcast OK"); else s.log(); } syncer->cv.notify_all(); }; watcherSend(self, updaterDone, rawTx).log(); // Loop as long as any thread is still running: while (true) { // Wait for the condition variable, which also acquires the lock: std::unique_lock<std::mutex> lock(syncer->mutex); syncer->cv.wait(lock); // Stop waiting if any broadcast has succeeded: if (s1->done && s1->status) break; if (s2->done && s2->status) break; if (s3->done && s3->status) break; // If they are all done, we have an error: if (s1->done && s2->done && s3->done) return s1->status; } return Status(); }
Login::Login(LoginStore &store, DataSlice dataKey): store(store), parent_(store.shared_from_this()), dataKey_(dataKey.begin(), dataKey.end()) {}