diff options
Diffstat (limited to 'src/blockchain_db')
-rw-r--r-- | src/blockchain_db/blockchain_db.cpp | 6 | ||||
-rw-r--r-- | src/blockchain_db/blockchain_db.h | 18 | ||||
-rw-r--r-- | src/blockchain_db/lmdb/db_lmdb.cpp | 52 | ||||
-rw-r--r-- | src/blockchain_db/lmdb/db_lmdb.h | 1 | ||||
-rw-r--r-- | src/blockchain_db/testdb.h | 1 |
5 files changed, 73 insertions, 5 deletions
diff --git a/src/blockchain_db/blockchain_db.cpp b/src/blockchain_db/blockchain_db.cpp index 5fec22d8d..1a6a19da5 100644 --- a/src/blockchain_db/blockchain_db.cpp +++ b/src/blockchain_db/blockchain_db.cpp @@ -67,7 +67,7 @@ bool matches_category(relay_method method, relay_category category) noexcept case relay_method::local: return false; case relay_method::block: - case relay_method::flood: + case relay_method::fluff: return true; case relay_method::none: break; @@ -90,7 +90,7 @@ void txpool_tx_meta_t::set_relay_method(relay_method method) noexcept is_local = 1; break; default: - case relay_method::flood: + case relay_method::fluff: break; case relay_method::block: kept_by_block = 1; @@ -106,7 +106,7 @@ relay_method txpool_tx_meta_t::get_relay_method() const noexcept return relay_method::none; if (is_local) return relay_method::local; - return relay_method::flood; + return relay_method::fluff; } const command_line::arg_descriptor<std::string> arg_db_sync_mode = { diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h index b2c5d6cb4..e9fc85803 100644 --- a/src/blockchain_db/blockchain_db.h +++ b/src/blockchain_db/blockchain_db.h @@ -108,7 +108,7 @@ extern const command_line::arg_descriptor<bool, false> arg_db_salvage; enum class relay_category : uint8_t { - broadcasted = 0,//!< Public txes received via block/flooding/fluff + broadcasted = 0,//!< Public txes received via block/fluff relayable, //!< Every tx not marked `relay_method::none` legacy, //!< `relay_category::broadcasted` + `relay_method::none` for rpc relay requests or historical reasons all //!< Everything in the db @@ -1275,6 +1275,22 @@ public: virtual bool get_pruned_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const = 0; /** + * @brief fetches a number of pruned transaction blob from the given hash, in canonical blockchain order + * + * The subclass should return the pruned transactions stored from the one with the given + * hash. + * + * If the first transaction does not exist, the subclass should return false. + * If the first transaction exists, but there are fewer transactions starting with it + * than requested, the subclass should return false. + * + * @param h the hash to look for + * + * @return true iff the transactions were found + */ + virtual bool get_pruned_tx_blobs_from(const crypto::hash& h, size_t count, std::vector<cryptonote::blobdata> &bd) const = 0; + + /** * @brief fetches the prunable transaction blob with the given hash * * The subclass should return the prunable transaction stored which has the given diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index e8667adcf..5093015f2 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -163,7 +163,15 @@ int BlockchainLMDB::compare_string(const MDB_val *a, const MDB_val *b) { const char *va = (const char*) a->mv_data; const char *vb = (const char*) b->mv_data; - return strcmp(va, vb); + const size_t sz = std::min(a->mv_size, b->mv_size); + int ret = strncmp(va, vb, sz); + if (ret) + return ret; + if (a->mv_size < b->mv_size) + return -1; + if (a->mv_size > b->mv_size) + return 1; + return 0; } } @@ -3057,6 +3065,48 @@ bool BlockchainLMDB::get_pruned_tx_blob(const crypto::hash& h, cryptonote::blobd return true; } +bool BlockchainLMDB::get_pruned_tx_blobs_from(const crypto::hash& h, size_t count, std::vector<cryptonote::blobdata> &bd) const +{ + LOG_PRINT_L3("BlockchainLMDB::" << __func__); + check_open(); + + if (!count) + return true; + + TXN_PREFIX_RDONLY(); + RCURSOR(tx_indices); + RCURSOR(txs_pruned); + + bd.reserve(bd.size() + count); + + MDB_val_set(v, h); + MDB_val result; + int res = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &v, MDB_GET_BOTH); + if (res == MDB_NOTFOUND) + return false; + if (res) + throw0(DB_ERROR(lmdb_error("DB error attempting to fetch tx from hash", res).c_str())); + + const txindex *tip = (const txindex *)v.mv_data; + const uint64_t id = tip->data.tx_id; + MDB_val_set(val_tx_id, id); + MDB_cursor_op op = MDB_SET; + while (count--) + { + res = mdb_cursor_get(m_cur_txs_pruned, &val_tx_id, &result, op); + op = MDB_NEXT; + if (res == MDB_NOTFOUND) + return false; + if (res) + throw0(DB_ERROR(lmdb_error("DB error attempting to fetch tx blob", res).c_str())); + bd.emplace_back(reinterpret_cast<char*>(result.mv_data), result.mv_size); + } + + TXN_POSTFIX_RDONLY(); + + return true; +} + bool BlockchainLMDB::get_prunable_tx_blob(const crypto::hash& h, cryptonote::blobdata &bd) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h index e56711e8f..7c0b4c72c 100644 --- a/src/blockchain_db/lmdb/db_lmdb.h +++ b/src/blockchain_db/lmdb/db_lmdb.h @@ -254,6 +254,7 @@ public: virtual bool get_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const; virtual bool get_pruned_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const; + virtual bool get_pruned_tx_blobs_from(const crypto::hash& h, size_t count, std::vector<cryptonote::blobdata> &bd) const; virtual bool get_prunable_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const; virtual bool get_prunable_tx_hash(const crypto::hash& tx_hash, crypto::hash &prunable_hash) const; diff --git a/src/blockchain_db/testdb.h b/src/blockchain_db/testdb.h index a5847dec6..46de38c7e 100644 --- a/src/blockchain_db/testdb.h +++ b/src/blockchain_db/testdb.h @@ -69,6 +69,7 @@ public: virtual cryptonote::blobdata get_block_blob(const crypto::hash& h) const override { return cryptonote::blobdata(); } virtual bool get_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const override { return false; } virtual bool get_pruned_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const override { return false; } + virtual bool get_pruned_tx_blobs_from(const crypto::hash& h, size_t count, std::vector<cryptonote::blobdata> &bd) const { return false; } virtual bool get_prunable_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const override { return false; } virtual bool get_prunable_tx_hash(const crypto::hash& tx_hash, crypto::hash &prunable_hash) const override { return false; } virtual uint64_t get_block_height(const crypto::hash& h) const override { return 0; } |