void InsertTx(const Tx& tx, const TxHashesOutNums& hashesOutNums, const HashValue& txHash, int height, const ConstBuf& txIns, const ConstBuf& spend, const ConstBuf& data) override { CoinEng& eng = Eng(); m_cmdInsertTx .Bind(1, ReducedHashValue(txHash)) .Bind(2, (Int64)height) .Bind(3, txIns) .Bind(4, spend); m_cmdInsertTx.Bind(5, data); try { DBG_LOCAL_IGNORE_NAME(MAKE_HRESULT(SEVERITY_ERROR, FACILITY_SQLITE, SQLITE_CONSTRAINT_PRIMARYKEY), ignSQLITE_CONSTRAINT_PRIMARYKEY); m_cmdInsertTx.ExecuteNonQuery(); } catch (const SqliteException&) { TRC(1, "Duplicated Transaction: " << txHash); if (height >= eng.ChainParams.CheckDupTxHeight && ContainsInLinear(GetCoinsByTxHash(txHash), true)) Throw(E_COIN_DupNonSpentTx); SqliteCommand("UPDATE txes SET coins=? WHERE id=?", m_db) .Bind(1, spend) .Bind(2, ReducedHashValue(txHash)) .ExecuteNonQuery(); } if (eng.Mode == EngMode::BlockExplorer) InsertPubkeyToTxes(tx); }
void PutDomainData(RCString domain, uint32_t height, const HashValue& hashTx, RCString addressData, bool bInsert) override { if (ResolverMode) { if (bInsert) { m_cmdInsertDomain.Bind(1, domain) .Bind(2, addressData) .Bind(3, height) .ExecuteNonQuery(); } else { m_cmdUpdateDomain.Bind(3, domain) .Bind(1, addressData) .Bind(2, height) .ExecuteNonQuery(); } } else { if (bInsert) { m_cmdInsertDomain.Bind(1, domain) .Bind(2, ReducedHashValue(hashTx)) .ExecuteNonQuery(); } else { m_cmdUpdateDomain.Bind(1, ReducedHashValue(hashTx)) .Bind(2, domain) .ExecuteNonQuery(); } } }
void SaveCoinsByTxHash(const HashValue& hash, const vector<bool>& vec) override { if (find(vec.begin(), vec.end(), true) != vec.end()) m_cmdTxUpdateCoins.Bind(1, CoinEng::SpendVectorToBlob(vec)); else m_cmdTxUpdateCoins.Bind(1, nullptr); m_cmdTxUpdateCoins.Bind(2, ReducedHashValue(hash)) .ExecuteNonQuery(); }
vector<bool> GetCoinsByTxHash(const HashValue& hash) override { DbDataReader dr = m_cmdTxFindCoins.Bind(1, ReducedHashValue(hash)).ExecuteVector(); vector<bool> vec; if (!dr.IsDBNull(0)) { CMemReadStream stm(dr.GetBytes(0)); for (int v; (v=stm.ReadByte())!=-1;) { for (int i=0; i<8; ++i) vec.push_back(v & (1 << i)); } } return vec; }
pair<int, int> FindPrevTxCoords(DbWriter& wr, int height, const HashValue& hash) override { //!!! ASSERT(!MtxSqlite.try_lock()); DbDataReader dr = m_cmdTxHashToBlockordIdx .Bind(1, ReducedHashValue(hash)) .ExecuteVector(); int heightOut = dr.GetInt32(0); wr.Write7BitEncoded(height-heightOut+1); pair<int, int> pp = TxHashesOutNums(dr.GetBytes(1)).StartingTxOutIdx(hash); if (pp.second < 0) Throw(E_COIN_InconsistentDatabase); return pp; }
bool FindTx(const HashValue& hash, Tx *ptx) override { EXT_LOCK (MtxSqlite) { DbDataReader dr = m_cmdFindTx.Bind(1, ReducedHashValue(hash)).ExecuteReader(); if (!dr.Read()) return false; if (ptx) { ptx->EnsureCreate(); ptx->SetHash(hash); LoadFromDb(*ptx, dr); } } return true; }
void OptionalDeleteExpiredDomains(uint32_t height) override { if (ResolverMode) { if (!(heightExpired & 0xFF)) { SqliteCommand(EXT_STR("DELETE FROM domains WHERE height <= " << heightExpired), m_db) .ExecuteNonQuery(); } } else { Block blockExpired = GetBlockByHeight(heightExpired); EXT_FOR (const TxHashOutNum& hom, blockExpired.get_TxHashesOutNums()) { m_cmdDeleteDomain .Bind(1, ReducedHashValue(hom.HashTx)) .ExecuteNonQuery(); } } }
void ReadTxIns(const HashValue& hash, const TxObj& txObj) override { EXT_LOCK (MtxSqlite) { txObj.ReadTxIns(DbReader(CMemReadStream(m_cmdTxFindIns.Bind(1, ReducedHashValue(hash)).ExecuteVector().GetBytes(0)), &Eng())); } }