From f76930a34252f8ad84265a280621865d29639fe9 Mon Sep 17 00:00:00 2001 From: raph Date: Wed, 3 Jan 2024 23:02:58 +0100 Subject: [PATCH 01/18] Restart sshd in deploy script (#2952) --- deploy/setup | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/deploy/setup b/deploy/setup index 36d384e54e..86dfe216c6 100755 --- a/deploy/setup +++ b/deploy/setup @@ -31,8 +31,6 @@ esac touch ~/.hushlogin -sed -i -E 's/#?PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config - mkdir -p \ /etc/systemd/system/bitcoind.service.d \ /etc/systemd/system/ord.service.d @@ -62,6 +60,10 @@ ufw allow http ufw allow https ufw allow ssh +sed -i -E 's/#?PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config +sshd -t +systemctl restart sshd + case $CHAIN in main) ufw allow 8333 From 6857bfb8770c68b11c6105114f02d80f8c6cc413 Mon Sep 17 00:00:00 2001 From: raph Date: Wed, 3 Jan 2024 23:22:15 +0100 Subject: [PATCH 02/18] Add chain to status page (#2953) --- src/index.rs | 1 + src/subcommand/server.rs | 2 ++ src/templates/status.rs | 1 + templates/status.html | 2 ++ 4 files changed, 6 insertions(+) diff --git a/src/index.rs b/src/index.rs index 20c7bd0740..5f920eb085 100644 --- a/src/index.rs +++ b/src/index.rs @@ -431,6 +431,7 @@ impl Index { Ok(StatusHtml { blessed_inscriptions, + chain: self.options.chain(), cursed_inscriptions, height, inscriptions: blessed_inscriptions + cursed_inscriptions, diff --git a/src/subcommand/server.rs b/src/subcommand/server.rs index 3f54bde538..3c3b1ec499 100644 --- a/src/subcommand/server.rs +++ b/src/subcommand/server.rs @@ -2552,6 +2552,8 @@ mod tests { StatusCode::OK, ".*

Status

+
chain
+
mainnet
height
0
inscriptions
diff --git a/src/templates/status.rs b/src/templates/status.rs index a90b2047a3..540e4a418f 100644 --- a/src/templates/status.rs +++ b/src/templates/status.rs @@ -4,6 +4,7 @@ use super::*; pub(crate) struct StatusHtml { pub(crate) blessed_inscriptions: u64, pub(crate) cursed_inscriptions: u64, + pub(crate) chain: Chain, pub(crate) height: Option, pub(crate) inscriptions: u64, pub(crate) lost_sats: u64, diff --git a/templates/status.html b/templates/status.html index 7f9569b9be..944a2fc286 100644 --- a/templates/status.html +++ b/templates/status.html @@ -1,5 +1,7 @@

Status

+
chain
+
{{ self.chain }}
%% if let Some(height) = self.height {
height
{{ height }}
From 354e65c61fa255bfc804b55fd8a7322b13b7def7 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Wed, 3 Jan 2024 14:30:00 -0800 Subject: [PATCH 03/18] Remove quotes around key to allow shell expansion (#2951) --- justfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/justfile b/justfile index 71da16a57d..4948b29887 100644 --- a/justfile +++ b/justfile @@ -53,7 +53,7 @@ install-personal-key key='~/.ssh/id_ed25519.pub': #!/usr/bin/env bash set -euxo pipefail for server in alpha balance regtest signet stability testnet; do - ssh-copy-id -i '{{ key }}' root@$server.ordinals.net + ssh-copy-id -i {{ key }} root@$server.ordinals.net done log unit='ord' domain='alpha.ordinals.net': From 09e1e19debae8003d7276563b1996f9fb1f16a37 Mon Sep 17 00:00:00 2001 From: raph Date: Thu, 4 Jan 2024 00:32:33 +0100 Subject: [PATCH 04/18] Add JSON endpoint for status (#2955) --- src/lib.rs | 4 ++-- src/subcommand/server.rs | 11 +++++++--- src/templates.rs | 2 +- src/templates/status.rs | 32 ++++++++++++++-------------- tests/json_api.rs | 46 ++++++++++++++++++++++++++++++++++++++++ tests/lib.rs | 4 +++- 6 files changed, 76 insertions(+), 23 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 3805416a4e..55b2379d9d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,7 +48,6 @@ use { Witness, }, bitcoincore_rpc::{Client, RpcApi}, - chain::Chain, chrono::{DateTime, TimeZone, Utc}, ciborium::Value, clap::{ArgGroup, Parser}, @@ -84,6 +83,7 @@ use { }; pub use self::{ + chain::Chain, fee_rate::FeeRate, index::Index, inscriptions::{Envelope, Inscription, InscriptionId}, @@ -115,7 +115,7 @@ macro_rules! tprintln { mod arguments; mod blocktime; -mod chain; +pub mod chain; mod config; mod decimal; mod decimal_sat; diff --git a/src/subcommand/server.rs b/src/subcommand/server.rs index 3c3b1ec499..d767ba53d6 100644 --- a/src/subcommand/server.rs +++ b/src/subcommand/server.rs @@ -15,7 +15,7 @@ use { PreviewAudioHtml, PreviewCodeHtml, PreviewFontHtml, PreviewImageHtml, PreviewMarkdownHtml, PreviewModelHtml, PreviewPdfHtml, PreviewTextHtml, PreviewUnknownHtml, PreviewVideoHtml, RangeHtml, RareTxt, RuneHtml, RunesHtml, SatHtml, SatInscriptionJson, SatInscriptionsJson, - SatJson, StatusHtml, TransactionHtml, + SatJson, TransactionHtml, }, }, axum::{ @@ -769,8 +769,13 @@ impl Server { async fn status( Extension(server_config): Extension>, Extension(index): Extension>, - ) -> ServerResult> { - Ok(index.status()?.page(server_config)) + AcceptJson(accept_json): AcceptJson, + ) -> ServerResult { + Ok(if accept_json { + Json(index.status()?).into_response() + } else { + index.status()?.page(server_config).into_response() + }) } async fn search_by_query( diff --git a/src/templates.rs b/src/templates.rs index aae0b5f953..4a53f94836 100644 --- a/src/templates.rs +++ b/src/templates.rs @@ -47,7 +47,7 @@ mod rare; mod rune; mod runes; pub mod sat; -mod status; +pub mod status; mod transaction; #[derive(Boilerplate)] diff --git a/src/templates/status.rs b/src/templates/status.rs index 540e4a418f..2181cf2261 100644 --- a/src/templates/status.rs +++ b/src/templates/status.rs @@ -1,21 +1,21 @@ use super::*; -#[derive(Boilerplate)] -pub(crate) struct StatusHtml { - pub(crate) blessed_inscriptions: u64, - pub(crate) cursed_inscriptions: u64, - pub(crate) chain: Chain, - pub(crate) height: Option, - pub(crate) inscriptions: u64, - pub(crate) lost_sats: u64, - pub(crate) minimum_rune_for_next_block: Rune, - pub(crate) rune_index: bool, - pub(crate) runes: u64, - pub(crate) sat_index: bool, - pub(crate) started: DateTime, - pub(crate) transaction_index: bool, - pub(crate) unrecoverably_reorged: bool, - pub(crate) uptime: Duration, +#[derive(Boilerplate, Debug, PartialEq, Serialize, Deserialize)] +pub struct StatusHtml { + pub blessed_inscriptions: u64, + pub cursed_inscriptions: u64, + pub chain: Chain, + pub height: Option, + pub inscriptions: u64, + pub lost_sats: u64, + pub minimum_rune_for_next_block: Rune, + pub rune_index: bool, + pub runes: u64, + pub sat_index: bool, + pub started: DateTime, + pub transaction_index: bool, + pub unrecoverably_reorged: bool, + pub uptime: Duration, } impl PageContent for StatusHtml { diff --git a/tests/json_api.rs b/tests/json_api.rs index ab3dfb8e8e..2be51014f4 100644 --- a/tests/json_api.rs +++ b/tests/json_api.rs @@ -365,3 +365,49 @@ fn get_block() { } ); } + +#[test] +fn get_status() { + let rpc_server = test_bitcoincore_rpc::spawn(); + + create_wallet(&rpc_server); + + inscribe(&rpc_server); + + let response = + TestServer::spawn_with_server_args(&rpc_server, &["--index-sats"], &["--enable-json-api"]) + .json_request("/status"); + + assert_eq!(response.status(), StatusCode::OK); + + let mut status_json: StatusHtml = serde_json::from_str(&response.text().unwrap()).unwrap(); + + let dummy_started = "2012-12-12 12:12:12+00:00" + .parse::>() + .unwrap(); + + let dummy_uptime = Duration::from_secs(1); + + status_json.started = dummy_started; + status_json.uptime = dummy_uptime; + + pretty_assert_eq!( + status_json, + StatusHtml { + blessed_inscriptions: 1, + cursed_inscriptions: 0, + chain: Chain::Mainnet, + height: Some(2), + inscriptions: 1, + lost_sats: 0, + minimum_rune_for_next_block: Rune(99246114928149462), + rune_index: false, + runes: 0, + sat_index: true, + started: dummy_started, + transaction_index: false, + unrecoverably_reorged: false, + uptime: dummy_uptime, + } + ); +} diff --git a/tests/lib.rs b/tests/lib.rs index abc086ed83..0942ad1acf 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -7,13 +7,15 @@ use { blockdata::constants::COIN_VALUE, Network, OutPoint, Txid, }, + chrono::{DateTime, Utc}, executable_path::executable_path, ord::{ + chain::Chain, rarity::Rarity, subcommand::runes::RuneInfo, templates::{ block::BlockJson, inscription::InscriptionJson, inscriptions::InscriptionsJson, - output::OutputJson, sat::SatJson, + output::OutputJson, sat::SatJson, status::StatusHtml, }, Edict, InscriptionId, Rune, RuneId, Runestone, SatPoint, }, From 16aa7efb806f01e02c78840b9a522df92df30ef1 Mon Sep 17 00:00:00 2001 From: 0xLugon Date: Fri, 5 Jan 2024 06:30:53 +0700 Subject: [PATCH 05/18] Add JSON endpoints for Runes (#2941) --- src/index.rs | 37 ++------- src/index/entry.rs | 30 +++---- src/lib.rs | 4 +- src/subcommand/server.rs | 39 ++++++--- src/subcommand/wallet/etch.rs | 6 +- src/subcommand/wallet/send.rs | 2 +- src/templates.rs | 8 +- src/templates/rune.rs | 12 +-- src/templates/runes.rs | 8 +- tests/json_api.rs | 152 ++++++++++++++++++++++++++++++++-- tests/lib.rs | 15 ++-- tests/test_server.rs | 12 ++- 12 files changed, 236 insertions(+), 89 deletions(-) diff --git a/src/index.rs b/src/index.rs index 5f920eb085..9042ce20a3 100644 --- a/src/index.rs +++ b/src/index.rs @@ -11,7 +11,7 @@ use { super::*, crate::{ subcommand::{find::FindRangeOutput, server::InscriptionQuery}, - templates::{RuneHtml, StatusHtml}, + templates::StatusHtml, }, bitcoin::block::Header, bitcoincore_rpc::{json::GetBlockHeaderResult, Client}, @@ -30,7 +30,7 @@ use { }, }; -pub(crate) use self::entry::RuneEntry; +pub use self::entry::RuneEntry; pub(crate) mod entry; mod fetcher; @@ -855,29 +855,10 @@ impl Index { ) } - pub(crate) fn rune(&self, rune: Rune) -> Result> { - let rtx = self.database.begin_read()?; - - let Some(id) = rtx - .open_table(RUNE_TO_RUNE_ID)? - .get(rune.0)? - .map(|guard| guard.value()) - else { - return Ok(None); - }; - - let entry = RuneEntry::load( - rtx - .open_table(RUNE_ID_TO_RUNE_ENTRY)? - .get(id)? - .unwrap() - .value(), - ); - - Ok(Some((RuneId::load(id), entry))) - } - - pub(crate) fn rune_html(&self, rune: Rune) -> Result> { + pub(crate) fn rune( + &self, + rune: Rune, + ) -> Result)>> { let rtx = self.database.begin_read()?; let Some(id) = rtx @@ -907,11 +888,7 @@ impl Index { .is_some() .then_some(parent); - Ok(Some(RuneHtml { - entry, - id: RuneId::load(id), - parent, - })) + Ok(Some((RuneId::load(id), entry, parent))) } pub(crate) fn runes(&self) -> Result> { diff --git a/src/index/entry.rs b/src/index/entry.rs index e5b1a9976c..116ee448ea 100644 --- a/src/index/entry.rs +++ b/src/index/entry.rs @@ -28,21 +28,21 @@ impl Entry for Header { } } -#[derive(Debug, PartialEq, Copy, Clone)] -pub(crate) struct RuneEntry { - pub(crate) burned: u128, - pub(crate) deadline: Option, - pub(crate) divisibility: u8, - pub(crate) end: Option, - pub(crate) etching: Txid, - pub(crate) limit: Option, - pub(crate) mints: u64, - pub(crate) number: u64, - pub(crate) rune: Rune, - pub(crate) spacers: u32, - pub(crate) supply: u128, - pub(crate) symbol: Option, - pub(crate) timestamp: u32, +#[derive(Debug, PartialEq, Copy, Clone, Serialize, Deserialize)] +pub struct RuneEntry { + pub burned: u128, + pub deadline: Option, + pub divisibility: u8, + pub end: Option, + pub etching: Txid, + pub limit: Option, + pub mints: u64, + pub number: u64, + pub rune: Rune, + pub spacers: u32, + pub supply: u128, + pub symbol: Option, + pub timestamp: u32, } pub(super) type RuneEntryValue = ( diff --git a/src/lib.rs b/src/lib.rs index 55b2379d9d..9102594701 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,7 +21,7 @@ use { deserialize_from_str::DeserializeFromStr, epoch::Epoch, height::Height, - index::{List, RuneEntry}, + index::List, inscriptions::{media, teleburn, Charm, Media, ParsedEnvelope}, outgoing::Outgoing, representation::Representation, @@ -85,7 +85,7 @@ use { pub use self::{ chain::Chain, fee_rate::FeeRate, - index::Index, + index::{Index, RuneEntry}, inscriptions::{Envelope, Inscription, InscriptionId}, object::Object, options::Options, diff --git a/src/subcommand/server.rs b/src/subcommand/server.rs index d767ba53d6..03bdaf58fb 100644 --- a/src/subcommand/server.rs +++ b/src/subcommand/server.rs @@ -14,8 +14,8 @@ use { InscriptionsHtml, InscriptionsJson, OutputHtml, OutputJson, PageContent, PageHtml, PreviewAudioHtml, PreviewCodeHtml, PreviewFontHtml, PreviewImageHtml, PreviewMarkdownHtml, PreviewModelHtml, PreviewPdfHtml, PreviewTextHtml, PreviewUnknownHtml, PreviewVideoHtml, - RangeHtml, RareTxt, RuneHtml, RunesHtml, SatHtml, SatInscriptionJson, SatInscriptionsJson, - SatJson, TransactionHtml, + RangeHtml, RareTxt, RuneHtml, RuneJson, RunesHtml, RunesJson, SatHtml, SatInscriptionJson, + SatInscriptionsJson, SatJson, TransactionHtml, }, }, axum::{ @@ -617,31 +617,44 @@ impl Server { Extension(server_config): Extension>, Extension(index): Extension>, Path(DeserializeFromStr(spaced_rune)): Path>, - ) -> ServerResult> { + AcceptJson(accept_json): AcceptJson, + ) -> ServerResult { if !index.has_rune_index() { return Err(ServerError::NotFound( "this server has no rune index".to_string(), )); } - Ok( - index - .rune_html(spaced_rune.rune)? - .ok_or_not_found(|| format!("rune {spaced_rune}"))? - .page(server_config), - ) + let (id, entry, parent) = index + .rune(spaced_rune.rune)? + .ok_or_not_found(|| format!("rune {spaced_rune}"))?; + + Ok(if accept_json { + Json(RuneJson { entry, id, parent }).into_response() + } else { + RuneHtml { entry, id, parent } + .page(server_config) + .into_response() + }) } async fn runes( Extension(server_config): Extension>, Extension(index): Extension>, - ) -> ServerResult> { - Ok( + AcceptJson(accept_json): AcceptJson, + ) -> ServerResult { + Ok(if accept_json { + Json(RunesJson { + entries: index.runes()?, + }) + .into_response() + } else { RunesHtml { entries: index.runes()?, } - .page(server_config), - ) + .page(server_config) + .into_response() + }) } async fn home( diff --git a/src/subcommand/wallet/etch.rs b/src/subcommand/wallet/etch.rs index b02ea68015..1c00a36370 100644 --- a/src/subcommand/wallet/etch.rs +++ b/src/subcommand/wallet/etch.rs @@ -16,6 +16,7 @@ pub(crate) struct Etch { #[derive(Serialize, Deserialize, Debug)] pub struct Output { + pub rune: SpacedRune, pub transaction: Txid, } @@ -123,6 +124,9 @@ impl Etch { let transaction = client.send_raw_transaction(&signed_transaction)?; - Ok(Box::new(Output { transaction })) + Ok(Box::new(Output { + rune: self.rune, + transaction, + })) } } diff --git a/src/subcommand/wallet/send.rs b/src/subcommand/wallet/send.rs index 24575ceac2..bf1d98b0c4 100644 --- a/src/subcommand/wallet/send.rs +++ b/src/subcommand/wallet/send.rs @@ -182,7 +182,7 @@ impl Send { Self::lock_non_cardinal_outputs(client, &inscriptions, &runic_outputs, unspent_outputs)?; - let (id, entry) = index + let (id, entry, _parent) = index .rune(spaced_rune.rune)? .with_context(|| format!("rune `{}` has not been etched", spaced_rune.rune))?; diff --git a/src/templates.rs b/src/templates.rs index 4a53f94836..fc9385d7b7 100644 --- a/src/templates.rs +++ b/src/templates.rs @@ -20,8 +20,8 @@ pub(crate) use { }, range::RangeHtml, rare::RareTxt, - rune::RuneHtml, - runes::RunesHtml, + rune::{RuneHtml, RuneJson}, + runes::{RunesHtml, RunesJson}, sat::{SatHtml, SatInscriptionJson, SatInscriptionsJson, SatJson}, server_config::ServerConfig, status::StatusHtml, @@ -44,8 +44,8 @@ pub mod output; mod preview; mod range; mod rare; -mod rune; -mod runes; +pub mod rune; +pub mod runes; pub mod sat; pub mod status; mod transaction; diff --git a/src/templates/rune.rs b/src/templates/rune.rs index 76ed61dbc0..78a688a66a 100644 --- a/src/templates/rune.rs +++ b/src/templates/rune.rs @@ -1,10 +1,12 @@ use super::*; -#[derive(Boilerplate)] -pub(crate) struct RuneHtml { - pub(crate) entry: RuneEntry, - pub(crate) id: RuneId, - pub(crate) parent: Option, +pub type RuneJson = RuneHtml; + +#[derive(Boilerplate, Debug, PartialEq, Serialize, Deserialize)] +pub struct RuneHtml { + pub entry: RuneEntry, + pub id: RuneId, + pub parent: Option, } impl PageContent for RuneHtml { diff --git a/src/templates/runes.rs b/src/templates/runes.rs index 976714ab2f..ace35fca32 100644 --- a/src/templates/runes.rs +++ b/src/templates/runes.rs @@ -1,8 +1,10 @@ use super::*; -#[derive(Boilerplate)] -pub(crate) struct RunesHtml { - pub(crate) entries: Vec<(RuneId, RuneEntry)>, +pub type RunesJson = RunesHtml; + +#[derive(Boilerplate, Debug, PartialEq, Serialize, Deserialize)] +pub struct RunesHtml { + pub entries: Vec<(RuneId, RuneEntry)>, } impl PageContent for RunesHtml { diff --git a/tests/json_api.rs b/tests/json_api.rs index 2be51014f4..439e440835 100644 --- a/tests/json_api.rs +++ b/tests/json_api.rs @@ -368,15 +368,21 @@ fn get_block() { #[test] fn get_status() { - let rpc_server = test_bitcoincore_rpc::spawn(); + let rpc_server = test_bitcoincore_rpc::builder() + .network(Network::Regtest) + .build(); create_wallet(&rpc_server); + rpc_server.mine_blocks(1); inscribe(&rpc_server); - let response = - TestServer::spawn_with_server_args(&rpc_server, &["--index-sats"], &["--enable-json-api"]) - .json_request("/status"); + let response = TestServer::spawn_with_server_args( + &rpc_server, + &["--regtest", "--index-sats", "--index-runes"], + &["--enable-json-api"], + ) + .json_request("/status"); assert_eq!(response.status(), StatusCode::OK); @@ -396,12 +402,12 @@ fn get_status() { StatusHtml { blessed_inscriptions: 1, cursed_inscriptions: 0, - chain: Chain::Mainnet, - height: Some(2), + chain: Chain::Regtest, + height: Some(3), inscriptions: 1, lost_sats: 0, - minimum_rune_for_next_block: Rune(99246114928149462), - rune_index: false, + minimum_rune_for_next_block: Rune(99218849511960410), + rune_index: true, runes: 0, sat_index: true, started: dummy_started, @@ -411,3 +417,133 @@ fn get_status() { } ); } + +#[test] +fn get_runes() { + let rpc_server = test_bitcoincore_rpc::builder() + .network(Network::Regtest) + .build(); + + create_wallet(&rpc_server); + rpc_server.mine_blocks(3); + + let a = etch(&rpc_server, Rune(RUNE)); + let b = etch(&rpc_server, Rune(RUNE + 1)); + let c = etch(&rpc_server, Rune(RUNE + 2)); + + rpc_server.mine_blocks(1); + + let server = TestServer::spawn_with_server_args( + &rpc_server, + &["--index-runes", "--regtest"], + &["--enable-json-api"], + ); + + let response = server.json_request(format!("/rune/{}", a.rune)); + assert_eq!(response.status(), StatusCode::OK); + + let rune_json: RuneJson = serde_json::from_str(&response.text().unwrap()).unwrap(); + + pretty_assert_eq!( + rune_json, + RuneJson { + entry: RuneEntry { + burned: 0, + deadline: None, + divisibility: 0, + end: None, + etching: a.transaction, + limit: None, + mints: 0, + number: 0, + rune: Rune(RUNE), + spacers: 0, + supply: 1000, + symbol: Some('¢'), + timestamp: 5, + }, + id: RuneId { + height: 5, + index: 1 + }, + parent: None, + } + ); + + let response = server.json_request("/runes"); + + assert_eq!(response.status(), StatusCode::OK); + + let runes_json: RunesJson = serde_json::from_str(&response.text().unwrap()).unwrap(); + + pretty_assert_eq!( + runes_json, + RunesJson { + entries: vec![ + ( + RuneId { + height: 5, + index: 1 + }, + RuneEntry { + burned: 0, + deadline: None, + divisibility: 0, + end: None, + etching: a.transaction, + limit: None, + mints: 0, + number: 0, + rune: Rune(RUNE), + spacers: 0, + supply: 1000, + symbol: Some('¢'), + timestamp: 5, + } + ), + ( + RuneId { + height: 7, + index: 1 + }, + RuneEntry { + burned: 0, + deadline: None, + divisibility: 0, + end: None, + etching: b.transaction, + limit: None, + mints: 0, + number: 1, + rune: Rune(RUNE + 1), + spacers: 0, + supply: 1000, + symbol: Some('¢'), + timestamp: 7, + } + ), + ( + RuneId { + height: 9, + index: 1 + }, + RuneEntry { + burned: 0, + deadline: None, + divisibility: 0, + end: None, + etching: c.transaction, + limit: None, + mints: 0, + number: 2, + rune: Rune(RUNE + 2), + spacers: 0, + supply: 1000, + symbol: Some('¢'), + timestamp: 9, + } + ) + ] + } + ); +} diff --git a/tests/lib.rs b/tests/lib.rs index 0942ad1acf..f1d3ad25a4 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -15,9 +15,9 @@ use { subcommand::runes::RuneInfo, templates::{ block::BlockJson, inscription::InscriptionJson, inscriptions::InscriptionsJson, - output::OutputJson, sat::SatJson, status::StatusHtml, + output::OutputJson, rune::RuneJson, runes::RunesJson, sat::SatJson, status::StatusHtml, }, - Edict, InscriptionId, Rune, RuneId, Runestone, SatPoint, + Edict, InscriptionId, Rune, RuneEntry, RuneId, Runestone, SatPoint, }, pretty_assertions::assert_eq as pretty_assert_eq, regex::Regex, @@ -108,10 +108,13 @@ fn runes(rpc_server: &test_bitcoincore_rpc::Handle) -> BTreeMap fn inscribe(rpc_server: &test_bitcoincore_rpc::Handle) -> (InscriptionId, Txid) { rpc_server.mine_blocks(1); - let output = CommandBuilder::new("wallet inscribe --fee-rate 1 --file foo.txt") - .write("foo.txt", "FOO") - .rpc_server(rpc_server) - .run_and_deserialize_output::(); + let output = CommandBuilder::new(format!( + "--chain {} wallet inscribe --fee-rate 1 --file foo.txt", + rpc_server.network() + )) + .write("foo.txt", "FOO") + .rpc_server(rpc_server) + .run_and_deserialize_output::(); rpc_server.mine_blocks(1); diff --git a/tests/test_server.rs b/tests/test_server.rs index 87a7f794cc..7541264411 100644 --- a/tests/test_server.rs +++ b/tests/test_server.rs @@ -27,7 +27,17 @@ impl TestServer { server_args: &[&str], ) -> Self { let tempdir = TempDir::new().unwrap(); - fs::write(tempdir.path().join(".cookie"), "foo:bar").unwrap(); + + let cookie_file = match rpc_server.network().as_str() { + "mainnet" => tempdir.path().join(".cookie"), + network => { + fs::create_dir(tempdir.path().join(network)).unwrap(); + tempdir.path().join(format!("{network}/.cookie")) + } + }; + + fs::write(cookie_file.clone(), "foo:bar").unwrap(); + let port = TcpListener::bind("127.0.0.1:0") .unwrap() .local_addr() From b9b1ddd5b3a1e96322a2dacf4390bac62ab5513a Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Thu, 4 Jan 2024 16:15:15 -0800 Subject: [PATCH 06/18] Vindicate cursed inscriptions (#2950) --- src/index.rs | 247 +++++++++++++++++++++-- src/index/updater/inscription_updater.rs | 27 ++- src/inscriptions/charm.rs | 37 ++-- src/subcommand/server.rs | 44 ++++ src/templates/inscription.rs | 1 + tests/json_api.rs | 19 +- 6 files changed, 332 insertions(+), 43 deletions(-) diff --git a/src/index.rs b/src/index.rs index 9042ce20a3..91fb5e6cb8 100644 --- a/src/index.rs +++ b/src/index.rs @@ -87,18 +87,18 @@ pub enum List { #[derive(Copy, Clone)] pub(crate) enum Statistic { Schema = 0, - BlessedInscriptions, - Commits, - CursedInscriptions, - IndexRunes, - IndexSats, - LostSats, - OutputsTraversed, - ReservedRunes, - Runes, - SatRanges, - UnboundInscriptions, - IndexTransactions, + BlessedInscriptions = 1, + Commits = 2, + CursedInscriptions = 3, + IndexRunes = 4, + IndexSats = 5, + LostSats = 6, + OutputsTraversed = 7, + ReservedRunes = 8, + Runes = 9, + SatRanges = 10, + UnboundInscriptions = 11, + IndexTransactions = 12, } impl Statistic { @@ -5568,4 +5568,227 @@ mod tests { ); } } + + #[test] + fn pre_jubilee_first_reinscription_after_cursed_inscription_is_blessed() { + for context in Context::configurations() { + context.mine_blocks(1); + + // Before the jubilee, an inscription on a sat using a pushnum opcode is + // cursed and not vindicated. + + let script = script::Builder::new() + .push_opcode(opcodes::OP_FALSE) + .push_opcode(opcodes::all::OP_IF) + .push_slice(b"ord") + .push_slice([]) + .push_opcode(opcodes::all::OP_PUSHNUM_1) + .push_opcode(opcodes::all::OP_ENDIF) + .into_script(); + + let witness = Witness::from_slice(&[script.into_bytes(), Vec::new()]); + + let txid = context.rpc_server.broadcast_tx(TransactionTemplate { + inputs: &[(1, 0, 0, witness)], + ..Default::default() + }); + + let inscription_id = InscriptionId { txid, index: 0 }; + + context.mine_blocks(1); + + let entry = context + .index + .get_inscription_entry(inscription_id) + .unwrap() + .unwrap(); + + assert!(Charm::charms(entry.charms) + .iter() + .any(|charm| *charm == Charm::Cursed)); + + assert!(!Charm::charms(entry.charms) + .iter() + .any(|charm| *charm == Charm::Vindicated)); + + let sat = entry.sat; + + assert_eq!(entry.inscription_number, -1); + + // Before the jubilee, reinscription on the same sat is not cursed and + // not vindicated. + + let inscription = Inscription::default(); + + let txid = context.rpc_server.broadcast_tx(TransactionTemplate { + inputs: &[(2, 1, 0, inscription.to_witness())], + ..Default::default() + }); + + context.mine_blocks(1); + + let inscription_id = InscriptionId { txid, index: 0 }; + + let entry = context + .index + .get_inscription_entry(inscription_id) + .unwrap() + .unwrap(); + + assert_eq!(entry.inscription_number, 0); + + assert!(!Charm::charms(entry.charms) + .iter() + .any(|charm| *charm == Charm::Cursed)); + + assert!(!Charm::charms(entry.charms) + .iter() + .any(|charm| *charm == Charm::Vindicated)); + + assert_eq!(sat, entry.sat); + + // Before the jubilee, a third reinscription on the same sat is cursed + // and not vindicated. + + let inscription = Inscription::default(); + + let txid = context.rpc_server.broadcast_tx(TransactionTemplate { + inputs: &[(3, 1, 0, inscription.to_witness())], + ..Default::default() + }); + + context.mine_blocks(1); + + let inscription_id = InscriptionId { txid, index: 0 }; + + let entry = context + .index + .get_inscription_entry(inscription_id) + .unwrap() + .unwrap(); + + assert!(Charm::charms(entry.charms) + .iter() + .any(|charm| *charm == Charm::Cursed)); + + assert!(!Charm::charms(entry.charms) + .iter() + .any(|charm| *charm == Charm::Vindicated)); + + assert_eq!(entry.inscription_number, -2); + + assert_eq!(sat, entry.sat); + } + } + + #[test] + fn post_jubilee_first_reinscription_after_vindicated_inscription_not_vindicated() { + for context in Context::configurations() { + context.mine_blocks(110); + // After the jubilee, an inscription on a sat using a pushnum opcode is + // vindicated and not cursed. + + let script = script::Builder::new() + .push_opcode(opcodes::OP_FALSE) + .push_opcode(opcodes::all::OP_IF) + .push_slice(b"ord") + .push_slice([]) + .push_opcode(opcodes::all::OP_PUSHNUM_1) + .push_opcode(opcodes::all::OP_ENDIF) + .into_script(); + + let witness = Witness::from_slice(&[script.into_bytes(), Vec::new()]); + + let txid = context.rpc_server.broadcast_tx(TransactionTemplate { + inputs: &[(1, 0, 0, witness)], + ..Default::default() + }); + + let inscription_id = InscriptionId { txid, index: 0 }; + + context.mine_blocks(1); + + let entry = context + .index + .get_inscription_entry(inscription_id) + .unwrap() + .unwrap(); + + assert!(!Charm::charms(entry.charms) + .iter() + .any(|charm| *charm == Charm::Cursed)); + + assert!(Charm::charms(entry.charms) + .iter() + .any(|charm| *charm == Charm::Vindicated)); + + let sat = entry.sat; + + assert_eq!(entry.inscription_number, 0); + + // After the jubilee, a reinscription on the same is not cursed and not + // vindicated. + + let inscription = Inscription::default(); + + let txid = context.rpc_server.broadcast_tx(TransactionTemplate { + inputs: &[(111, 1, 0, inscription.to_witness())], + ..Default::default() + }); + + context.mine_blocks(1); + + let inscription_id = InscriptionId { txid, index: 0 }; + + let entry = context + .index + .get_inscription_entry(inscription_id) + .unwrap() + .unwrap(); + + assert!(!Charm::charms(entry.charms) + .iter() + .any(|charm| *charm == Charm::Cursed)); + + assert!(!Charm::charms(entry.charms) + .iter() + .any(|charm| *charm == Charm::Vindicated)); + + assert_eq!(entry.inscription_number, 1); + + assert_eq!(sat, entry.sat); + + // After the jubilee, a third reinscription on the same is vindicated and + // not cursed. + + let inscription = Inscription::default(); + + let txid = context.rpc_server.broadcast_tx(TransactionTemplate { + inputs: &[(112, 1, 0, inscription.to_witness())], + ..Default::default() + }); + + context.mine_blocks(1); + + let inscription_id = InscriptionId { txid, index: 0 }; + + let entry = context + .index + .get_inscription_entry(inscription_id) + .unwrap() + .unwrap(); + + assert!(!Charm::charms(entry.charms) + .iter() + .any(|charm| *charm == Charm::Cursed)); + + assert!(Charm::charms(entry.charms) + .iter() + .any(|charm| *charm == Charm::Vindicated)); + + assert_eq!(entry.inscription_number, 2); + + assert_eq!(sat, entry.sat); + } + } } diff --git a/src/index/updater/inscription_updater.rs b/src/index/updater/inscription_updater.rs index a491950073..19f99033cc 100644 --- a/src/index/updater/inscription_updater.rs +++ b/src/index/updater/inscription_updater.rs @@ -30,6 +30,7 @@ enum Origin { pointer: Option, reinscription: bool, unbound: bool, + vindicated: bool, }, Old { old_satpoint: SatPoint, @@ -76,6 +77,7 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> { let mut floating_inscriptions = Vec::new(); let mut id_counter = 0; let mut inscribed_offsets = BTreeMap::new(); + let jubilant = self.height >= self.chain.jubilee_height(); let mut total_input_value = 0; let total_output_value = tx.output.iter().map(|txout| txout.value).sum::(); @@ -142,9 +144,7 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> { index: id_counter, }; - let curse = if self.height >= self.chain.jubilee_height() { - None - } else if inscription.payload.unrecognized_even_field { + let curse = if inscription.payload.unrecognized_even_field { Some(Curse::UnrecognizedEvenField) } else if inscription.payload.duplicate_field { Some(Curse::DuplicateField) @@ -167,17 +167,18 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> { let initial_inscription_sequence_number = self.id_to_sequence_number.get(id.store())?.unwrap().value(); - let initial_inscription_is_cursed = InscriptionEntry::load( + let entry = InscriptionEntry::load( self .sequence_number_to_entry .get(initial_inscription_sequence_number)? .unwrap() .value(), - ) - .inscription_number - < 0; + ); + + let initial_inscription_was_cursed_or_vindicated = + entry.inscription_number < 0 || Charm::Vindicated.is_set(entry.charms); - if initial_inscription_is_cursed { + if initial_inscription_was_cursed_or_vindicated { None } else { Some(Curse::Reinscription) @@ -201,13 +202,14 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> { inscription_id, offset, origin: Origin::New { - reinscription: inscribed_offsets.get(&offset).is_some(), - cursed: curse.is_some(), + cursed: curse.is_some() && !jubilant, fee: 0, hidden: inscription.payload.hidden(), parent: inscription.payload.parent(), pointer: inscription.payload.pointer(), + reinscription: inscribed_offsets.get(&offset).is_some(), unbound, + vindicated: curse.is_some() && jubilant, }, }); @@ -404,6 +406,7 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> { pointer: _, reinscription, unbound, + vindicated, } => { let inscription_number = if cursed { let number: i32 = self.cursed_inscription_count.try_into().unwrap(); @@ -467,6 +470,10 @@ impl<'a, 'db, 'tx> InscriptionUpdater<'a, 'db, 'tx> { Charm::Unbound.set(&mut charms); } + if vindicated { + Charm::Vindicated.set(&mut charms); + } + if let Some(Sat(n)) = sat { self.sat_to_sequence_number.insert(&n, &sequence_number)?; } diff --git a/src/inscriptions/charm.rs b/src/inscriptions/charm.rs index b80c5c6616..d0770886d7 100644 --- a/src/inscriptions/charm.rs +++ b/src/inscriptions/charm.rs @@ -1,19 +1,20 @@ -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug, PartialEq)] pub(crate) enum Charm { - Coin, - Cursed, - Epic, - Legendary, - Lost, - Nineball, - Rare, - Reinscription, - Unbound, - Uncommon, + Coin = 0, + Cursed = 1, + Epic = 2, + Legendary = 3, + Lost = 4, + Nineball = 5, + Rare = 6, + Reinscription = 7, + Unbound = 8, + Uncommon = 9, + Vindicated = 10, } impl Charm { - pub(crate) const ALL: [Charm; 10] = [ + pub(crate) const ALL: [Charm; 11] = [ Self::Coin, Self::Uncommon, Self::Rare, @@ -24,6 +25,7 @@ impl Charm { Self::Cursed, Self::Unbound, Self::Lost, + Self::Vindicated, ]; fn flag(self) -> u16 { @@ -50,6 +52,7 @@ impl Charm { Self::Reinscription => "♻️", Self::Unbound => "🔓", Self::Uncommon => "🌱", + Self::Vindicated => "❤️‍🔥", } } @@ -65,6 +68,16 @@ impl Charm { Self::Reinscription => "reinscription", Self::Unbound => "unbound", Self::Uncommon => "uncommon", + Self::Vindicated => "vindicated", } } + + #[cfg(test)] + pub(crate) fn charms(charms: u16) -> Vec { + Self::ALL + .iter() + .filter(|charm| charm.is_set(charms)) + .cloned() + .collect() + } } diff --git a/src/subcommand/server.rs b/src/subcommand/server.rs index 03bdaf58fb..925451d1c7 100644 --- a/src/subcommand/server.rs +++ b/src/subcommand/server.rs @@ -1237,6 +1237,11 @@ impl Server { Ok(if accept_json { Json(InscriptionJson { inscription_id: info.entry.id, + charms: Charm::ALL + .iter() + .filter(|charm| charm.is_set(info.charms)) + .map(|charm| charm.title().into()) + .collect(), children: info.children, inscription_number: info.entry.inscription_number, genesis_height: info.entry.height, @@ -4379,6 +4384,45 @@ next ); } + #[test] + fn charm_vindicated() { + let server = TestServer::new_with_regtest(); + + server.mine_blocks(110); + + let txid = server.bitcoin_rpc_server.broadcast_tx(TransactionTemplate { + inputs: &[ + (1, 0, 0, Witness::default()), + (2, 0, 0, inscription("text/plain", "cursed").to_witness()), + ], + outputs: 2, + ..Default::default() + }); + + let id = InscriptionId { txid, index: 0 }; + + server.mine_blocks(1); + + server.assert_response_regex( + format!("/inscription/{id}"), + StatusCode::OK, + format!( + ".*

Inscription 0

.* +
+
id
+
{id}
+
charms
+
+ ❤️‍🔥 +
+ .* +
+.* +" + ), + ); + } + #[test] fn charm_coin() { let server = TestServer::new_with_regtest_with_index_sats(); diff --git a/src/templates/inscription.rs b/src/templates/inscription.rs index 4faff866ab..2470424a35 100644 --- a/src/templates/inscription.rs +++ b/src/templates/inscription.rs @@ -23,6 +23,7 @@ pub(crate) struct InscriptionHtml { #[derive(Debug, PartialEq, Serialize, Deserialize)] pub struct InscriptionJson { pub address: Option, + pub charms: Vec, pub children: Vec, pub content_length: Option, pub content_type: Option, diff --git a/tests/json_api.rs b/tests/json_api.rs index 439e440835..fc0d471a19 100644 --- a/tests/json_api.rs +++ b/tests/json_api.rs @@ -147,22 +147,23 @@ fn get_inscription() { pretty_assert_eq!( inscription_json, InscriptionJson { - parent: None, + address: None, + charms: vec!["coin".into(), "uncommon".into()], children: Vec::new(), + content_length: Some(3), + content_type: Some("text/plain;charset=utf-8".to_string()), + genesis_fee: 138, + genesis_height: 2, inscription_id, inscription_number: 0, - genesis_height: 2, - genesis_fee: 138, + next: None, output_value: Some(10000), - address: None, + parent: None, + previous: None, + rune: None, sat: Some(ord::Sat(50 * COIN_VALUE)), satpoint: SatPoint::from_str(&format!("{}:{}:{}", reveal, 0, 0)).unwrap(), - content_type: Some("text/plain;charset=utf-8".to_string()), - content_length: Some(3), timestamp: 2, - previous: None, - next: None, - rune: None, } ) } From 809847a0984ed2d7589e5955ae6aee4af20c46c1 Mon Sep 17 00:00:00 2001 From: raph Date: Sat, 6 Jan 2024 01:07:15 +0100 Subject: [PATCH 07/18] Add no sync option to server command (#2966) --- src/subcommand/server.rs | 8 +++- src/subcommand/wallet/inscribe.rs | 3 +- tests/command_builder.rs | 13 +++--- tests/index.rs | 2 +- tests/lib.rs | 1 + tests/server.rs | 69 +++++++++++++++++++++++++++++++ 6 files changed, 86 insertions(+), 10 deletions(-) diff --git a/src/subcommand/server.rs b/src/subcommand/server.rs index 925451d1c7..d1e60c57e5 100644 --- a/src/subcommand/server.rs +++ b/src/subcommand/server.rs @@ -170,6 +170,8 @@ pub(crate) struct Server { help = "Decompress encoded content. Currently only supports brotli. Be careful using this on production instances. A decompressed inscription may be arbitrarily large, making decompression a DoS vector." )] pub(crate) decompress: bool, + #[arg(long, alias = "nosync", help = "Do not update the index.")] + no_sync: bool, } impl Server { @@ -181,8 +183,10 @@ impl Server { if SHUTTING_DOWN.load(atomic::Ordering::Relaxed) { break; } - if let Err(error) = index_clone.update() { - log::warn!("Updating index: {error}"); + if !self.no_sync { + if let Err(error) = index_clone.update() { + log::warn!("Updating index: {error}"); + } } thread::sleep(Duration::from_millis(5000)); }); diff --git a/src/subcommand/wallet/inscribe.rs b/src/subcommand/wallet/inscribe.rs index 71dc9b039a..a27f88e438 100644 --- a/src/subcommand/wallet/inscribe.rs +++ b/src/subcommand/wallet/inscribe.rs @@ -85,10 +85,11 @@ pub(crate) struct Inscribe { pub(crate) json_metadata: Option, #[clap(long, help = "Set inscription metaprotocol to .")] pub(crate) metaprotocol: Option, - #[arg(long, help = "Do not back up recovery key.")] + #[arg(long, alias = "nobackup", help = "Do not back up recovery key.")] pub(crate) no_backup: bool, #[arg( long, + alias = "nolimit", help = "Do not check that transactions are equal to or below the MAX_STANDARD_TX_WEIGHT of 400,000 weight units. Transactions over this limit are currently nonstandard and will not be relayed by bitcoind in its default configuration. Do not use this flag unless you understand the implications." )] pub(crate) no_limit: bool, diff --git a/tests/command_builder.rs b/tests/command_builder.rs index 5cc9171c8e..01fc621fe2 100644 --- a/tests/command_builder.rs +++ b/tests/command_builder.rs @@ -36,7 +36,7 @@ pub(crate) struct CommandBuilder { rpc_server_cookie_file: Option, rpc_server_url: Option, stdin: Vec, - tempdir: TempDir, + tempdir: Arc, } impl CommandBuilder { @@ -49,7 +49,7 @@ impl CommandBuilder { rpc_server_cookie_file: None, rpc_server_url: None, stdin: Vec::new(), - tempdir: TempDir::new().unwrap(), + tempdir: Arc::new(TempDir::new().unwrap()), } } @@ -98,7 +98,7 @@ impl CommandBuilder { } } - pub(crate) fn temp_dir(self, tempdir: TempDir) -> Self { + pub(crate) fn temp_dir(self, tempdir: Arc) -> Self { Self { tempdir, ..self } } @@ -124,7 +124,7 @@ impl CommandBuilder { .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) - .current_dir(&self.tempdir) + .current_dir(&*self.tempdir) .arg("--data-dir") .arg(self.tempdir.path()) .args(&self.args); @@ -134,7 +134,8 @@ impl CommandBuilder { #[track_caller] fn run(self) -> (TempDir, String) { - let child = self.command().spawn().unwrap(); + let mut command = self.command(); + let child = command.spawn().unwrap(); child .stdin @@ -157,7 +158,7 @@ impl CommandBuilder { self.expected_stderr.assert_match(stderr); self.expected_stdout.assert_match(stdout); - (self.tempdir, stdout.into()) + (Arc::try_unwrap(self.tempdir).unwrap(), stdout.into()) } pub(crate) fn run_and_extract_file(self, path: impl AsRef) -> String { diff --git a/tests/index.rs b/tests/index.rs index 143f260af4..72e3a20ecf 100644 --- a/tests/index.rs +++ b/tests/index.rs @@ -95,7 +95,7 @@ fn export_inscription_number_to_id_tsv() { let tsv = CommandBuilder::new("index export --tsv foo.tsv") .rpc_server(&rpc_server) - .temp_dir(temp_dir) + .temp_dir(Arc::new(temp_dir)) .stdout_regex(r"\{\}\n") .run_and_extract_file("foo.tsv"); diff --git a/tests/lib.rs b/tests/lib.rs index f1d3ad25a4..5037851cca 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -23,6 +23,7 @@ use { regex::Regex, reqwest::{StatusCode, Url}, serde::de::DeserializeOwned, + std::sync::Arc, std::{ collections::BTreeMap, fs, diff --git a/tests/server.rs b/tests/server.rs index 71edfe1103..c7792fb279 100644 --- a/tests/server.rs +++ b/tests/server.rs @@ -492,3 +492,72 @@ fn inscription_transactions_are_stored_with_transaction_index() { StatusCode::NOT_FOUND, ); } + +#[test] +fn run_no_sync() { + let rpc_server = test_bitcoincore_rpc::spawn(); + + let port = TcpListener::bind("127.0.0.1:0") + .unwrap() + .local_addr() + .unwrap() + .port(); + + let tempdir = Arc::new(TempDir::new().unwrap()); + + let builder = CommandBuilder::new(format!("server --address 127.0.0.1 --http-port {port}",)) + .rpc_server(&rpc_server) + .temp_dir(tempdir.clone()); + + let mut command = builder.command(); + + let mut child = command.spawn().unwrap(); + + rpc_server.mine_blocks(1); + + for attempt in 0.. { + if let Ok(response) = reqwest::blocking::get(format!("http://localhost:{port}/blockheight")) { + if response.status() == 200 { + assert_eq!(response.text().unwrap(), "1"); + break; + } + } + + if attempt == 100 { + panic!("Server did not respond to status check",); + } + + thread::sleep(Duration::from_millis(50)); + } + + child.kill().unwrap(); + + let builder = CommandBuilder::new(format!( + "server --no-sync --address 127.0.0.1 --http-port {port}", + )) + .rpc_server(&rpc_server) + .temp_dir(tempdir); + + let mut command = builder.command(); + + let mut child = command.spawn().unwrap(); + + rpc_server.mine_blocks(2); + + for attempt in 0.. { + if let Ok(response) = reqwest::blocking::get(format!("http://localhost:{port}/blockheight")) { + if response.status() == 200 { + assert_eq!(response.text().unwrap(), "1"); + break; + } + } + + if attempt == 100 { + panic!("Server did not respond to status check",); + } + + thread::sleep(Duration::from_millis(50)); + } + + child.kill().unwrap(); +} From fc90d249e50248ac4d462424525cce2fb16c2759 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Sat, 6 Jan 2024 13:58:41 -0800 Subject: [PATCH 08/18] Deduplicate deploy script case statements (#2962) --- deploy/setup | 70 +++++++++++++++------------------------------------- 1 file changed, 20 insertions(+), 50 deletions(-) diff --git a/deploy/setup b/deploy/setup index 86dfe216c6..b32ac5d891 100755 --- a/deploy/setup +++ b/deploy/setup @@ -10,35 +10,8 @@ BRANCH=$3 COMMIT=$4 REVISION="ord-$BRANCH-$COMMIT" -case $CHAIN in - main) - CSP_ORIGIN=ordinals.com - ;; - regtest) - CSP_ORIGIN=regtest.ordinals.com - ;; - signet) - CSP_ORIGIN=signet.ordinals.com - ;; - test) - CSP_ORIGIN=testnet.ordinals.com - ;; - *) - echo "Unknown chain: $CHAIN" - exit 1 - ;; -esac - touch ~/.hushlogin -mkdir -p \ - /etc/systemd/system/bitcoind.service.d \ - /etc/systemd/system/ord.service.d - -printf "[Service]\nEnvironment=CHAIN=%s\nEnvironment=CSP_ORIGIN=%s\n" $CHAIN $CSP_ORIGIN \ - | tee /etc/systemd/system/bitcoind.service.d/override.conf \ - > /etc/systemd/system/ord.service.d/override.conf - hostnamectl set-hostname $DOMAIN apt-get install --yes \ @@ -60,21 +33,25 @@ ufw allow http ufw allow https ufw allow ssh -sed -i -E 's/#?PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config -sshd -t -systemctl restart sshd - case $CHAIN in main) + COOKIE_FILE_DIR=/var/lib/bitcoind + CSP_ORIGIN=ordinals.com ufw allow 8333 ;; regtest) + COOKIE_FILE_DIR=/var/lib/bitcoind/regtest + CSP_ORIGIN=regtest.ordinals.com ufw allow 18444 ;; signet) + COOKIE_FILE_DIR=/var/lib/bitcoind/signet + CSP_ORIGIN=signet.ordinals.com ufw allow 38333 ;; test) + COOKIE_FILE_DIR=/var/lib/bitcoind/testnet3 + CSP_ORIGIN=testnet.ordinals.com ufw allow 18333 ;; *) @@ -83,6 +60,18 @@ case $CHAIN in ;; esac +mkdir -p \ + /etc/systemd/system/bitcoind.service.d \ + /etc/systemd/system/ord.service.d + +printf "[Service]\nEnvironment=CHAIN=%s\nEnvironment=CSP_ORIGIN=%s\n" $CHAIN $CSP_ORIGIN \ + | tee /etc/systemd/system/bitcoind.service.d/override.conf \ + > /etc/systemd/system/ord.service.d/override.conf + +sed -i -E 's/#?PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config +sshd -t +systemctl restart sshd + ufw --force enable if ! which bitcoind; then @@ -119,25 +108,6 @@ systemctl daemon-reload systemctl enable bitcoind systemctl restart bitcoind -case $CHAIN in - main) - COOKIE_FILE_DIR=/var/lib/bitcoind - ;; - regtest) - COOKIE_FILE_DIR=/var/lib/bitcoind/regtest - ;; - signet) - COOKIE_FILE_DIR=/var/lib/bitcoind/signet - ;; - test) - COOKIE_FILE_DIR=/var/lib/bitcoind/testnet3 - ;; - *) - echo "Unknown chain: $CHAIN" - exit 1 - ;; -esac - while [[ ! -f $COOKIE_FILE_DIR/.cookie ]]; do echo "Waiting for bitcoind…" sleep 1 From 4e8a1891e9d795a5d1f3801190b7301038791c34 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Sat, 6 Jan 2024 16:13:45 -0800 Subject: [PATCH 09/18] Enter beta (#2973) --- src/templates.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/templates.rs b/src/templates.rs index fc9385d7b7..8906adca8a 100644 --- a/src/templates.rs +++ b/src/templates.rs @@ -74,7 +74,7 @@ where fn superscript(&self) -> String { if self.config.chain == Chain::Mainnet { - "alpha".into() + "beta".into() } else { self.config.chain.to_string() } @@ -142,7 +142,7 @@ mod tests {