From 840e915e8f8a432c427edf48d0ea5063815a2c14 Mon Sep 17 00:00:00 2001 From: Rucknium Date: Mon, 18 Nov 2024 15:03:01 +0000 Subject: [PATCH] Add key images to txpool data collection Useful for retrospectively analyzing intentional or unintentional double-spend attempts --- R/ip.R | 2 +- R/txpool.R | 23 ++++++++++++++++++----- man/peers.ip.collect.Rd | 2 +- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/R/ip.R b/R/ip.R index 045623e..16648ad 100644 --- a/R/ip.R +++ b/R/ip.R @@ -51,7 +51,7 @@ in.malicious.ips <- function(x, malicious.ips) { #' #' @examples #' \dontrun{ -#' suspected.malicious.ips <-readLines( +#' suspected.malicious.ips <- readLines( #' "https://raw.githubusercontent.com/Boog900/monero-ban-list/refs/heads/main/ban_list.txt") #' peers.ip.collect(malicious.ips = suspected.malicious.ips) #' } diff --git a/R/txpool.R b/R/txpool.R index ddafaf4..20bbb41 100644 --- a/R/txpool.R +++ b/R/txpool.R @@ -1,8 +1,6 @@ - - #' Initialize txpool archive database #' #' @description Initializes a database file to record the arrival time of @@ -29,6 +27,7 @@ txpool.init <- function(db.file = "xmr-txpool-archive.db") { } con <- DBI::dbConnect(RSQLite::SQLite(), db.file) + on.exit(DBI::dbDisconnect(con)) DBI::dbExecute(con, "PRAGMA journal_mode=WAL;") # txpool.export() can read while txpool.collect() writes # https://stackoverflow.com/questions/15143871/simplest-way-to-retry-sqlite-query-if-db-is-locked @@ -39,6 +38,7 @@ id_hash TEXT, fee TEXT, weight TEXT, receive_time TEXT, +key_images TEXT, unique(id_hash) )") # unique(id_hash) prevents the same txs being inserted more than once @@ -182,7 +182,13 @@ txpool.collect <- function(db.file = "xmr-txpool-archive.db", # txpool.export() can read while txpool.collect() writes # https://stackoverflow.com/questions/15143871/simplest-way-to-retry-sqlite-query-if-db-is-locked - on.exit(message(paste0("txpool data collection stopped at ", base::date()))) + try(DBI::dbExecute(con, "ALTER TABLE txs ADD COLUMN key_images TEXT"), silent = TRUE) + # This is in case there is an older version of the database without key_images + + on.exit({ + DBI::dbDisconnect(con) + message(paste0("txpool data collection stopped at ", base::date())) + }) while (TRUE) { @@ -200,17 +206,23 @@ txpool.collect <- function(db.file = "xmr-txpool-archive.db", txs <- vector(mode = "list", length = length(tx.pool)) for (i in seq_along(tx.pool)) { + + tx_json <- RJSONIO::fromJSON(tx.pool[[i]]$tx_json) + key.images <- sapply(tx_json$vin, FUN = function(x) {x$key$k_image}) + key.images <- paste0(key.images, collapse = ";") + txs[[i]] <- data.table::data.table( id_hash = tx.pool[[i]]$id_hash, fee = tx.pool[[i]]$fee, weight = tx.pool[[i]]$weight, - receive_time = tx.pool[[i]]$receive_time) + receive_time = tx.pool[[i]]$receive_time, + key_images = key.images) } txs <- data.table::rbindlist(txs) tx.statement <- DBI::dbSendQuery(con, - "INSERT OR IGNORE INTO txs VALUES (:id_hash,:fee,:weight,:receive_time)") + "INSERT OR IGNORE INTO txs VALUES (:id_hash,:fee,:weight,:receive_time,:key_images)") # "IGNORE" prevents the same txs from being inserted more than once DBI::dbBind(tx.statement, params = txs) DBI::dbClearResult(tx.statement) @@ -287,6 +299,7 @@ txpool.export <- function(db.file = "xmr-txpool-archive.db", csv.filepath = "", end.date.filename <- ifelse(end.date == "2035-01-01", "", paste0("end-" , end.date, "-")) con <- DBI::dbConnect(RSQLite::SQLite(), db.file) + on.exit(DBI::dbDisconnect(con)) DBI::dbExecute(con, "PRAGMA journal_mode=WAL;") # txpool.export() can read while txpool.collect() writes # https://stackoverflow.com/questions/15143871/simplest-way-to-retry-sqlite-query-if-db-is-locked diff --git a/man/peers.ip.collect.Rd b/man/peers.ip.collect.Rd index 83b0888..44d7a3b 100644 --- a/man/peers.ip.collect.Rd +++ b/man/peers.ip.collect.Rd @@ -47,7 +47,7 @@ infinite loop. \code{ctrl + c} to interrupt the function. } \examples{ \dontrun{ -suspected.malicious.ips <-readLines( +suspected.malicious.ips <- readLines( "https://raw.githubusercontent.com/Boog900/monero-ban-list/refs/heads/main/ban_list.txt") peers.ip.collect(malicious.ips = suspected.malicious.ips) }