misc-research/Pre-fork-BCH-BTC-Spending/aggregate-spent-status-data.R
2022-04-09 14:38:00 +00:00

105 lines
4 KiB
R

library(data.table)
library(RSQLite)
library(DBI)
library(scales)
# NOTE: Also need lubridate package installed, but not loading it due to
# it masking functions
bch.data.dir <- ""
btc.data.dir <- ""
# Input data directory here, with trailing "/"
con.bch <- DBI::dbConnect(RSQLite::SQLite(), paste0(bch.data.dir, "tx-graph-node-indices.db"))
con.btc <- DBI::dbConnect(RSQLite::SQLite(), paste0(btc.data.dir, "tx-graph-node-indices.db"))
pre.fork.edgelist <- DBI::dbGetQuery(con.bch,
"SELECT origin_index, destination_index FROM edgelist_intermediate_2 WHERE block_height <= 478558")
# 478558 is last block height that BCH and BTC share a block
pre.fork.utxo.set <- setdiff(pre.fork.edgelist$destination_index, pre.fork.edgelist$origin_index)
DBI::dbWriteTable(con.bch, "pre_fork_utxo_set",
data.frame(destination_index = pre.fork.utxo.set, stringsAsFactors = FALSE))
pre.fork.utxo.set.value <- DBI::dbGetQuery(con.bch,
'SELECT destination_index, value FROM edgelist_intermediate_2 WHERE destination_index IN (SELECT destination_index FROM pre_fork_utxo_set)')
setDT(pre.fork.utxo.set.value)
pre.fork.bitcoin.supply <- 50 * length(0:209999) + 25 * length(210000:419999) + 12.5 * length(420000:478558)
pre.fork.utxo.set.value[, sum(value)] / pre.fork.bitcoin.supply
# [1] 0.99984
pre.fork.bitcoin.supply - pre.fork.utxo.set.value[, sum(value)]
# [1] 2637.559
pre.fork.utxo.set.value <- pre.fork.utxo.set.value[ ! destination_index %in% c(1740174960, 1740175469), ]
# Removes the transactions that are coinbases of blocks 91722, 91812, 91842, 91880
# Since they are duplicated transaction hashes. See:
# https://bitcoin.stackexchange.com/questions/40444/what-happens-when-two-txids-collide
# https://github.com/bitcoin/bitcoin/commit/ab91bf39b7c11e9c86bb2043c24f0f377f1cf514
excluded.duplicate.tx.hashes.output.count <- 4
excluded.duplicate.tx.hashes.value <- 50 * 4
spent.status <- DBI::dbGetQuery(con.bch,
'SELECT origin_index, block_height FROM edgelist_intermediate_2 WHERE origin_index IN (SELECT destination_index FROM pre_fork_utxo_set)')
colnames(spent.status) <- c("destination_index", "bch.spent.block_height")
setDT(spent.status)
spent.status <- merge(pre.fork.utxo.set.value, spent.status, all.x = TRUE)
# rm(pre.fork.utxo.set.value)
# aggregate(spent.status$value, by = list(! is.na(spent.status$bch.spent.block_height)), FUN = sum)
# Group.1 x
# 1 FALSE 5699742
# 2 TRUE 10779508
# table(spent.status[value > 0, ! is.na(bch.spent.block_height)])
# FALSE TRUE
# 29154762 21307064
bch.block.times <- readRDS(paste0(bch.data.dir, "block_times.rds"))
bch.block.times[, block_time := as.POSIXct(block_time, origin = "1970-01-01", tz = "GMT")]
colnames(bch.block.times) <- c("bch.spent.block_height", "block_time")
spent.status <- merge(spent.status, bch.block.times, all = TRUE, by = "bch.spent.block_height")
# Note that due to all = TRUE this will get all blocks,
# even if there are no target spent outputs within the block
spent.status.by.block <- spent.status[,
.(value = sum(value, na.rm= TRUE), n.outputs = length(destination_index[ (! is.na(value)) & value > 0])),
by = .(bch.spent.block_height, block_time)]
spent.status.by.block[, block_time.date := lubridate::date(block_time)]
spent.status.by.date <- spent.status.by.block[,
.(value = sum(value, na.rm= TRUE), n.outputs = sum(n.outputs, na.rm= TRUE)),
by = .(block_time.date)]
unspent <- spent.status.by.date[is.na(block_time.date), value]
cumsum.na.rm <- function(x) {x[is.na(x)] <- 0; cumsum(x)}
spent.status.by.date[, value.cumsum := cumsum.na.rm(value) - unspent]
spent.status.by.date[, perc.value.cumsum := 100 * value.cumsum / sum(value, na.rm = TRUE)]
spent.status.by.date[, unspent.perc.value.cumsum := 100 - perc.value.cumsum]
btc.spent.status <- DBI::dbGetQuery(con.btc,
'SELECT origin_index, block_height FROM edgelist_intermediate_2 WHERE origin_index IN (SELECT destination_index FROM pre_fork_utxo_set)')
colnames(btc.spent.status) <- c("destination_index, btc.spent.block_height")
setDT(btc.spent.status)
spent.status <- merge(spent.status, btc.spent.status, all.x = TRUE)