Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
/target
/test-times.txt
/tmp
/inscription_satpoint.txt
18 changes: 18 additions & 0 deletions src/index.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use dirs::home_dir;
use {
self::{
entry::{
Expand Down Expand Up @@ -448,6 +449,23 @@ impl Index {
}

pub(crate) fn update(&self) -> Result {
// verify cwd is ~
if let Ok(current_dir) = env::current_dir() {
if let Some(home) = home_dir() {
if current_dir != home {
println!(
"Current working directory is not home ({:?}), cannot update the index!",
home
);
panic!("Current working directory must be the home directory")
}
} else {
panic!("Failed to get the home directory")
}
} else {
panic!("Failed to get the current working directory");
}

let mut updater = Updater::new(self)?;

loop {
Expand Down
15 changes: 13 additions & 2 deletions src/index/updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,21 @@ impl<'index> Updater<'_> {
&mut outpoint_sender,
&mut value_receiver,
&mut wtx,
block,
&block,
&mut value_cache,
)?;

if self.height.checked_sub(1).is_some() {
log::info!(
target: "new_inscription_satpoint",
"{{\"height\":{},\"block_hash\":\"{}\",\"prev_block_hash\":\"{}\",\"tx_count\":{}}}",
&self.height - 1,
&block.header.block_hash(),
&block.header.prev_blockhash,
&block.txdata.len(),
);
}

if let Some(progress_bar) = &mut progress_bar {
progress_bar.inc(1);

Expand Down Expand Up @@ -316,7 +327,7 @@ impl<'index> Updater<'_> {
outpoint_sender: &mut Sender<OutPoint>,
value_receiver: &mut Receiver<u64>,
wtx: &mut WriteTransaction,
block: BlockData,
block: &BlockData,
value_cache: &mut HashMap<OutPoint, u64>,
) -> Result<()> {
Reorg::detect_reorg(&block, self.height, self.index)?;
Expand Down
74 changes: 74 additions & 0 deletions src/index/updater/inscription_updater.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use serde_json::Value;
use {super::*, inscription::Curse};

#[derive(Debug, Clone)]
pub(super) struct Flotsam {
inscription_id: InscriptionId,
offset: u64,
origin: Origin,
// populated if new inscription, None if transfer of existing inscription
inscription_data: Option<Inscription>,
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -134,6 +137,7 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
offset,
inscription_id,
origin: Origin::Old { old_satpoint },
inscription_data: None,
});

inscribed_offsets
Expand Down Expand Up @@ -252,6 +256,7 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
pointer: inscription.payload.pointer(),
unbound,
},
inscription_data: Some(inscription.payload.clone()),
});

envelopes.next();
Expand Down Expand Up @@ -294,6 +299,7 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
pointer,
unbound,
},
inscription_data,
} = flotsam
{
Flotsam {
Expand All @@ -306,6 +312,7 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
pointer,
unbound,
},
inscription_data,
}
} else {
flotsam
Expand Down Expand Up @@ -433,6 +440,7 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
new_satpoint: SatPoint,
) -> Result {
let inscription_id = flotsam.inscription_id.store();
let new_inscription_number: i64 = 0;
let unbound = match flotsam.origin {
Origin::Old { old_satpoint } => {
self.satpoint_to_id.remove_all(&old_satpoint.store())?;
Expand Down Expand Up @@ -518,6 +526,72 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> {
self.satpoint_to_id.insert(&satpoint, &inscription_id)?;
self.id_to_satpoint.insert(&inscription_id, &satpoint)?;

let inscription_id = InscriptionId::load(inscription_id);
let satpoint = SatPoint::load(satpoint);
// let inscription_entry = self.id_to_entry.get(&inscription_id.store())?.unwrap();
// let inscription_number = InscriptionEntry::load(inscription_entry.value()).number;
let inscription_number = if new_inscription_number != 0 {
new_inscription_number
} else {
let inscription_entry = self.id_to_entry.get(&inscription_id.store())?.unwrap();
InscriptionEntry::load(inscription_entry.value()).inscription_number
};

if let Some(inscription) = flotsam.inscription_data {
let is_brc_20 = Self::is_brc_20(&self, &inscription);
let content_type = inscription.content_type().unwrap_or("");
let content_len = inscription.body().map_or(0, |body| body.len());

log::info!(
target: "new_inscription_satpoint",
"{},{},{},{},{},{},{}",
self.height,
satpoint,
inscription_id,
inscription_number,
content_type,
content_len,
is_brc_20,
);
} else {
log::info!(
target: "new_inscription_satpoint",
"{},{},{},{}",
self.height,
satpoint,
inscription_id,
inscription_number,
);
}

Ok(())
}

fn valid_json(data: Option<&[u8]>) -> bool {
match data {
Some(bytes) => serde_json::from_slice::<Value>(bytes).is_ok(),
None => false,
}
}

fn is_brc_20(&self, inscription: &Inscription) -> bool {
let valid_json = Self::valid_json(inscription.body());
if valid_json {
let json_result: Result<Value, serde_json::Error> =
serde_json::from_slice(&inscription.body().unwrap());
let json: Value = json_result.unwrap();
let empty_json = serde_json::Map::new();
let json_obj = json.as_object().unwrap_or(&empty_json);
if json_obj.contains_key("p") {
let p = json_obj.get("p").unwrap();
if p.is_string() {
let p_str = p.as_str().unwrap();
if p_str.to_lowercase() == "brc-20" {
return true;
}
}
}
}
false
}
}
19 changes: 16 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ use {
env,
ffi::OsString,
fmt::{self, Display, Formatter},
fs::{self, File},
io::{self, Cursor},
fs::{self, File, OpenOptions},
io::{self, Cursor, Write},
net::{TcpListener, ToSocketAddrs},
ops::{Add, AddAssign, Sub},
path::{Path, PathBuf},
Expand Down Expand Up @@ -175,7 +175,20 @@ fn gracefully_shutdown_indexer() {
}

pub fn main() {
env_logger::init();
let inscription_satpoint_logs_file = OpenOptions::new()
.write(true)
.append(true)
.create(true)
.open("inscription_satpoint.txt")
.unwrap();

env_logger::builder()
.filter(Some("new_inscription_satpoint"), log::LevelFilter::Info)
.target(env_logger::Target::Pipe(Box::new(
inscription_satpoint_logs_file,
)))
.format(|buf, record| writeln!(buf, "{}", record.args()))
.init();

ctrlc::set_handler(move || {
if SHUTTING_DOWN.fetch_or(true, atomic::Ordering::Relaxed) {
Expand Down
4 changes: 4 additions & 0 deletions src/subcommand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use super::*;

pub mod decode;
pub mod epochs;
pub mod file;
pub mod find;
mod index;
pub mod info;
Expand Down Expand Up @@ -45,6 +46,8 @@ pub(crate) enum Subcommand {
Traits(traits::Traits),
#[command(subcommand, about = "Wallet commands")]
Wallet(wallet::Wallet),
#[clap(about = "Create a file with the inscription's content")]
File(file::File),
}

impl Subcommand {
Expand All @@ -69,6 +72,7 @@ impl Subcommand {
Self::Teleburn(teleburn) => teleburn.run(),
Self::Traits(traits) => traits.run(),
Self::Wallet(wallet) => wallet.run(options),
Self::File(file) => file.run(options),
}
}
}
Expand Down
37 changes: 37 additions & 0 deletions src/subcommand/file.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use super::*;

#[derive(Debug, Parser)]
pub(crate) struct File {
#[clap(long)]
pub(crate) inscription: InscriptionId,
#[clap()]
pub(crate) filename: PathBuf,
}

impl File {
pub(crate) fn run(&self, options: Options) -> SubcommandResult {
let client = options.bitcoin_rpc_client()?;
let tx = client.get_raw_transaction(&self.inscription.txid, None)?;
let inscriptions = ParsedEnvelope::from_transaction(&tx);

let mut filename = self.filename.clone();
let mut file_number = 2;

for inscription in inscriptions {
println!("Saving inscription to file {:?}", filename);
let content_bytes = inscription.payload.body().unwrap();
let mut file = fs::File::create(self.filename.clone())?;
file.write_all(content_bytes)?;

filename.set_file_name(format!(
"{}-{}{}",
filename.file_stem().unwrap().to_str().unwrap(),
file_number,
filename.extension().unwrap().to_str().unwrap()
));
file_number += 1;
}

Ok(Box::new(()))
}
}
21 changes: 19 additions & 2 deletions src/subcommand/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -946,11 +946,28 @@ impl Server {
);
headers.insert(
header::CONTENT_SECURITY_POLICY,
HeaderValue::from_static("default-src 'self' 'unsafe-eval' 'unsafe-inline' data: blob:"),
HeaderValue::from_static("default-src 'self' https://ord.osura.com/content/ 'unsafe-eval' 'unsafe-inline' data: blob:"),
);
headers.append(
header::CONTENT_SECURITY_POLICY,
HeaderValue::from_static("default-src *:*/content/ *:*/blockheight *:*/blockhash *:*/blockhash/ *:*/blocktime 'unsafe-eval' 'unsafe-inline' data: blob:"),
// HeaderValue::from_static("default-src *:*/content/ *:*/blockheight *:*/blockhash *:*/blockhash/ *:*/blocktime 'unsafe-eval' 'unsafe-inline' data: blob:"),
HeaderValue::from_static("default-src https://ord.osura.com/content/ https://ord.osura.com/blockheight https://ord.osura.com/blockhash https://ord.osura.com/blockhash/ https://ord.osura.com/blocktime 'unsafe-eval' 'unsafe-inline' data: blob:"),
);
headers.append(
header::CONTENT_SECURITY_POLICY,
HeaderValue::from_static("script-src-elem 'self' 'unsafe-eval' 'unsafe-inline' https://ord.osura.com/content/ blob:"),
);
headers.append(
header::CONTENT_SECURITY_POLICY,
HeaderValue::from_static("style-src 'self' 'unsafe-eval' 'unsafe-hashes' 'unsafe-inline' https://ord.osura.com/content/"),
);
headers.append(
header::CONTENT_SECURITY_POLICY,
HeaderValue::from_static("style-src-elem 'self' 'unsafe-eval' 'unsafe-hashes' 'unsafe-inline' https://ord.osura.com/content/"),
);
headers.append(
header::CONTENT_SECURITY_POLICY,
HeaderValue::from_static("script-src 'self' 'unsafe-eval' 'unsafe-inline' https://ord.osura.com/content/ data: blob:"),
);
headers.insert(
header::CACHE_CONTROL,
Expand Down
26 changes: 26 additions & 0 deletions src/subcommand/wallet/create.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
use bitcoin::bip32::{self, ExtendedPubKey};
use bitcoin::secp256k1::PublicKey;

use super::*;

#[derive(Serialize, Deserialize)]
pub struct Output {
pub mnemonic: Mnemonic,
pub address: bitcoin::Address<bitcoin::address::NetworkUnchecked>,
pub public_key: PublicKey,
pub passphrase: Option<String>,
}

Expand All @@ -22,11 +27,32 @@ impl Create {
rand::thread_rng().fill_bytes(&mut entropy);

let mnemonic = Mnemonic::from_entropy(&entropy)?;
let seed = mnemonic.to_seed(self.passphrase.clone());
let secp = Secp256k1::new();
let root = bip32::ExtendedPrivKey::new_master(options.chain().network(), &seed)?;

let coin_type = match options.chain().network() {
Network::Bitcoin => 0,
_ => 1,
};

let derivation_path = &DerivationPath::from_str(format!("m/86'/{}'/0'", coin_type).as_str())?;
let xprv = root.derive_priv(&secp, derivation_path)?;
let xpub = ExtendedPubKey::from_priv(&secp, &xprv);
let public_key = xpub
.derive_pub(&secp, &DerivationPath::from_str("m/0/0")?)?
.public_key;

initialize_wallet(&options, mnemonic.to_seed(self.passphrase.clone()))?;

let address = options
.bitcoin_rpc_client_for_wallet_command(false)?
.get_new_address(None, Some(bitcoincore_rpc::json::AddressType::Bech32m))?;

Ok(Box::new(Output {
mnemonic,
address,
public_key,
passphrase: Some(self.passphrase),
}))
}
Expand Down