Skip to content

Commit

Permalink
Show timestamp on /inscription (ordinals#1200)
Browse files Browse the repository at this point in the history
  • Loading branch information
casey authored Jan 12, 2023
1 parent e810c02 commit 1a0f61a
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 113 deletions.
115 changes: 48 additions & 67 deletions src/index.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use {
self::updater::Updater,
self::{
inscription_entry::{InscriptionEntry, InscriptionEntryValue},
updater::Updater,
},
super::*,
bitcoin::BlockHeader,
bitcoincore_rpc::{json::GetBlockHeaderResult, Auth, Client},
Expand All @@ -10,6 +13,7 @@ use {
std::sync::atomic::{self, AtomicBool},
};

mod inscription_entry;
mod rtx;
mod updater;

Expand All @@ -28,9 +32,7 @@ macro_rules! define_table {
}

define_table! { HEIGHT_TO_BLOCK_HASH, u64, &BlockHashArray }
define_table! { INSCRIPTION_ID_TO_HEIGHT, &InscriptionIdArray, u64 }
define_table! { INSCRIPTION_ID_TO_INSCRIPTION_NUMBER, &InscriptionIdArray, u64}
define_table! { INSCRIPTION_ID_TO_SAT, &InscriptionIdArray, u64 }
define_table! { INSCRIPTION_ID_TO_INSCRIPTION_ENTRY, &InscriptionIdArray, InscriptionEntryValue }
define_table! { INSCRIPTION_ID_TO_SATPOINT, &InscriptionIdArray, &SatPointArray }
define_table! { INSCRIPTION_NUMBER_TO_INSCRIPTION_ID, u64, &InscriptionIdArray }
define_table! { OUTPOINT_TO_SAT_RANGES, &OutPointArray, &[u8] }
Expand Down Expand Up @@ -161,13 +163,6 @@ impl Index {
let rpc_url = options.rpc_url();
let cookie_file = options.cookie_file()?;

if cfg!(test) {
// The default max database size is 10 MiB for Regtest and 1 TiB
// for all other networks. A larger database takes longer to
// initialize, so unit tests should use the regtest network.
assert_eq!(options.chain(), Chain::Regtest);
}

log::info!(
"Connecting to Bitcoin Core RPC server at {rpc_url} using credentials from `{}`",
cookie_file.display()
Expand Down Expand Up @@ -235,9 +230,7 @@ impl Index {
};

tx.open_table(HEIGHT_TO_BLOCK_HASH)?;
tx.open_table(INSCRIPTION_ID_TO_HEIGHT)?;
tx.open_table(INSCRIPTION_ID_TO_INSCRIPTION_NUMBER)?;
tx.open_table(INSCRIPTION_ID_TO_SAT)?;
tx.open_table(INSCRIPTION_ID_TO_INSCRIPTION_ENTRY)?;
tx.open_table(INSCRIPTION_ID_TO_SATPOINT)?;
tx.open_table(INSCRIPTION_NUMBER_TO_INSCRIPTION_ID)?;
tx.open_table(OUTPOINT_TO_VALUE)?;
Expand Down Expand Up @@ -498,20 +491,6 @@ impl Index {
)
}

pub(crate) fn get_inscription_number_by_inscription_id(
&self,
id: InscriptionId,
) -> Result<Option<u64>> {
Ok(
self
.database
.begin_read()?
.open_table(INSCRIPTION_ID_TO_INSCRIPTION_NUMBER)?
.get(&id.as_inner())?
.map(|n| n.value()),
)
}

pub(crate) fn get_inscription_id_by_inscription_number(
&self,
n: u64,
Expand All @@ -526,39 +505,29 @@ impl Index {
)
}

pub(crate) fn get_sat_by_inscription_id(
pub(crate) fn get_inscription_satpoint_by_id(
&self,
inscription_id: InscriptionId,
) -> Result<Option<Sat>> {
) -> Result<Option<SatPoint>> {
Ok(
self
.database
.begin_read()?
.open_table(INSCRIPTION_ID_TO_SAT)?
.open_table(INSCRIPTION_ID_TO_SATPOINT)?
.get(inscription_id.as_inner())?
.map(|value| Sat(value.value())),
.map(|satpoint| decode_satpoint(*satpoint.value())),
)
}

pub(crate) fn get_inscription_by_id(
&self,
inscription_id: InscriptionId,
) -> Result<Option<(Inscription, SatPoint)>> {
let Some(satpoint) = self
.database
.begin_read()?
.open_table(INSCRIPTION_ID_TO_SATPOINT)?
.get(inscription_id.as_inner())?
.map(|satpoint| decode_satpoint(*satpoint.value()))
else {
return Ok(None);
};

let Some(inscription) = self.get_transaction(inscription_id)?.and_then(|tx| Inscription::from_transaction(&tx)) else {
return Ok(None);
};

Ok(Some((inscription, satpoint)))
) -> Result<Option<Inscription>> {
Ok(
self
.get_transaction(inscription_id)?
.and_then(|tx| Inscription::from_transaction(&tx)),
)
}

pub(crate) fn get_inscriptions_on_output(
Expand Down Expand Up @@ -728,14 +697,18 @@ impl Index {
)
}

pub(crate) fn get_genesis_height(&self, inscription_id: InscriptionId) -> Result<u64> {
self
.database
.begin_read()?
.open_table(INSCRIPTION_ID_TO_HEIGHT)?
.get(inscription_id.as_inner())?
.map(|x| x.value())
.ok_or_else(|| anyhow!("no height for inscription"))
pub(crate) fn get_inscription_entry(
&self,
inscription_id: InscriptionId,
) -> Result<Option<InscriptionEntry>> {
Ok(
self
.database
.begin_read()?
.open_table(INSCRIPTION_ID_TO_INSCRIPTION_ENTRY)?
.get(inscription_id.as_inner())?
.map(|value| InscriptionEntry::load(value.value())),
)
}

#[cfg(test)]
Expand Down Expand Up @@ -965,16 +938,21 @@ mod tests {

assert_eq!(
context.index.get_inscription_by_id(inscription_id).unwrap(),
Some((
inscription,
SatPoint {
outpoint: OutPoint {
txid: inscription_id,
vout: 0,
},
offset: 0,
}
))
Some(inscription)
);

assert_eq!(
context
.index
.get_inscription_satpoint_by_id(inscription_id)
.unwrap(),
Some(SatPoint {
outpoint: OutPoint {
txid: inscription_id,
vout: 0,
},
offset: 0,
})
);
}

Expand All @@ -987,7 +965,10 @@ mod tests {
context.mine_blocks(1);

assert_eq!(
context.index.get_inscription_by_id(inscription_id).unwrap(),
context
.index
.get_inscription_satpoint_by_id(inscription_id)
.unwrap(),
None,
);
}
Expand Down
37 changes: 37 additions & 0 deletions src/index/inscription_entry.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use super::*;

pub(crate) struct InscriptionEntry {
pub(crate) height: u64,
pub(crate) number: u64,
pub(crate) sat: Option<Sat>,
pub(crate) timestamp: u32,
}

pub(crate) type InscriptionEntryValue = (u64, u64, u64, u32);

impl InscriptionEntry {
pub(crate) fn load((height, number, sat, timestamp): InscriptionEntryValue) -> Self {
Self {
height,
number,
sat: if sat == u64::MAX {
None
} else {
Some(Sat(sat))
},
timestamp,
}
}

pub(crate) fn store(self) -> InscriptionEntryValue {
(
self.height,
self.number,
match self.sat {
Some(sat) => sat.n(),
None => u64::MAX,
},
self.timestamp,
)
}
}
11 changes: 4 additions & 7 deletions src/index/updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,8 @@ impl Updater {
}
}

let mut inscription_id_to_height = wtx.open_table(INSCRIPTION_ID_TO_HEIGHT)?;
let mut inscription_id_to_inscription_number =
wtx.open_table(INSCRIPTION_ID_TO_INSCRIPTION_NUMBER)?;
let mut inscription_id_to_sat = wtx.open_table(INSCRIPTION_ID_TO_SAT)?;
let mut inscription_id_to_inscription_entry =
wtx.open_table(INSCRIPTION_ID_TO_INSCRIPTION_ENTRY)?;
let mut inscription_id_to_satpoint = wtx.open_table(INSCRIPTION_ID_TO_SATPOINT)?;
let mut inscription_number_to_inscription_id =
wtx.open_table(INSCRIPTION_NUMBER_TO_INSCRIPTION_ID)?;
Expand All @@ -292,16 +290,15 @@ impl Updater {

let mut inscription_updater = InscriptionUpdater::new(
self.height,
&mut inscription_id_to_height,
&mut inscription_id_to_inscription_number,
&mut inscription_id_to_satpoint,
index,
&mut inscription_id_to_sat,
&mut inscription_id_to_inscription_entry,
lost_sats,
&mut inscription_number_to_inscription_id,
&mut outpoint_to_value,
&mut sat_to_inscription_id,
&mut satpoint_to_inscription_id,
block.header.time,
value_cache,
)?;

Expand Down
37 changes: 21 additions & 16 deletions src/index/updater/inscription_updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,32 @@ enum Origin {
pub(super) struct InscriptionUpdater<'a, 'db, 'tx> {
flotsam: Vec<Flotsam>,
height: u64,
id_to_height: &'a mut Table<'db, 'tx, &'tx InscriptionIdArray, u64>,
id_to_number: &'a mut Table<'db, 'tx, &'tx InscriptionIdArray, u64>,
id_to_satpoint: &'a mut Table<'db, 'tx, &'tx InscriptionIdArray, &'tx SatPointArray>,
index: &'a Index,
inscription_id_to_sat: &'a mut Table<'db, 'tx, &'tx InscriptionIdArray, u64>,
id_to_entry: &'a mut Table<'db, 'tx, &'tx InscriptionIdArray, InscriptionEntryValue>,
lost_sats: u64,
next_number: u64,
number_to_id: &'a mut Table<'db, 'tx, u64, &'tx InscriptionIdArray>,
outpoint_to_value: &'a mut Table<'db, 'tx, &'tx OutPointArray, u64>,
reward: u64,
sat_to_inscription_id: &'a mut Table<'db, 'tx, u64, &'tx InscriptionIdArray>,
satpoint_to_id: &'a mut Table<'db, 'tx, &'tx SatPointArray, &'tx InscriptionIdArray>,
timestamp: u32,
value_cache: &'a mut HashMap<OutPoint, u64>,
}

impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
pub(super) fn new(
height: u64,
id_to_height: &'a mut Table<'db, 'tx, &'tx InscriptionIdArray, u64>,
id_to_number: &'a mut Table<'db, 'tx, &'tx InscriptionIdArray, u64>,
id_to_satpoint: &'a mut Table<'db, 'tx, &'tx InscriptionIdArray, &'tx SatPointArray>,
index: &'a Index,
inscription_id_to_sat: &'a mut Table<'db, 'tx, &'tx InscriptionIdArray, u64>,
id_to_entry: &'a mut Table<'db, 'tx, &'tx InscriptionIdArray, InscriptionEntryValue>,
lost_sats: u64,
number_to_id: &'a mut Table<'db, 'tx, u64, &'tx InscriptionIdArray>,
outpoint_to_value: &'a mut Table<'db, 'tx, &'tx OutPointArray, u64>,
sat_to_inscription_id: &'a mut Table<'db, 'tx, u64, &'tx InscriptionIdArray>,
satpoint_to_id: &'a mut Table<'db, 'tx, &'tx SatPointArray, &'tx InscriptionIdArray>,
timestamp: u32,
value_cache: &'a mut HashMap<OutPoint, u64>,
) -> Result<Self> {
let next_number = number_to_id
Expand All @@ -54,18 +52,17 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
Ok(Self {
flotsam: Vec::new(),
height,
id_to_height,
id_to_number,
id_to_satpoint,
index,
inscription_id_to_sat,
id_to_entry,
lost_sats,
next_number,
number_to_id,
outpoint_to_value,
reward: Height(height).subsidy(),
sat_to_inscription_id,
satpoint_to_id,
timestamp,
value_cache,
})
}
Expand Down Expand Up @@ -205,28 +202,36 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
self.satpoint_to_id.remove(&encode_satpoint(old_satpoint))?;
}
Origin::New => {
self.id_to_height.insert(&inscription_id, &self.height)?;
self
.id_to_number
.insert(&inscription_id, &self.next_number)?;
self
.number_to_id
.insert(&self.next_number, &inscription_id)?;

let mut sat = None;
if let Some(input_sat_ranges) = input_sat_ranges {
let mut offset = 0;
for (start, end) in input_sat_ranges {
let size = end - start;
if offset + size > flotsam.offset {
let sat = start + flotsam.offset - offset;
self.sat_to_inscription_id.insert(&sat, &inscription_id)?;
self.inscription_id_to_sat.insert(&inscription_id, &sat)?;
let n = start + flotsam.offset - offset;
self.sat_to_inscription_id.insert(&n, &inscription_id)?;
sat = Some(Sat(n));
break;
}
offset += size;
}
}

self.id_to_entry.insert(
&inscription_id,
&InscriptionEntry {
height: self.height,
number: self.next_number,
sat,
timestamp: self.timestamp,
}
.store(),
)?;

self.next_number += 1;
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ fn integration_test() -> bool {
.unwrap_or(false)
}

fn timestamp(seconds: u32) -> NaiveDateTime {
NaiveDateTime::from_timestamp_opt(seconds.into(), 0).unwrap()
}

fn main() {
env_logger::init();

Expand Down
Loading

0 comments on commit 1a0f61a

Please sign in to comment.