From cb86c1052399738f1dd1d191dc844f649f3b8eb7 Mon Sep 17 00:00:00 2001 From: Rucknium Date: Wed, 2 Mar 2022 15:10:50 +0000 Subject: [PATCH] Add get-coinbases.R --- .../R/get-coinbases.R | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 CashFusion-Descendant-Analysis/R/get-coinbases.R diff --git a/CashFusion-Descendant-Analysis/R/get-coinbases.R b/CashFusion-Descendant-Analysis/R/get-coinbases.R new file mode 100644 index 0000000..3200cb5 --- /dev/null +++ b/CashFusion-Descendant-Analysis/R/get-coinbases.R @@ -0,0 +1,124 @@ + +# install.packages("rbch") +# install.packages("data.table") +# install.packages("future.apply") +# install.packages("stringr") + +library(rbch) +library(data.table) +library(future.apply) +library(stringr) + + +bitcoin.conf.file <- "" +# Input filepath for your bitcoin.conf file + +data.dir <- "" +# Input data directory here, with trailing "/" + +bch.config <- rbch::conrpc(bitcoin.conf.file) + + +con <- DBI::dbConnect(RSQLite::SQLite(), paste0(data.dir, "tx-graph-node-indices.db")) + + +# first.fusion.height <- 646085 + +# current.block.height <- rbch::getblockchaininfo(bch.config)@result$blocks + +tx.graph.files <- list.files(data.dir) +tx.graph.files <- tx.graph.files[grepl("^tx_graph.+rds$", tx.graph.files)] + +first.fusion.height <- min(as.numeric(unlist(stringr::str_extract_all(tx.graph.files, "[0-9]+")))) +current.block.height <- max(as.numeric(unlist(stringr::str_extract_all(tx.graph.files, "[0-9]+")))) + + +heights.to.process <- first.fusion.height:current.block.height +heights.to.process <- split(heights.to.process, + cut(heights.to.process, ceiling(length(heights.to.process)/50))) + +future::plan(future::multiprocess()) + +coinbases <- list() + +for (height.set in heights.to.process) { + + fused.all.ls <- future.apply::future_lapply(height.set, function(iter.block.height) { + + if (iter.block.height %% 1000 == 0) { + cat(iter.block.height, base::date(), "\n") + } + + block.hash <- rbch::getblockhash(bch.config, iter.block.height) + block.data <- rbch::getblock(bch.config, blockhash = block.hash@result, verbosity = "l2") + # Argument verbose = 2 gives full transaction data + # For some reason it doesn't give the fee: + # https://docs.bitcoincashnode.org/doc/json-rpc/getrawtransaction.html + + raw.txs.ls <- block.data@result$tx + + coinbase.tx <- raw.txs.ls[[1]] + + value <- vector("numeric", length(coinbase.tx$vout) ) + + for (j in seq_along(coinbase.tx$vout)) { + value[j] <- coinbase.tx$vout[[j]]$value + } + + outgoing <- data.table(txid = coinbase.tx$txid, + position = seq_along(coinbase.tx$vout), value = value, stringsAsFactors = FALSE) + + list(outgoing) + + }) + + + print(object.size(fused.all.ls), units = "Mb") + + fused.all.ls <- unlist(fused.all.ls, recursive = FALSE) + + outgoing <- data.table::rbindlist(fused.all.ls) + + coinbases[[length(coinbases) + 1]] <- outgoing + + rm(fused.all.ls) + rm(outgoing) + +} + + +coinbases <- data.table::rbindlist(coinbases) + +coinbases$txid_position <- paste0(coinbases$txid, "-", + formatC(coinbases$position, width = 4, format = "f", flag = "0", digits = 0)) + + +DBI::dbWriteTable(con, "coinbases", coinbases, overwrite = TRUE) + + +DBI::dbWriteTable(con, "coinbases_intermediate_1", + data.frame(txid_position = character(0), stringsAsFactors = FALSE), + overwrite = TRUE) + + +base::date() +DBI::dbExecute(con, "INSERT INTO coinbases_intermediate_1 SELECT + txid_position FROM + coinbases EXCEPT + SELECT origin FROM edgelist") +base::date() + + +unspent.coinbases <- DBI::dbGetQuery(con, + 'SELECT * FROM coinbases_intermediate_1') + +unspent.coinbases <- merge(unspent.coinbases, coinbases) + + +saveRDS(unspent.coinbases, + file = paste0(data.dir, "unspent_coinbases.rds"), + compress = FALSE) + + + +