SHOWING: First 60
#66,953,763text
fn from_instructions(
instructions: &mut Instructions,
input: usize,
offset: usize,
) -> Result<Option<Self>> {
if instructions.next().transpose()? != Some(Instruction::Op(opcodes::all::OP_IF)) {
return Ok(None);
}
if instructions.next().transpose()? != Some(Instruction::PushBytes((&PROTOCOL_ID).into())) {
return Ok(None);
}
let mut pushnum = false;
let mut payload = Vec::new();
loop {
match instructions.next().transpose()? {
None => return Ok(None),
Some(Instruction::Op(opcodes::all::OP_ENDIF)) => {
return Ok(Some(Envelope {
input: input.try_into().unwrap(),
offset: offset.try_into().unwrap(),
payload,
pushnum,
}));
}
Some(Instruction::Op(opcodes::all::OP_PUSHNUM_NEG1)) => {
pushnum = true;
payload.push(vec![0x81]);
}
Some(Instruction::Op(opcodes::all::OP_PUSHNUM_1)) => {
pushnum = true;
payload.push(vec![1]);
#44,983,270text }
fn store(self) -> Self::Value {
let mut value = [0; 36];
self.consensus_encode(&mut value.as_mut_slice()).unwrap();
value
}
}
pub(super) type SatPointValue = [u8; 44];
impl Entry for SatPoint {
type Value = SatPointValue;
fn load(value: Self::Value) -> Self {
Decodable::consensus_decode(&mut io::Cursor::new(value)).unwrap()
}
fn store(self) -> Self::Value {
let mut value = [0; 44];
self.consensus_encode(&mut value.as_mut_slice()).unwrap();
value
}
}
pub(super) type SatRange = (u64, u64);
impl Entry for SatRange {
type Value = [u8; 11];
fn load([b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10]: Self::Value) -> Self {
let raw_base = u64::from_le_bytes([b0, b1, b2, b3, b4, b5, b6, 0]);
// 51 bit base
let base = raw_base & ((1 << 51) - 1);
let raw_delta = u64::from_le_bytes([b6, b7, b8, b9, b10, 0, 0, 0]);
// 33 bit delta
let delta = raw_delta >> 3;
(base, base + delta)
}
fn store(self) -> Self::Value {
let base = self.0;
#44,983,269text inputs: &[(1, 0, 0, inscription("text/plain", "hello").to_witness())],
..Default::default()
});
context.mine_blocks(2);
let parent_inscription_id = InscriptionId {
txid: parent_txid,
index: 0,
};
let txid = context.rpc_server.broadcast_tx(TransactionTemplate {
inputs: &[
(2, 1, 0, Default::default()),
(
3,
0,
0,
Inscription {
content_type: Some("text/plain".into()),
body: Some("hello".into()),
parent: Some(parent_inscription_id.parent_value()),
..Default::default()
}
.to_witness(),
),
],
..Default::default()
});
context.mine_blocks(1);
let inscription_id = InscriptionId { txid, index: 0 };
assert_eq!(
context.index.get_parent_by_inscription_id(inscription_id),
parent_inscription_id
);
assert_eq!(
context
#44,983,267text let delta = self.1 - self.0;
let n = u128::from(base) | u128::from(delta) << 51;
n.to_le_bytes()[0..11].try_into().unwrap()
}
}
pub(super) type TxidValue = [u8; 32];
impl Entry for Txid {
type Value = TxidValue;
fn load(value: Self::Value) -> Self {
Txid::from_byte_array(value)
}
fn store(self) -> Self::Value {
Txid::to_byte_array(self)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn inscription_id_entry() {
let inscription_id = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdefi0"
.parse::<InscriptionId>()
.unwrap();
assert_eq!(
inscription_id.store(),
(
0x0123456789abcdef0123456789abcdef,
0x0123456789abcdef0123456789abcdef,
0
)
);
assert_eq!(
InscriptionId::load((
0x0123456789abcdef0123456789abcdef,
0x0123456789abcdef0123456789abcdef,
0
)),
inscription_id
);
}
#[test]
fn parent_entry_index() {
let inscription_id = "0000000000000000000000000000000000000000000000000000000000000000i1"
#44,983,265text u32, // timestamp
);
impl Default for RuneEntry {
fn default() -> Self {
Self {
burned: 0,
divisibility: 0,
end: None,
etching: Txid::all_zeros(),
limit: None,
number: 0,
rune: Rune(0),
supply: 0,
symbol: None,
timestamp: 0,
}
}
}
impl Entry for RuneEntry {
type Value = RuneEntryValue;
fn load(
(burned, divisibility, end, etching, limit, number, rune, supply, symbol, timestamp): RuneEntryValue,
) -> Self {
Self {
burned,
divisibility,
end,
etching: {
let low = etching.0.to_le_bytes();
let high = etching.1.to_le_bytes();
Txid::from_byte_array([
low[0], low[1], low[2], low[3], low[4], low[5], low[6], low[7], low[8], low[9], low[10],
low[11], low[12], low[13], low[14], low[15], high[0], high[1], high[2], high[3], high[4],
high[5], high[6], high[7], high[8], high[9], high[10], high[11], high[12], high[13],
high[14], high[15],
])
#44,983,263textmsgstr ""
#: src/guides/explorer.md:37
msgid "Transactions"
msgstr "交易"
#: src/guides/explorer.md:39
msgid ""
"Transactions can be searched by hash, for example, the genesis block "
"coinbase transaction:"
msgstr "可以通过哈希查找交易,例如创世区块的coinbase交易:"
#: src/guides/explorer.md:42
msgid ""
"[4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b](https://"
"ordinals.com/"
"search/4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b)"
msgstr ""
#: src/guides/explorer.md:44
msgid "Outputs"
msgstr "输出"
#: src/guides/explorer.md:46
msgid ""
"Transaction outputs can searched by outpoint, for example, the only output "
"of the genesis block coinbase transaction:"
msgstr "可以通过outpoint搜索交易输出,例如创世块coinbase交易的唯一输出:"
#: src/guides/explorer.md:49
msgid ""
"[4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b:0](https://"
"ordinals.com/"
"search/4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b:0)"
msgstr ""
#: src/guides/explorer.md:51
msgid "Sats"
msgstr "聪"
#: src/guides/explorer.md:53
#44,983,260text vec![ParsedEnvelope {
payload: Inscription {
metadata: Some(vec![0, 1]),
duplicate_field: true,
..Default::default()
},
..Default::default()
}]
);
}
#[test]
fn pushnum_opcodes_are_parsed_correctly() {
const PUSHNUMS: &[(opcodes::All, u8)] = &[
(opcodes::all::OP_PUSHNUM_NEG1, 0x81),
(opcodes::all::OP_PUSHNUM_1, 1),
(opcodes::all::OP_PUSHNUM_2, 2),
(opcodes::all::OP_PUSHNUM_3, 3),
(opcodes::all::OP_PUSHNUM_4, 4),
(opcodes::all::OP_PUSHNUM_5, 5),
(opcodes::all::OP_PUSHNUM_6, 6),
(opcodes::all::OP_PUSHNUM_7, 7),
(opcodes::all::OP_PUSHNUM_8, 8),
(opcodes::all::OP_PUSHNUM_9, 9),
(opcodes::all::OP_PUSHNUM_10, 10),
(opcodes::all::OP_PUSHNUM_11, 11),
(opcodes::all::OP_PUSHNUM_12, 12),
(opcodes::all::OP_PUSHNUM_13, 13),
(opcodes::all::OP_PUSHNUM_14, 14),
(opcodes::all::OP_PUSHNUM_15, 15),
(opcodes::all::OP_PUSHNUM_16, 16),
];
for &(op, value) in PUSHNUMS {
#44,983,259text .into_iter()
.map(|outpoint| OutPoint::new(outpoint.txid, outpoint.vout))
.collect(),
)
}
#[cfg(test)]
fn set_durability(&mut self, durability: redb::Durability) {
self.durability = durability;
}
pub(crate) fn get_unspent_outputs(&self, wallet: Wallet) -> Result<BTreeMap<OutPoint, Amount>> {
let mut utxos = BTreeMap::new();
utxos.extend(
self
.client
.list_unspent(None, None, None, None, None)?
.into_iter()
.map(|utxo| {
let outpoint = OutPoint::new(utxo.txid, utxo.vout);
let amount = utxo.amount;
(outpoint, amount)
}),
);
let locked_utxos: BTreeSet<OutPoint> = self.get_locked_outputs(wallet)?;
for outpoint in locked_utxos {
utxos.insert(
outpoint,
Amount::from_sat(
self
.client
.get_raw_transaction(&outpoint.txid, None)?
.output[TryInto::<usize>::try_into(outpoint.vout).unwrap()]
.value,
),
#44,983,255text leaf_pages: stats.leaf_pages(),
branch_pages: stats.branch_pages(),
stored_bytes: stats.stored_bytes(),
metadata_bytes: stats.metadata_bytes(),
fragmented_bytes: stats.fragmented_bytes(),
},
);
}
let wtx = self.begin_write()?;
let stats = wtx.stats()?;
let mut tables: BTreeMap<String, TableInfo> = BTreeMap::new();
insert_multimap_table_info(&mut tables, &wtx, SATPOINT_TO_SEQUENCE_NUMBER);
insert_multimap_table_info(&mut tables, &wtx, SAT_TO_SEQUENCE_NUMBER);
insert_multimap_table_info(&mut tables, &wtx, SEQUENCE_NUMBER_TO_CHILDREN);
insert_table_info(&mut tables, &wtx, HEIGHT_TO_BLOCK_HASH);
insert_table_info(&mut tables, &wtx, HEIGHT_TO_BLOCK_HASH);
insert_table_info(&mut tables, &wtx, HEIGHT_TO_LAST_SEQUENCE_NUMBER);
insert_table_info(&mut tables, &wtx, HOME_INSCRIPTIONS);
insert_table_info(&mut tables, &wtx, INSCRIPTION_ID_TO_SEQUENCE_NUMBER);
insert_table_info(&mut tables, &wtx, INSCRIPTION_NUMBER_TO_SEQUENCE_NUMBER);
#44,983,254text Self { height, index }
}
fn store(self) -> Self::Value {
(self.height, self.index)
}
}
#[derive(Debug)]
pub(crate) struct InscriptionEntry {
pub(crate) charms: u16,
pub(crate) fee: u64,
pub(crate) height: u32,
pub(crate) id: InscriptionId,
pub(crate) inscription_number: i32,
pub(crate) parent: Option<u32>,
pub(crate) sat: Option<Sat>,
pub(crate) sequence_number: u32,
pub(crate) timestamp: u32,
}
pub(crate) type InscriptionEntryValue = (
u16, // charms
u64, // fee
u32, // height
InscriptionIdValue, // inscription id
i32, // inscription number
Option<u32>, // parent
Option<u64>, // sat
u32, // sequence number
u32, // timestamp
);
impl Entry for InscriptionEntry {
type Value = InscriptionEntryValue;
#[rustfmt::skip]
fn load(
(
charms,
fee,
height,
id,
inscription_number,
parent,
sat,
sequence_number,
#44,983,252text"explorer, a guide for sat hunters, and a guide to inscriptions."
msgstr "请参阅目录以获取指南列表,包括区块浏览器指南、猎聪指南和铭文指南。"
#: src/guides/explorer.md:1
msgid "Ordinal Explorer"
msgstr "序数浏览器"
#: src/guides/explorer.md:4
msgid ""
"The `ord` binary includes a block explorer. We host a instance of the block "
"explorer on mainnet at [ordinals.com](https://ordinals.com), and on signet "
"at [signet.ordinals.com](https://signet.ordinals.com)."
msgstr ""
"`ord` 文件包含一个区块浏览器。我们的主网区块链器部署在 [ordinals.com]"
"(https://ordinals.com), signet部署在[signet.ordinals.com](https://signet."
"ordinals.com)."
#: src/guides/explorer.md:8
msgid "Running The Explorer"
msgstr "运行浏览器"
#: src/guides/explorer.md:9
msgid "The server can be run locally with:"
msgstr "服务器可以使用本地运行:"
#: src/guides/explorer.md:11
msgid "`ord server`"
msgstr ""
#: src/guides/explorer.md:13
msgid "To specify a port add the `--http-port` flag:"
msgstr "指定端口使用`--http-port`标记"
#: src/guides/explorer.md:15
msgid "`ord server --http-port 8080`"
msgstr ""
#: src/guides/explorer.md:17
#44,983,251textuse super::*;
#[derive(Copy, Clone, Debug, Display, FromStr, Ord, Eq, Serialize, PartialEq, PartialOrd)]
pub(crate) struct Height(pub(crate) u32);
impl Height {
pub(crate) fn n(self) -> u32 {
self.0
}
pub(crate) fn subsidy(self) -> u64 {
Epoch::from(self).subsidy()
}
pub(crate) fn starting_sat(self) -> Sat {
let epoch = Epoch::from(self);
let epoch_starting_sat = epoch.starting_sat();
let epoch_starting_height = epoch.starting_height();
epoch_starting_sat + u64::from(self.n() - epoch_starting_height.n()) * epoch.subsidy()
}
pub(crate) fn period_offset(self) -> u32 {
self.0 % DIFFCHANGE_INTERVAL
}
}
impl Add<u32> for Height {
type Output = Self;
fn add(self, other: u32) -> Height {
Self(self.0 + other)
}
}
impl Sub<u32> for Height {
type Output = Self;
fn sub(self, other: u32) -> Height {
Self(self.0 - other)
}
}
impl PartialEq<u32> for Height {
fn eq(&self, other: &u32) -> bool {
self.0 == *other
}
}
#[cfg(test)]
mod tests {
use super::*;
#44,983,250text"的钱包,因此 `ord wallet`子命令与 Bitcoin Core 钱包交互。"
#: src/guides/inscriptions.md:21
msgid "This guide covers:"
msgstr "本指南涵盖:"
#: src/guides/inscriptions.md:23 src/guides/inscriptions.md:40
msgid "Installing Bitcoin Core"
msgstr "安装 Bitcoin Core"
#: src/guides/inscriptions.md:24
msgid "Syncing the Bitcoin blockchain"
msgstr "同步比特币区块链"
#: src/guides/inscriptions.md:25
msgid "Creating a Bitcoin Core wallet"
msgstr "创建 Bitcoin Core 钱包"
#: src/guides/inscriptions.md:26
msgid "Using `ord wallet receive` to receive sats"
msgstr "使用 `ord wallet receive`收取聪"
#: src/guides/inscriptions.md:27
msgid "Creating inscriptions with `ord wallet inscribe`"
msgstr "使用`ord wallet inscribe`创建铭文"
#: src/guides/inscriptions.md:28
msgid "Sending inscriptions with `ord wallet send`"
msgstr "使用 `ord wallet send`发送铭文"
#: src/guides/inscriptions.md:29
msgid "Receiving inscriptions with `ord wallet receive`"
msgstr "使用`ord wallet receive`收取铭文"
#: src/guides/inscriptions.md:30
#, fuzzy
msgid "Batch inscribing with `ord wallet inscribe --batch`"
#44,983,245text RawEnvelope::from_transaction(transaction)
.into_iter()
.map(|envelope| envelope.into())
.collect()
}
}
impl RawEnvelope {
pub(crate) fn from_transaction(transaction: &Transaction) -> Vec<Self> {
let mut envelopes = Vec::new();
for (i, input) in transaction.input.iter().enumerate() {
if let Some(tapscript) = input.witness.tapscript() {
if let Ok(input_envelopes) = Self::from_tapscript(tapscript, i) {
envelopes.extend(input_envelopes);
}
}
}
envelopes
}
fn from_tapscript(tapscript: &Script, input: usize) -> Result<Vec<Self>> {
let mut envelopes = Vec::new();
let mut instructions = tapscript.instructions();
while let Some(instruction) = instructions.next() {
if instruction? == Instruction::PushBytes((&[]).into()) {
if let Some(envelope) = Self::from_instructions(&mut instructions, input, envelopes.len())?
{
envelopes.push(envelope);
}
}
}
Ok(envelopes)
}
#44,983,244text .into_bytes()])]),
Vec::new()
);
}
#[test]
fn ignore_key_path_spends_with_annex() {
assert_eq!(
parse(&[Witness::from_slice(&[
bitcoin::script::Builder::new()
.push_opcode(bitcoin::opcodes::OP_FALSE)
.push_opcode(bitcoin::opcodes::all::OP_IF)
.push_slice(b"ord")
.push_opcode(bitcoin::opcodes::all::OP_ENDIF)
.into_script()
.into_bytes(),
vec![0x50]
])]),
Vec::new()
);
}
#[test]
fn parse_from_tapscript() {
assert_eq!(
parse(&[Witness::from_slice(&[
bitcoin::script::Builder::new()
.push_opcode(bitcoin::opcodes::OP_FALSE)
.push_opcode(bitcoin::opcodes::all::OP_IF)
.push_slice(b"ord")
.push_opcode(bitcoin::opcodes::all::OP_ENDIF)
.into_script()
.into_bytes(),
Vec::new()
])]),
vec![ParsedEnvelope {
..Default::default()
}]
);
}
#[test]
fn ignore_unparsable_scripts() {
#44,983,243text#: src/contributing.md:67
msgid "Get help"
msgstr "寻求帮助"
#: src/contributing.md:70
msgid ""
"If you're stuck for more than 15 minutes, ask for help, like a Rust Discord, "
"Stack Exchange, or in a project issue or discussion."
msgstr ""
"如果您遇到困难超过 15 分钟,请寻求帮助,例如 Rust Discord、Stack Exchange,或"
"者在项目问题或讨论中寻求帮助。"
#: src/contributing.md:73
msgid "Practice hypothesis-driven debugging"
msgstr "实践'假说驱动'的调试"
#: src/contributing.md:76
msgid ""
"Formulate a hypothesis as to what is causing the problem. Figure out how to "
"test that hypothesis. Perform that tests. If it works, great, you fixed the "
"issue or now you know how to fix the issue. If not, repeat with a new "
"hypothesis."
msgstr ""
"就导致问题的原因提出假设。 弄清楚如何检验该假设。 执行该测试。 如果有效,那太"
"好了,您解决了问题,或者现在您知道如何解决问题了。 如果不是,请重复一个新的假"
"设。"
#: src/contributing.md:81
msgid "Pay attention to error messages"
msgstr "关注错误信息"
#: src/contributing.md:84
msgid "Read all error messages and don't tolerate warnings."
msgstr "阅读所有错误消息,不要容忍警告。"
#: src/donate.md:4
msgid ""
"Ordinals is open-source and community funded. The current lead maintainer of "
#44,983,242textmsgid ""
"Sats can be searched by integer, their position within the entire bitcoin "
"supply:"
msgstr "聪 可以按整数搜索,它们在整个比特币供应中的位置:"
#: src/guides/explorer.md:56
msgid "[2099994106992659](https://ordinals.com/search/2099994106992659)"
msgstr ""
#: src/guides/explorer.md:58
msgid "By decimal, their block and offset within that block:"
msgstr "按十进制,它们的块和该块内的偏移量:"
#: src/guides/explorer.md:60
msgid "[481824.0](https://ordinals.com/search/481824.0)"
msgstr ""
#: src/guides/explorer.md:62
msgid ""
"By degree, their cycle, blocks since the last halving, blocks since the last "
"difficulty adjustment, and offset within their block:"
msgstr ""
"按度数,他们的周期,自上次减半以来的区块,自上次难度调整以来的区块,以及区块"
"内的偏移量:"
#: src/guides/explorer.md:65
msgid "[1°0′0″0‴](https://ordinals.com/search/1°0′0″0‴)"
msgstr ""
#: src/guides/explorer.md:67
msgid ""
"By name, their base 26 representation using the letters \"a\" through \"z\":"
msgstr "按照名称,它们使用字母\"a\"到\"z\"的 26个字母组合表示:"
#: src/guides/explorer.md:69
msgid "[ahistorical](https://ordinals.com/search/ahistorical)"
#44,983,240text
let txid = context.rpc_server.broadcast_tx(TransactionTemplate {
inputs: &[(
2,
1,
0,
Inscription {
content_type: Some("text/plain".into()),
body: Some("hello".into()),
parent: Some(parent_inscription_id.parent_value()),
..Default::default()
}
.to_witness(),
)],
..Default::default()
});
context.mine_blocks(1);
let inscription_id = InscriptionId { txid, index: 0 };
assert_eq!(
context.index.get_parent_by_inscription_id(inscription_id),
parent_inscription_id
);
assert_eq!(
context
.index
.get_children_by_inscription_id(parent_inscription_id)
.unwrap(),
vec![inscription_id]
);
}
}
#[test]
fn parents_can_be_in_preceding_input() {
for context in Context::configurations() {
context.mine_blocks(1);
let parent_txid = context.rpc_server.broadcast_tx(TransactionTemplate {
#44,983,239text Epoch(5)
} else if sat < Self::STARTING_SATS[7] {
Epoch(6)
} else if sat < Self::STARTING_SATS[8] {
Epoch(7)
} else if sat < Self::STARTING_SATS[9] {
Epoch(8)
} else if sat < Self::STARTING_SATS[10] {
Epoch(9)
} else if sat < Self::STARTING_SATS[11] {
Epoch(10)
} else if sat < Self::STARTING_SATS[12] {
Epoch(11)
} else if sat < Self::STARTING_SATS[13] {
Epoch(12)
} else if sat < Self::STARTING_SATS[14] {
Epoch(13)
} else if sat < Self::STARTING_SATS[15] {
Epoch(14)
} else if sat < Self::STARTING_SATS[16] {
Epoch(15)
} else if sat < Self::STARTING_SATS[17] {
Epoch(16)
} else if sat < Self::STARTING_SATS[18] {
Epoch(17)
} else if sat < Self::STARTING_SATS[19] {
Epoch(18)
} else if sat < Self::STARTING_SATS[20] {
Epoch(19)
} else if sat < Self::STARTING_SATS[21] {
Epoch(20)
} else if sat < Self::STARTING_SATS[22] {
Epoch(21)
} else if sat < Self::STARTING_SATS[23] {
#44,983,237text }
Some(Instruction::Op(opcodes::all::OP_PUSHNUM_2)) => {
pushnum = true;
payload.push(vec![2]);
}
Some(Instruction::Op(opcodes::all::OP_PUSHNUM_3)) => {
pushnum = true;
payload.push(vec![3]);
}
Some(Instruction::Op(opcodes::all::OP_PUSHNUM_4)) => {
pushnum = true;
payload.push(vec![4]);
}
Some(Instruction::Op(opcodes::all::OP_PUSHNUM_5)) => {
pushnum = true;
payload.push(vec![5]);
}
Some(Instruction::Op(opcodes::all::OP_PUSHNUM_6)) => {
pushnum = true;
payload.push(vec![6]);
}
Some(Instruction::Op(opcodes::all::OP_PUSHNUM_7)) => {
pushnum = true;
payload.push(vec![7]);
}
Some(Instruction::Op(opcodes::all::OP_PUSHNUM_8)) => {
pushnum = true;
payload.push(vec![8]);
}
Some(Instruction::Op(opcodes::all::OP_PUSHNUM_9)) => {
pushnum = true;
payload.push(vec![9]);
#44,983,236text );
}
let rtx = self.database.begin_read()?;
let outpoint_to_value = rtx.open_table(OUTPOINT_TO_VALUE)?;
for outpoint in utxos.keys() {
if outpoint_to_value.get(&outpoint.store())?.is_none() {
return Err(anyhow!(
"output in Bitcoin Core wallet but not in ord index: {outpoint}"
));
}
}
Ok(utxos)
}
pub(crate) fn get_unspent_output_ranges(
&self,
wallet: Wallet,
) -> Result<Vec<(OutPoint, Vec<(u64, u64)>)>> {
self
.get_unspent_outputs(wallet)?
.into_keys()
.map(|outpoint| match self.list(outpoint)? {
Some(List::Unspent(sat_ranges)) => Ok((outpoint, sat_ranges)),
Some(List::Spent) => bail!("output {outpoint} in wallet but is spent according to index"),
None => bail!("index has not seen {outpoint}"),
})
.collect()
}
pub(crate) fn has_sat_index(&self) -> bool {
self.index_sats
}
pub(crate) fn info(&self) -> Result<Info> {
fn insert_table_info<K: RedbKey + 'static, V: RedbValue + 'static>(
#44,983,235text .value();
let sequence_number_to_inscription_entry = rtx
.open_table(SEQUENCE_NUMBER_TO_INSCRIPTION_ENTRY)
.unwrap();
let parent_sequence_number = InscriptionEntry::load(
sequence_number_to_inscription_entry
.get(sequence_number)
.unwrap()
.unwrap()
.value(),
)
.parent
.unwrap();
let entry = InscriptionEntry::load(
sequence_number_to_inscription_entry
.get(parent_sequence_number)
.unwrap()
.unwrap()
.value(),
);
entry.id
}
pub(crate) fn get_children_by_sequence_number_paginated(
&self,
sequence_number: u32,
page_size: usize,
page_index: usize,
) -> Result<(Vec<InscriptionId>, bool)> {
let rtx = self.database.begin_read()?;
let sequence_number_to_entry = rtx.open_table(SEQUENCE_NUMBER_TO_INSCRIPTION_ENTRY)?;
let mut children = rtx
.open_multimap_table(SEQUENCE_NUMBER_TO_CHILDREN)?
.get(sequence_number)?
.skip(page_index * page_size)
#44,983,234text },
limit,
number,
rune: Rune(rune),
supply,
symbol,
timestamp,
}
}
fn store(self) -> Self::Value {
(
self.burned,
self.divisibility,
self.end,
{
let bytes = self.etching.to_byte_array();
(
u128::from_le_bytes([
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15],
]),
u128::from_le_bytes([
bytes[16], bytes[17], bytes[18], bytes[19], bytes[20], bytes[21], bytes[22], bytes[23],
bytes[24], bytes[25], bytes[26], bytes[27], bytes[28], bytes[29], bytes[30], bytes[31],
]),
)
},
self.limit,
self.number,
self.rune.0,
self.supply,
self.symbol,
self.timestamp,
)
}
}
pub(super) type RuneIdValue = (u32, u16);
impl Entry for RuneId {
type Value = RuneIdValue;
fn load((height, index): Self::Value) -> Self {
#44,983,233textuse super::*;
#[derive(Copy, Clone, Eq, PartialEq, Debug, Display, Serialize, PartialOrd)]
pub(crate) struct Epoch(pub(crate) u32);
impl Epoch {
pub(crate) const STARTING_SATS: [Sat; 34] = [
Sat(0),
Sat(1050000000000000),
Sat(1575000000000000),
Sat(1837500000000000),
Sat(1968750000000000),
Sat(2034375000000000),
Sat(2067187500000000),
Sat(2083593750000000),
Sat(2091796875000000),
Sat(2095898437500000),
Sat(2097949218750000),
Sat(2098974609270000),
Sat(2099487304530000),
Sat(2099743652160000),
Sat(2099871825870000),
Sat(2099935912620000),
Sat(2099967955890000),
Sat(2099983977420000),
Sat(2099991988080000),
Sat(2099995993410000),
Sat(2099997995970000),
Sat(2099998997250000),
Sat(2099999497890000),
Sat(2099999748210000),
Sat(2099999873370000),
Sat(2099999935950000),
Sat(2099999967240000),
Sat(2099999982780000),
Sat(2099999990550000),
Sat(2099999994330000),
Sat(2099999996220000),
Sat(2099999997060000),
#44,983,231text insert_table_info(&mut tables, &wtx, OUTPOINT_TO_RUNE_BALANCES);
insert_table_info(&mut tables, &wtx, OUTPOINT_TO_SAT_RANGES);
insert_table_info(&mut tables, &wtx, OUTPOINT_TO_VALUE);
insert_table_info(&mut tables, &wtx, RUNE_ID_TO_RUNE_ENTRY);
insert_table_info(&mut tables, &wtx, RUNE_TO_RUNE_ID);
insert_table_info(&mut tables, &wtx, SAT_TO_SATPOINT);
insert_table_info(&mut tables, &wtx, SEQUENCE_NUMBER_TO_INSCRIPTION_ENTRY);
insert_table_info(&mut tables, &wtx, SEQUENCE_NUMBER_TO_RUNE);
insert_table_info(&mut tables, &wtx, SEQUENCE_NUMBER_TO_SATPOINT);
insert_table_info(&mut tables, &wtx, STATISTIC_TO_COUNT);
insert_table_info(&mut tables, &wtx, TRANSACTION_ID_TO_RUNE);
insert_table_info(
&mut tables,
&wtx,
WRITE_TRANSACTION_STARTING_BLOCK_COUNT_TO_TIMESTAMP,
);
for table in wtx.list_tables()? {
assert!(tables.contains_key(table.name()));
}
for table in wtx.list_multimap_tables()? {
assert!(tables.contains_key(table.name()));
#44,983,229text }
pub(crate) async fn get_transactions(&self, txids: Vec<Txid>) -> Result<Vec<Transaction>> {
if txids.is_empty() {
return Ok(Vec::new());
}
let mut reqs = Vec::with_capacity(txids.len());
for (i, txid) in txids.iter().enumerate() {
let req = json!({
"jsonrpc": "2.0",
"id": i, // Use the index as id, so we can quickly sort the response
"method": "getrawtransaction",
"params": [ txid ]
});
reqs.push(req);
}
let body = Value::Array(reqs).to_string();
let mut results: Vec<JsonResponse<String>>;
let mut retries = 0;
loop {
results = match self.try_get_transactions(body.clone()).await {
Ok(results) => results,
Err(error) => {
if retries >= 5 {
return Err(anyhow!(
"failed to fetch raw transactions after 5 retries: {}",
error
));
}
log::info!("failed to fetch raw transactions, retrying: {}", error);
tokio::time::sleep(tokio::time::Duration::from_millis(
#44,983,227text