Skip to content

Clean up sync checks, remove mainnet alpha, and fix testnet sync #85

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 22, 2025
Merged
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
3 changes: 2 additions & 1 deletion client/src/bin/spaced.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ impl Composer {
}

async fn run(&mut self) -> anyhow::Result<()> {
let spaced = Args::configure().await?;
let shutdown_receiver = self.shutdown.subscribe();
let spaced = Args::configure(shutdown_receiver).await?;
self.setup_rpc_services(&spaced).await;
self.setup_sync_service(spaced).await;

Expand Down
11 changes: 4 additions & 7 deletions client/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ pub struct Args {
#[serde(rename_all = "lowercase")]
pub enum ExtendedNetwork {
Mainnet,
MainnetAlpha,
Testnet,
Testnet4,
Signet,
Expand All @@ -98,7 +97,7 @@ pub enum ExtendedNetwork {
impl ExtendedNetwork {
pub fn fallback_network(&self) -> Network {
match self {
ExtendedNetwork::Mainnet | ExtendedNetwork::MainnetAlpha => Network::Bitcoin,
ExtendedNetwork::Mainnet => Network::Bitcoin,
ExtendedNetwork::Testnet => Network::Testnet,
ExtendedNetwork::Signet => Network::Signet,
ExtendedNetwork::Regtest => Network::Regtest,
Expand All @@ -110,7 +109,7 @@ impl ExtendedNetwork {
impl Args {
/// Configures spaced node by processing command line arguments
/// and configuration files
pub async fn configure() -> anyhow::Result<Spaced> {
pub async fn configure(shutdown: tokio::sync::broadcast::Receiver<()>) -> anyhow::Result<Spaced> {
let mut args = Args::merge_args_config(None);
let default_dirs = get_default_node_dirs();

Expand Down Expand Up @@ -170,7 +169,7 @@ impl Args {
!args.bitcoin_rpc_light
);

let genesis = Spaced::genesis(&rpc, args.chain).await?;
let genesis = Spaced::genesis(&rpc, args.chain, shutdown).await?;

fs::create_dir_all(data_dir.clone())?;

Expand Down Expand Up @@ -282,7 +281,7 @@ pub fn safe_exit(code: i32) -> ! {

pub fn default_bitcoin_rpc_url(network: &ExtendedNetwork) -> &'static str {
match network {
ExtendedNetwork::Mainnet | ExtendedNetwork::MainnetAlpha => "http://127.0.0.1:8332",
ExtendedNetwork::Mainnet => "http://127.0.0.1:8332",
ExtendedNetwork::Testnet4 => "http://127.0.0.1:48332",
ExtendedNetwork::Signet => "http://127.0.0.1:38332",
ExtendedNetwork::Testnet => "http://127.0.0.1:18332",
Expand Down Expand Up @@ -380,7 +379,6 @@ impl Display for ExtendedNetwork {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let str = match self {
ExtendedNetwork::Mainnet => "mainnet".to_string(),
ExtendedNetwork::MainnetAlpha => "mainnet-alpha".to_string(),
ExtendedNetwork::Testnet => "testnet".to_string(),
ExtendedNetwork::Testnet4 => "testnet4".to_string(),
ExtendedNetwork::Signet => "signet".to_string(),
Expand All @@ -393,7 +391,6 @@ impl Display for ExtendedNetwork {
pub fn default_spaces_rpc_port(chain: &ExtendedNetwork) -> u16 {
match chain {
ExtendedNetwork::Mainnet => 7225,
ExtendedNetwork::MainnetAlpha => 7225,
ExtendedNetwork::Testnet4 => 7224,
ExtendedNetwork::Testnet => 7223,
ExtendedNetwork::Signet => 7221,
Expand Down
9 changes: 8 additions & 1 deletion client/src/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -896,15 +896,22 @@ impl BlockSource for BitcoinBlockSource {
#[serde(rename = "bestblockhash")]
pub best_block_hash: BlockHash,
}
let info: Info = self
let mut info: Info = self
.rpc
.send_json_blocking(&self.client, &self.rpc.get_blockchain_info())?;

// TODO: update this check once testnet4 is part of the [Network] type.
// use network names from bitcoin core
// https://github.com/bitcoin/bitcoin/blob/master/src/util/chaintype.cpp
let expected_chain = match expected_chain {
Network::Bitcoin => "main",
Network::Regtest => "regtest",
Network::Signet => "signet",
_ => "test"
};
if info.chain.starts_with("test") {
info.chain = "test".to_string()
}
if info.chain != expected_chain {
warn!("Invalid chain from connected rpc node - expected {}, got {}", expected_chain, info.chain);
return Ok(None);
Expand Down
75 changes: 62 additions & 13 deletions client/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,34 +257,83 @@ impl Spaced {
pub async fn genesis(
rpc: &BitcoinRpc,
network: ExtendedNetwork,
mut shutdown: tokio::sync::broadcast::Receiver<()>
) -> anyhow::Result<ChainAnchor> {
let mut anchor = match network {
ExtendedNetwork::Testnet => ChainAnchor::TESTNET(),
ExtendedNetwork::Testnet4 => ChainAnchor::TESTNET4(),
ExtendedNetwork::Regtest => ChainAnchor::REGTEST(),
ExtendedNetwork::Mainnet => ChainAnchor::MAINNET(),
ExtendedNetwork::MainnetAlpha => ChainAnchor::MAINNET_ALPHA(),
_ => panic!("unsupported network"),
};

if anchor.hash == BlockHash::all_zeros() {
let client = reqwest::Client::new();

anchor.hash = match rpc
.send_json(&client, &rpc.get_block_hash(anchor.height))
.await
{
Ok(hash) => hash,
Err(e) => {
return Err(anyhow!(
"Could not retrieve activation block at height {}: {}",
anchor.height,
e

// Wait for the RPC node to be ready
let mut attempts = 0;
let mut last_error = BitcoinRpcError::Other("Unknown error".to_string());
loop {
if shutdown.try_recv().is_ok() {
return Err(anyhow!("Fetching activation height terminated: shutdown requested"))
}
if attempts > 5 {
return Err(anyhow!(
"Could not retrieve activation height: {}",
last_error
));
}

let rpc_task = rpc.clone();
let net_task = network.fallback_network();
let best_chain = tokio::task::spawn_blocking(move || {
let source = BitcoinBlockSource::new(rpc_task);
source.get_best_chain(Some(anchor.height), net_task)
}).await.expect("join");

match best_chain {
Ok(Some(tip)) => {
info!("Connect to RPC node (tip: {})", tip.height);
if anchor.hash != BlockHash::all_zeros() {
break;
}

// Pull the activation block hash
let client = reqwest::Client::new();
anchor.hash = match rpc
.send_json(&client, &rpc.get_block_hash(anchor.height))
.await
{
Ok(hash) => hash,
Err(e) => {
warn!("Fetching height {}:{}, retrying in 1s ...", anchor.height, e);
last_error = e;
match &last_error {
BitcoinRpcError::Rpc(_) => {}
_ => attempts += 1,
}
continue;
}
};

break;
}
Ok(None) => {
warn!("Connected RPC node is still syncing, waiting 5s ...");
tokio::time::sleep(Duration::from_secs(5)).await;
}
Err(e) => {
warn!("Error fetching blockchain info: {}, retrying in 1s ...", e);
last_error = e;
tokio::time::sleep(Duration::from_secs(1)).await;
match &last_error {
BitcoinRpcError::Rpc(_) => {}
_ => attempts += 1,
}
}
}
}


Ok(anchor)
}
}
5 changes: 0 additions & 5 deletions protocol/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,6 @@ impl ChainAnchor {
height: 871_222,
};

pub const MAINNET_ALPHA: fn() -> Self = || ChainAnchor {
hash: BlockHash::all_zeros(),
height: 870_000,
};

// Testnet4 activation block
pub const TESTNET4: fn() -> Self = || Self {
hash: BlockHash::all_zeros(),
Expand Down
Loading