Skip to content

Commit

Permalink
Fetch etching inputs using Bitcoin Core RPC (ordinals#3336)
Browse files Browse the repository at this point in the history
  • Loading branch information
raphjaph committed Mar 23, 2024
1 parent c5cfe4e commit a2c1a1d
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 78 deletions.
17 changes: 12 additions & 5 deletions crates/test-bitcoincore-rpc/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -607,8 +607,15 @@ impl Api for Server {
blockhash: Option<BlockHash>,
) -> Result<Value, jsonrpc_core::Error> {
assert_eq!(blockhash, None, "Blockhash param is unsupported");
let state = self.state();
let current_height: u32 = (state.hashes.len() - 1).try_into().unwrap();
let confirmations = state
.txid_to_block_height
.get(&txid)
.map(|tx_height| current_height - tx_height);

if verbose.unwrap_or(false) {
match self.state().transactions.get(&txid) {
match state.transactions.get(&txid) {
Some(transaction) => Ok(
serde_json::to_value(GetRawTransactionResult {
in_active_chain: Some(true),
Expand All @@ -628,8 +635,8 @@ impl Api for Server {
n: n.try_into().unwrap(),
value: Amount::from_sat(output.value),
script_pub_key: GetRawTransactionResultVoutScriptPubKey {
asm: String::new(),
hex: Vec::new(),
asm: output.script_pubkey.to_asm_string(),
hex: output.script_pubkey.clone().into(),
req_sigs: None,
type_: None,
addresses: Vec::new(),
Expand All @@ -638,7 +645,7 @@ impl Api for Server {
})
.collect(),
blockhash: None,
confirmations: Some(1),
confirmations,
time: None,
blocktime: None,
})
Expand All @@ -647,7 +654,7 @@ impl Api for Server {
None => Err(Self::not_found()),
}
} else {
match self.state().transactions.get(&txid) {
match state.transactions.get(&txid) {
Some(tx) => Ok(Value::String(hex::encode(serialize(tx)))),
None => Err(Self::not_found()),
}
Expand Down
6 changes: 6 additions & 0 deletions crates/test-bitcoincore-rpc/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub struct State {
pub network: Network,
pub nonce: u32,
pub transactions: BTreeMap<Txid, Transaction>,
pub txid_to_block_height: BTreeMap<Txid, u32>,
pub utxos: BTreeMap<OutPoint, Amount>,
pub version: usize,
pub receive_addresses: Vec<Address>,
Expand Down Expand Up @@ -49,6 +50,7 @@ impl State {
nonce: 0,
receive_addresses: Vec::new(),
transactions: BTreeMap::new(),
txid_to_block_height: BTreeMap::new(),
utxos: BTreeMap::new(),
version,
wallets: BTreeSet::new(),
Expand Down Expand Up @@ -155,6 +157,10 @@ impl State {
};

for tx in block.txdata.iter() {
self
.txid_to_block_height
.insert(tx.txid(), self.hashes.len().try_into().unwrap());

for input in tx.input.iter() {
if !input.previous_output.is_null() {
assert!(self.utxos.remove(&input.previous_output).is_some());
Expand Down
6 changes: 2 additions & 4 deletions src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ use {
self::{
entry::{
Entry, HeaderValue, InscriptionEntry, InscriptionEntryValue, InscriptionIdValue,
OutPointValue, OutputEntry, OutputValue, RuneEntryValue, RuneIdValue, SatPointValue,
SatRange, TxidValue,
OutPointValue, RuneEntryValue, RuneIdValue, SatPointValue, SatRange, TxidValue,
},
event::Event,
reorg::*,
Expand Down Expand Up @@ -72,7 +71,6 @@ define_table! { HEIGHT_TO_LAST_SEQUENCE_NUMBER, u32, u32 }
define_table! { HOME_INSCRIPTIONS, u32, InscriptionIdValue }
define_table! { INSCRIPTION_ID_TO_SEQUENCE_NUMBER, InscriptionIdValue, u32 }
define_table! { INSCRIPTION_NUMBER_TO_SEQUENCE_NUMBER, i32, u32 }
define_table! { OUTPOINT_TO_OUTPUT, &OutPointValue, OutputValue }
define_table! { OUTPOINT_TO_RUNE_BALANCES, &OutPointValue, &[u8] }
define_table! { OUTPOINT_TO_SAT_RANGES, &OutPointValue, &[u8] }
define_table! { OUTPOINT_TO_VALUE, &OutPointValue, u64}
Expand Down Expand Up @@ -208,7 +206,7 @@ impl<T> BitcoinCoreRpcResultExt<T> for Result<T, bitcoincore_rpc::Error> {
}

pub struct Index {
client: Client,
pub(crate) client: Client,
database: Database,
durability: redb::Durability,
event_sender: Option<tokio::sync::mpsc::Sender<Event>>,
Expand Down
32 changes: 0 additions & 32 deletions src/index/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,6 @@ impl Entry for Header {
}
}

#[derive(Debug, PartialEq, Copy, Clone)]
pub(super) struct OutputEntry {
pub(super) height: u32,
pub(super) taproot: bool,
}

pub(super) type OutputValue = (u32, bool);

impl Entry for OutputEntry {
type Value = OutputValue;

fn load((height, taproot): Self::Value) -> Self {
Self { height, taproot }
}

fn store(self) -> Self::Value {
(self.height, self.taproot)
}
}

#[derive(Debug, PartialEq, Copy, Clone, Serialize, Deserialize)]
pub struct RuneEntry {
pub burned: u128,
Expand Down Expand Up @@ -570,16 +550,4 @@ mod tests {

assert_eq!(actual, expected);
}

#[test]
fn output() {
let value = (0, true);
let entry = OutputEntry {
height: 0,
taproot: true,
};

assert_eq!(entry.store(), value);
assert_eq!(OutputEntry::load(value), entry);
}
}
3 changes: 1 addition & 2 deletions src/index/updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,6 @@ impl<'index> Updater<'index> {

if self.index.index_runes && self.height >= self.index.settings.first_rune_height() {
let mut outpoint_to_rune_balances = wtx.open_table(OUTPOINT_TO_RUNE_BALANCES)?;
let mut outpoint_to_output = wtx.open_table(OUTPOINT_TO_OUTPUT)?;
let mut rune_id_to_rune_entry = wtx.open_table(RUNE_ID_TO_RUNE_ENTRY)?;
let mut rune_to_rune_id = wtx.open_table(RUNE_TO_RUNE_ID)?;
let mut sequence_number_to_rune_id = wtx.open_table(SEQUENCE_NUMBER_TO_RUNE_ID)?;
Expand All @@ -592,12 +591,12 @@ impl<'index> Updater<'index> {
.unwrap_or(0);

let mut rune_updater = RuneUpdater {
client: &self.index.client,
height: self.height,
id_to_entry: &mut rune_id_to_rune_entry,
inscription_id_to_sequence_number: &mut inscription_id_to_sequence_number,
minimum: Rune::minimum_at_height(self.index.settings.chain(), Height(self.height)),
outpoint_to_balances: &mut outpoint_to_rune_balances,
outpoint_to_output: &mut outpoint_to_output,
rune_to_id: &mut rune_to_rune_id,
runes,
sequence_number_to_rune_id: &mut sequence_number_to_rune_id,
Expand Down
52 changes: 17 additions & 35 deletions src/index/updater/rune_updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ pub(crate) struct RuneUpdate {
pub(crate) supply: u128,
}

pub(super) struct RuneUpdater<'a, 'tx> {
pub(super) struct RuneUpdater<'a, 'tx, 'client> {
pub(super) client: &'client Client,
pub(super) height: u32,
pub(super) id_to_entry: &'a mut Table<'tx, RuneIdValue, RuneEntryValue>,
pub(super) inscription_id_to_sequence_number: &'a Table<'tx, InscriptionIdValue, u32>,
pub(super) minimum: Rune,
pub(super) outpoint_to_balances: &'a mut Table<'tx, &'static OutPointValue, &'static [u8]>,
pub(super) outpoint_to_output: &'a mut Table<'tx, &'static OutPointValue, OutputValue>,
pub(super) rune_to_id: &'a mut Table<'tx, u128, RuneIdValue>,
pub(super) runes: u64,
pub(super) sequence_number_to_rune_id: &'a mut Table<'tx, u32, RuneIdValue>,
Expand All @@ -40,7 +40,7 @@ pub(super) struct RuneUpdater<'a, 'tx> {
pub(super) updates: HashMap<RuneId, RuneUpdate>,
}

impl<'a, 'tx> RuneUpdater<'a, 'tx> {
impl<'a, 'tx, 'client> RuneUpdater<'a, 'tx, 'client> {
pub(super) fn index_runes(&mut self, tx_index: u32, tx: &Transaction, txid: Txid) -> Result<()> {
let runestone = Runestone::from_transaction(tx);

Expand Down Expand Up @@ -222,33 +222,6 @@ impl<'a, 'tx> RuneUpdater<'a, 'tx> {
)?;
}

for input in tx.input.iter() {
if input.previous_output.is_null() {
continue;
}

self
.outpoint_to_output
.remove(&input.previous_output.store())?
.unwrap();
}

for (vout, output) in tx.output.iter().enumerate() {
let outpoint = OutPoint {
txid,
vout: vout.try_into().unwrap(),
};

self.outpoint_to_output.insert(
&outpoint.store(),
OutputEntry {
height: self.height,
taproot: output.script_pubkey.is_v1_p2tr(),
}
.store(),
)?;
}

// increment entries with burned runes
for (id, amount) in burned {
self.updates.entry(id).or_default().burned += amount;
Expand Down Expand Up @@ -402,16 +375,25 @@ impl<'a, 'tx> RuneUpdater<'a, 'tx> {
continue;
}

let Some(output) = self
.outpoint_to_output
.get(&input.previous_output.store())?
let Some(tx_info) = self
.client
.get_raw_transaction_info(&input.previous_output.txid, None)
.into_option()?
else {
panic!("input not in UTXO set: {}", input.previous_output);
};

let output = OutputEntry::load(output.value());
let taproot = tx_info.vout[input.previous_output.vout.into_usize()]
.script_pub_key
.script()?
.is_v1_p2tr();

let mature = tx_info
.confirmations
.map(|confirmations| confirmations >= RUNE_COMMIT_INTERVAL)
.unwrap_or_default();

if output.taproot && self.height >= output.height + RUNE_COMMIT_INTERVAL {
if taproot && mature {
return Ok(true);
}
}
Expand Down

0 comments on commit a2c1a1d

Please sign in to comment.