Skip to content

Commit

Permalink
Support Testnet4 Network (#221)
Browse files Browse the repository at this point in the history
  • Loading branch information
will-bitlight authored Jul 17, 2024
1 parent ffc026d commit 8647dd4
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 25 deletions.
24 changes: 9 additions & 15 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 9 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,14 @@ serde_yaml = { workspace = true, optional = true }
log = { workspace = true, optional = true }

[features]
default = ["esplora_blocking"]
all = ["esplora_blocking", "electrum_blocking", "serde", "log", "fs", "cli"]
default = ["esplora_blocking", "mempool_blocking"]
all = ["esplora_blocking", "electrum_blocking", "mempool_blocking", "serde", "log", "fs", "cli"]
fs = ["serde", "bp-wallet/fs"]
cli = ["fs"]
cli = ["fs", "bp-wallet/cli"]
esplora_blocking = ["bp-esplora"]
electrum_blocking = ["bp-electrum"]
serde = ["serde_crate", "serde_yaml", "bp-std/serde", "descriptors/serde", "rgb-psbt/serde"]
mempool_blocking = ["esplora_blocking"]

[package.metadata.docs.rs]
features = ["all"]
Expand All @@ -97,3 +98,8 @@ features = ["all"]
bp-wallet = { git = "https://github.com/BP-WG/bp-wallet", branch = "master" }
rgb-core = { git = "https://github.com/RGB-WG/rgb-core", branch = "master" }
rgb-std = { git = "https://github.com/RGB-WG/rgb-std", branch = "master" }
bp-std = { git = "https://github.com/BP-WG/bp-std.git", branch = "master" }
bp-invoice = { git = "https://github.com/BP-WG/bp-std.git", branch = "master"}
psbt = { git = "https://github.com/BP-WG/bp-std.git", branch = "master" }
descriptors = { git = "https://github.com/BP-WG/bp-std.git", branch = "master" }
rgb-interfaces = { git = "https://github.com/RGB-WG/rgb-interfaces.git", branch = "master" }
16 changes: 9 additions & 7 deletions cli/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,15 @@ impl RgbArgs {
}

pub fn resolver(&self) -> Result<AnyResolver, WalletError> {
let resolver = match (&self.resolver.esplora, &self.resolver.electrum) {
(None, Some(url)) => AnyResolver::electrum_blocking(url, None),
(Some(url), None) => AnyResolver::esplora_blocking(url, None),
_ => Err(s!(" - error: no transaction resolver is specified; use either --esplora \
or --electrum argument")),
}
.map_err(WalletError::Resolver)?;
let resolver =
match (&self.resolver.esplora, &self.resolver.electrum, &self.resolver.mempool) {
(None, Some(url), None) => AnyResolver::electrum_blocking(url, None),
(Some(url), None, None) => AnyResolver::esplora_blocking(url, None),
(None, None, Some(url)) => AnyResolver::mempool_blocking(url, None),
_ => Err(s!(" - error: no transaction resolver is specified; use either \
--esplora --mempool or --electrum argument")),
}
.map_err(WalletError::Resolver)?;
resolver.check(self.general.network)?;
Ok(resolver)
}
Expand Down
11 changes: 11 additions & 0 deletions src/indexers/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,21 @@ impl AnyResolver {
})
}

#[cfg(feature = "mempool_blocking")]
pub fn mempool_blocking(url: &str, config: Option<esplora::Config>) -> Result<Self, String> {
Ok(AnyResolver {
inner: Box::new(super::mempool_blocking::MemPoolClient::new(
url,
config.unwrap_or_default(),
)?),
terminal_txes: Default::default(),
})
}
pub fn check(&self, network: Network) -> Result<(), String> {
let expected_block_hash = match network {
Network::Mainnet => "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
Network::Testnet3 => "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943",
Network::Testnet4 => "00000000da84f2bafbbc53dee25a72ae507ff4914b867c565be350b0da8bf043",
Network::Signet => "00000008819873e925422c1ff0f99f7cc9bbb232af63a077a480a3633bee1ef6",
Network::Regtest => "0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206",
}
Expand Down
1 change: 1 addition & 0 deletions src/indexers/electrum_blocking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ impl RgbResolver for Client {
let txid = match network {
Network::Mainnet => "33e794d097969002ee05d336686fc03c9e15a597c1b9827669460fac98799036",
Network::Testnet3 => "5e6560fd518aadbed67ee4a55bdc09f19e619544f5511e9343ebba66d2f62653",
Network::Testnet4 => "7aa0a7ae1e223414cb807e40cd57e667b718e42aaf9306db9102fe28912b7b4e",
Network::Signet => "8153034f45e695453250a8fb7225a5e545144071d8ed7b0d3211efa1f3c92ad8",
Network::Regtest => "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
};
Expand Down
130 changes: 130 additions & 0 deletions src/indexers/mempool_blocking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// RGB smart contracts for Bitcoin & Lightning
//
// SPDX-License-Identifier: Apache-2.0
//
// Written in 2019-2023 by
// Dr Maxim Orlovsky <orlovsky@lnp-bp.org>
//
// Copyright (C) 2019-2023 LNP/BP Standards Association. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use bp::Tx;
use bpstd::{Network, Txid};
use esplora::{BlockingClient, Config, Error};
use rgbstd::WitnessAnchor;

use super::RgbResolver;

#[derive(Clone, Debug)]
/// Represents a client for interacting with a mempool.
// Currently, this client is wrapping an `esplora::BlockingClient` instance.
// If the mempool service changes in the future and is not compatible with
// esplora::BlockingClient, Only the internal implementation needs to be
// modified
pub struct MemPoolClient {
inner: BlockingClient,
}

impl MemPoolClient {
/// Creates a new `MemPoolClient` instance.
///
/// # Arguments
///
/// * `url` - The URL of the mempool server.
/// * `config` - The configuration for the mempool client.
///
/// # Returns
///
/// Returns a `Result` containing the `MemPoolClient` instance if
/// successful, or an `Error` if an error occurred.
pub fn new(url: &str, config: Config) -> Result<Self, Error> {
let inner = BlockingClient::from_config(url, config)?;
Ok(MemPoolClient { inner })
}
}

impl RgbResolver for MemPoolClient {
fn check(&self, network: Network, expected_block_hash: String) -> Result<(), String> {
self.inner.check(network, expected_block_hash)
}

fn resolve_height(&mut self, txid: Txid) -> Result<WitnessAnchor, String> {
self.inner.resolve_height(txid)
}

fn resolve_pub_witness(&self, txid: Txid) -> Result<Tx, Option<String>> {
self.inner.resolve_pub_witness(txid)
}
}

#[cfg(test)]
mod test {
use esplora::Config;
#[test]
fn test_mempool_client_mainnet_tx() {
let client = super::MemPoolClient::new("https://mempool.space/api", Config::default())
.expect("Failed to create client");
let txid = "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
.parse()
.unwrap();
let status = client.inner.tx_status(&txid).unwrap();
assert_eq!(status.block_height, Some(0));
assert_eq!(status.block_time, Some(1231006505));
}

#[test]
fn test_mempool_client_testnet_tx() {
let client =
super::MemPoolClient::new("https://mempool.space/testnet/api", Config::default())
.expect("Failed to create client");

let txid = "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
.parse()
.unwrap();
let status = client.inner.tx_status(&txid).unwrap();
assert_eq!(status.block_height, Some(0));
assert_eq!(status.block_time, Some(1296688602));
}

#[test]
fn test_mempool_client_testnet4_tx() {
let client =
super::MemPoolClient::new("https://mempool.space/testnet4/api", Config::default())
.expect("Failed to create client");
let txid = "7aa0a7ae1e223414cb807e40cd57e667b718e42aaf9306db9102fe28912b7b4e"
.parse()
.unwrap();
let status = client.inner.tx_status(&txid).unwrap();
assert_eq!(status.block_height, Some(0));
assert_eq!(status.block_time, Some(1714777860));
}

#[test]
fn test_mempool_client_testnet4_tx_detail() {
let client =
super::MemPoolClient::new("https://mempool.space/testnet4/api", Config::default())
.expect("Failed to create client");
let txid = "7aa0a7ae1e223414cb807e40cd57e667b718e42aaf9306db9102fe28912b7b4e"
.parse()
.unwrap();
let tx = client
.inner
.tx(&txid)
.expect("Failed to get tx")
.expect("Tx not found");
assert!(tx.inputs.len() > 0);
assert!(tx.outputs.len() > 0);
assert_eq!(tx.outputs[0].value, 5_000_000_000);
}
}
3 changes: 3 additions & 0 deletions src/indexers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,7 @@ pub mod esplora_blocking;
#[cfg(feature = "electrum_blocking")]
pub mod electrum_blocking;

#[cfg(feature = "mempool_blocking")]
pub mod mempool_blocking;

pub use any::{AnyResolver, RgbResolver};

0 comments on commit 8647dd4

Please sign in to comment.