void TxIOPair::unserialize(const BinaryDataRef& val) { BinaryRefReader brr(val); BitUnpacker<uint8_t> bitunpack(brr); isTxOutFromSelf_ = bitunpack.getBit(); isFromCoinbase_ = bitunpack.getBit(); bool isSpent = bitunpack.getBit(); isMultisig_ = bitunpack.getBit(); isUTXO_ = bitunpack.getBit(); isFromSameBlock_ = bitunpack.getBit(); // We always include the 8-byte value amount_ = brr.get_uint64_t(); setTxOut(val.getSliceRef(9, 8)); if (val.getSize() == 25) setTxIn(val.getSliceRef(17, 8)); //the key always carries the full txout ref /*if (!isSpent) setTxOut(key); else { //spent subssh, txout key setTxOut(val.getSliceRef(9, 8)); //when keyed by txins, the top bit in the tx index is always flipped BinaryData txinKey(key); txinKey.getPtr()[4] &= 0x7F; //last 8 bytes carry the txin key setTxIn(txinKey); }*/ }
void TxOut::unserialize( BinaryDataRef const & str, uint32_t nbytes, TxRef parent, uint32_t idx) { unserialize_checked(str.getPtr(), str.getSize(), nbytes, parent, idx); }
bool BinaryData::operator==(BinaryDataRef const & bd2) const { if(getSize() != bd2.getSize()) return false; return (memcmp(getPtr(), bd2.getPtr(), getSize()) == 0); }
int32_t BinaryData::find(BinaryDataRef const & matchStr, uint32_t startPos) { int32_t finalAnswer = -1; if(matchStr.getSize()==0) return startPos; for(int32_t i=startPos; i<=(int32_t)getSize()-(int32_t)matchStr.getSize(); i++) { if(matchStr[0] != data_[i]) continue; for(uint32_t j=0; j<matchStr.getSize(); j++) { if(matchStr[j] != data_[i+j]) break; // If we are at this instruction and is the last index, it's a match if(j==matchStr.getSize()-1) finalAnswer = i; } if(finalAnswer != -1) break; } return finalAnswer; }
bool BinaryData::startsWith(BinaryDataRef const & matchStr) const { if(matchStr.getSize() > getSize()) return false; for(uint32_t i=0; i<matchStr.getSize(); i++) if(matchStr[i] != (*this)[i]) return false; return true; }
void ZeroConfContainer::updateZCinDB(const vector<BinaryData>& keysToWrite, const vector<BinaryData>& keysToDelete) { //should run in its own thread to make sure we can get a write tx DB_SELECT dbs = BLKDATA; if (db_->getDbType() != ARMORY_DB_SUPER) dbs = HISTORY; LMDBEnv::Transaction tx; db_->beginDBTransaction(&tx, dbs, LMDB::ReadWrite); for (auto& key : keysToWrite) { StoredTx zcTx; zcTx.createFromTx(txMap_[key], true, true); db_->putStoredZC(zcTx, key); } for (auto& key : keysToDelete) { BinaryData keyWithPrefix; if (key.getSize() == 6) { keyWithPrefix.resize(7); uint8_t* keyptr = keyWithPrefix.getPtr(); keyptr[0] = DB_PREFIX_ZCDATA; memcpy(keyptr + 1, key.getPtr(), 6); } else keyWithPrefix = key; LDBIter dbIter(db_->getIterator(dbs)); if (!dbIter.seekTo(keyWithPrefix)) continue; vector<BinaryData> ktd; do { BinaryDataRef thisKey = dbIter.getKeyRef(); if (!thisKey.startsWith(keyWithPrefix)) break; ktd.push_back(thisKey); } while (dbIter.advanceAndRead(DB_PREFIX_ZCDATA)); for (auto Key : ktd) db_->deleteValue(dbs, Key); } }
BinaryData SigHashDataSegWit::getDataForSigHashAll(const TransactionStub& stub, BinaryDataRef subScript, unsigned inputIndex) { //grab subscript auto lastCSoffset = stub.getLastCodeSeparatorOffset(inputIndex); auto subScriptLen = subScript.getSize() - lastCSoffset; auto&& subscript = subScript.getSliceRef(lastCSoffset, subScriptLen); //pre state computePreState(stub); //serialize hashdata BinaryWriter hashdata; //version hashdata.put_uint32_t(stub.getVersion()); //hashPrevouts hashdata.put_BinaryData(hashPrevouts_); //hashSequence hashdata.put_BinaryData(hashSequence_); //outpoint hashdata.put_BinaryDataRef(stub.getOutpoint(inputIndex)); //script code hashdata.put_uint8_t(subScriptLen); hashdata.put_BinaryDataRef(subscript); //value hashdata.put_uint64_t(stub.getOutpointValue(inputIndex)); //sequence hashdata.put_uint32_t(stub.getTxInSequence(inputIndex)); //hashOutputs hashdata.put_BinaryData(hashOutputs_); //nLocktime hashdata.put_uint32_t(stub.getLockTime()); //sighash type hashdata.put_uint32_t(1); return hashdata.getData(); }
void FileMap::getRawBlock(BinaryDataRef& bdr, uint64_t offset, uint32_t size, std::atomic<uint64_t>& lastSeenCumulative) const { bdr.setRef(getMapPtr(offset), size); lastSeenCumulated_.store( lastSeenCumulative.fetch_add(size, std::memory_order_relaxed) + size, std::memory_order_relaxed); }
bool BinaryData::operator==(BinaryDataRef const & bd2) const { if(getSize() != bd2.getSize()) return false; for(unsigned int i=0; i<getSize(); i++) if( data_[i] != bd2[i]) return false; return true; }
bool BinaryData::endsWith(BinaryDataRef const & matchStr) const { uint32_t sz = matchStr.getSize(); if(sz > getSize()) return false; for(uint32_t i=0; i<sz; i++) if(matchStr[sz-(i+1)] != (*this)[getSize()-(i+1)]) return false; return true; }
BinaryData::BinaryData(BinaryDataRef const & bdRef) { copyFrom(bdRef.getPtr(), bdRef.getSize()); }
void ZeroConfContainer::loadZeroConfMempool( function<bool(const BinaryData&)> filter, bool clearMempool) { //run this in its own scope so the iter and tx are closed in order to open //RW tx afterwards { auto dbs = db_->getDbSelect(HISTORY); LMDBEnv::Transaction tx; db_->beginDBTransaction(&tx, dbs, LMDB::ReadOnly); LDBIter dbIter(db_->getIterator(dbs)); if (!dbIter.seekToStartsWith(DB_PREFIX_ZCDATA)) { enabled_ = true; return; } do { BinaryDataRef zcKey = dbIter.getKeyRef(); if (zcKey.getSize() == 7) { //Tx, grab it from DB StoredTx zcStx; db_->getStoredZcTx(zcStx, zcKey); //add to newZCMap_ Tx& zcTx = newZCMap_[zcKey.getSliceCopy(1, 6)]; zcTx = Tx(zcStx.getSerializedTx()); zcTx.setTxTime(zcStx.unixTime_); } else if (zcKey.getSize() == 9) { //TxOut, ignore it continue; } else { //shouldn't hit this LOGERR << "Unknown key found in ZC mempool"; break; } } while (dbIter.advanceAndRead(DB_PREFIX_ZCDATA)); } if (clearMempool == true) { vector<BinaryData> keysToWrite, keysToDelete; for (const auto& zcTx : newZCMap_) keysToDelete.push_back(zcTx.first); newZCMap_.clear(); updateZCinDB(keysToWrite, keysToDelete); } else if (newZCMap_.size()) { //copy newZCmap_ to keep the pre parse ZC map auto oldZCMap = newZCMap_; //now parse the new ZC parseNewZC(filter); //set the zckey to the highest used index if (txMap_.size() > 0) { BinaryData topZcKey = txMap_.rbegin()->first; topId_.store(READ_UINT32_BE(topZcKey.getSliceCopy(2, 4)) +1); } //intersect oldZCMap and txMap_ to figure out the invalidated ZCs vector<BinaryData> keysToWrite, keysToDelete; for (const auto& zcTx : oldZCMap) { if (txMap_.find(zcTx.first) == txMap_.end()) keysToDelete.push_back(zcTx.first); } //no need to run this in a side thread, this code only runs when we have //full control over the main thread updateZCinDB(keysToWrite, keysToDelete); } enabled_ = true; }
void TxRef::setRef(BinaryDataRef bdr) { dbKey6B_ = bdr.copy(); }
void BlockHeader::unserialize(BinaryDataRef const & str) { unserialize(str.getPtr(), str.getSize()); }
void OutPoint::unserialize(BinaryDataRef const & bdRef) { unserialize(bdRef.getPtr(), bdRef.getSize()); }
void TxOutRef::unserialize(BinaryDataRef const & str, uint32_t nbytes, TxRef* parent, int32_t idx) { unserialize(str.getPtr(), nbytes, parent, idx); }
BinaryData SigHashDataLegacy::getDataForSigHashAll(const TransactionStub& stub, BinaryDataRef subScript, unsigned inputIndex) { //grab subscript auto lastCSoffset = stub.getLastCodeSeparatorOffset(inputIndex); auto subScriptLen = subScript.getSize() - lastCSoffset; auto&& presubscript = subScript.getSliceRef(lastCSoffset, subScriptLen); //tokenize op_cs chunks auto&& tokens = tokenize(presubscript, OP_CODESEPARATOR); BinaryData subscript; if (tokens.size() == 1) { subscript = move(presubscript); } else { for (auto& token : tokens) { subscript.append(token); } } //isolate outputs auto&& serializedOutputs = stub.getSerializedOutputScripts(); //isolate inputs auto&& txinsData = stub.getTxInsData(); auto txin_count = txinsData.size(); BinaryWriter strippedTxins; for (unsigned i=0; i < txin_count; i++) { strippedTxins.put_BinaryData(txinsData[i].outputHash_); strippedTxins.put_uint32_t(txinsData[i].outputIndex_); if (inputIndex != i) { //put empty varint strippedTxins.put_var_int(0); //and sequence strippedTxins.put_uint32_t(txinsData[i].sequence_); } else { //scriptsig strippedTxins.put_var_int(subscript.getSize()); strippedTxins.put_BinaryData(subscript); //sequence strippedTxins.put_uint32_t(txinsData[i].sequence_); } } //wrap it up BinaryWriter scriptSigData; //version scriptSigData.put_uint32_t(stub.getVersion()); //txin count scriptSigData.put_var_int(txin_count); //txins scriptSigData.put_BinaryData(strippedTxins.getData()); //txout count scriptSigData.put_var_int(stub.getTxOutCount()); //txouts scriptSigData.put_BinaryData(serializedOutputs); //locktime scriptSigData.put_uint32_t(stub.getLockTime()); //sighashall scriptSigData.put_uint32_t(1); return BinaryData(scriptSigData.getData()); }
void BinaryData::copyFrom(BinaryDataRef const & bdr) { copyFrom( bdr.getPtr(), bdr.getSize() ); }