Skip to content

Commit

Permalink
More code review
Browse files Browse the repository at this point in the history
- Descriptor has "body" and "checksum" attributes
- Forgot a /* turning bare xpubs into descriptors
- Removed unnecessary clones
- Rename "hd" -> "wallet" in a few more places
  • Loading branch information
justinmoon committed Jun 26, 2020
1 parent 01729c7 commit d9a689b
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 44 deletions.
27 changes: 13 additions & 14 deletions src/hd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl HDWatcher {
HDWatcher {
wallets: wallets
.into_iter()
.map(|wallet| (wallet.descriptor.checksum(), wallet))
.map(|wallet| (wallet.descriptor.checksum.clone(), wallet))
.collect(),
}
}
Expand Down Expand Up @@ -198,8 +198,7 @@ impl HDWallet {
*rescan,
rpc.clone(),
)
.with_context(|| format!("invalid descriptor {}", descriptor))?
.clone(),
.with_context(|| format!("invalid descriptor {}", descriptor))?,
);
}

Expand Down Expand Up @@ -227,18 +226,19 @@ impl HDWallet {
*rescan,
rpc.clone(),
)
.with_context(|| format!("Invalid xpub-derived descriptor {}", descriptor))?
.clone(),
.with_context(|| format!("Invalid xpub-derived descriptor {}", descriptor))?,
);
}
}

// Bare xpubs
for (xyz, rescan) in bare_xpubs {
let descriptor = match xyz.script_type {
ScriptType::P2pkh => format!("pkh({})", xyz.extended_pubkey.to_string()),
ScriptType::P2wpkh => format!("wpkh({})", xyz.extended_pubkey.to_string()),
ScriptType::P2shP2wpkh => format!("sh(wpkh({}))", xyz.extended_pubkey.to_string()),
ScriptType::P2pkh => format!("pkh({})/*", xyz.extended_pubkey.to_string()),
ScriptType::P2wpkh => format!("wpkh({}/*)", xyz.extended_pubkey.to_string()),
ScriptType::P2shP2wpkh => {
format!("sh(wpkh({}/*))", xyz.extended_pubkey.to_string())
}
};
wallets.push(
Self::from_descriptor(
Expand All @@ -249,8 +249,7 @@ impl HDWallet {
*rescan,
rpc.clone(),
)
.with_context(|| format!("Invalid bare-xpub-derived descriptor {}", descriptor))?
.clone(),
.with_context(|| format!("Invalid bare-xpub-derived descriptor {}", descriptor))?,
);
}

Expand Down Expand Up @@ -305,14 +304,14 @@ impl HDWallet {

(start_index..=end_index)
.map(|index| {
let label = KeyOrigin::Derived(self.descriptor.checksum(), index).to_label();
let label = KeyOrigin::Derived(self.descriptor.checksum.clone(), index).to_label();
(self.descriptor.clone(), index, label, rescan_since)
})
.collect()
}

pub fn derive_address(&self, index: u32, rpc: &RpcClient) -> Result<Address> {
let res = rpc.derive_addresses(&self.descriptor.0, Some([index, index]))?;
let res = rpc.derive_addresses(&self.descriptor.to_string(), Some([index, index]))?;
Ok(res[0].to_owned())
}

Expand All @@ -334,7 +333,7 @@ fn batch_import(
watchonly: Some(true),
timestamp: *rescan_since,
range: Some((*index as usize, *index as usize)),
descriptor: Some(&descriptor.0),
descriptor: Some(&descriptor.to_string()),
..Default::default()
},
)
Expand Down Expand Up @@ -489,7 +488,7 @@ impl Serialize for HDWallet {
S: serde::Serializer,
{
let mut rgb = serializer.serialize_struct("HDWallet", 3)?;
rgb.serialize_field("descriptor", &self.descriptor.0)?;
rgb.serialize_field("descriptor", &self.descriptor.body)?;
rgb.serialize_field("network", &self.network)?;
rgb.serialize_field("gap_limit", &self.gap_limit)?;
rgb.serialize_field("initial_import_size", &self.initial_import_size)?;
Expand Down
30 changes: 16 additions & 14 deletions src/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ async fn run(
);
}

// GET /hd
// GET /wallet
let hd_wallets_handler = warp::get()
.and(warp::path!("wallet"))
.and(query.clone())
Expand All @@ -49,17 +49,19 @@ async fn run(
reply::json(&wallets)
});

// GET /hd/:fingerprint
// GET /wallet/:fingerprint
let hd_wallet_handler = warp::get()
.and(warp::path!("wallet" / DescrChecksum))
.and(query.clone())
.map(|descr_cs: DescrChecksum, query: Arc<Query>| {
let wallet = query.get_hd_wallet(descr_cs).or_err(StatusCode::NOT_FOUND)?;
let wallet = query
.get_hd_wallet(descr_cs)
.or_err(StatusCode::NOT_FOUND)?;
Ok(reply::json(&wallet))
})
.map(handle_error);

// GET /hd/:fingerprint/:index
// GET /wallet/:fingerprint/:index
let hd_key_handler = warp::get()
.and(warp::path!("wallet" / DescrChecksum / u32))
.and(query.clone())
Expand All @@ -71,7 +73,7 @@ async fn run(
})
.map(handle_error);

// GET /hd/:fingerprint/gap
// GET /wallet/:fingerprint/gap
let hd_gap_handler = warp::get()
.and(warp::path!("wallet" / DescrChecksum / "gap"))
.and(query.clone())
Expand All @@ -81,7 +83,7 @@ async fn run(
})
.map(handle_error);

// GET /hd/:fingerprint/next
// GET /wallet/:fingerprint/next
let hd_next_handler = warp::get()
.and(warp::path!("wallet" / DescrChecksum / "next"))
.and(query.clone())
Expand All @@ -90,7 +92,7 @@ async fn run(
.get_hd_wallet(descr_cs.clone())
.or_err(StatusCode::NOT_FOUND)?;
let next_index = wallet.get_next_index();
let uri = format!("/hd/{}/{}", descr_cs, next_index);
let uri = format!("/wallet/{}/{}", descr_cs, next_index);
// issue a 307 redirect to the hdkey resource uri, and also include the derivation
// index in the response
Ok(reply::with_header(
Expand All @@ -108,7 +110,7 @@ async fn run(
let address_route = warp::path!("address" / Address / ..).map(ScriptHash::from);
// TODO check address version bytes matches the configured network

// GET /hd/:fingerprint/:index/*
// GET /wallet/:fingerprint/:index/*
let hd_key_route = warp::path!("wallet" / DescrChecksum / u32 / ..)
.and(query.clone())
.map(|descr_cs: DescrChecksum, index: u32, query: Arc<Query>| {
Expand All @@ -125,7 +127,7 @@ async fn run(
.or(hd_key_route)
.unify();

// GET /hd/:fingerprint/:index
// GET /wallet/:fingerprint/:index
// GET /address/:address
// GET /scripthash/:scripthash
let spk_handler = warp::get()
Expand All @@ -140,7 +142,7 @@ async fn run(
})
.map(handle_error);

// GET /hd/:fingerprint/:index/stats
// GET /wallet/:fingerprint/:index/stats
// GET /address/:address/stats
// GET /scripthash/:scripthash/stats
let spk_stats_handler = warp::get()
Expand All @@ -155,7 +157,7 @@ async fn run(
})
.map(handle_error);

// GET /hd/:fingerprint/:index/utxos
// GET /wallet/:fingerprint/:index/utxos
// GET /address/:address/utxos
// GET /scripthash/:scripthash/utxos
let spk_utxo_handler = warp::get()
Expand All @@ -170,7 +172,7 @@ async fn run(
})
.map(handle_error);

// GET /hd/:fingerprint/:index/txs
// GET /wallet/:fingerprint/:index/txs
// GET /address/:address/txs
// GET /scripthash/:scripthash/txs
let spk_txs_handler = warp::get()
Expand All @@ -185,7 +187,7 @@ async fn run(
})
.map(handle_error);

// GET /hd/:fingerprint/:index/txs/compact
// GET /wallet/:fingerprint/:index/txs/compact
// GET /address/:address/txs/compact
// GET /scripthash/:scripthash/txs/compact
let spk_txs_compact_handler = warp::get()
Expand Down Expand Up @@ -312,7 +314,7 @@ async fn run(
)
.map(handle_error);

// GET /hd/:fingerprint/:index/stream
// GET /wallet/:fingerprint/:index/stream
// GET /scripthash/:scripthash/stream
// GET /address/:address/stream
let spk_sse_handler = warp::get()
Expand Down
7 changes: 6 additions & 1 deletion src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,12 @@ impl Query {
}

pub fn get_hd_wallet(&self, descr_cs: DescrChecksum) -> Option<HDWallet> {
self.indexer.read().unwrap().watcher().get(descr_cs).cloned()
self.indexer
.read()
.unwrap()
.watcher()
.get(descr_cs)
.cloned()
}

// get the ScriptInfo entry of a derived hd key, without it necessarily being indexed
Expand Down
28 changes: 13 additions & 15 deletions src/types.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::cmp::Ordering;
use std::fmt;
use std::str::FromStr;
use std::sync::Arc;

Expand Down Expand Up @@ -186,7 +185,7 @@ impl From<GetMempoolEntryResult> for MempoolEntry {
}
}

#[derive(Serialize, Clone, Eq, PartialEq, Debug, Hash)]
#[derive(Clone, Eq, PartialEq, Debug, Hash)]
pub struct DescrChecksum(pub String);

impl FromStr for DescrChecksum {
Expand All @@ -196,24 +195,23 @@ impl FromStr for DescrChecksum {
}
}

impl_string_serializer!(DescrChecksum, descr_cs, descr_cs.0);

/// A *ranged* output script descriptor
#[derive(Serialize, Clone, Eq, PartialEq, Debug, Hash)]
pub struct Descriptor(pub String);
#[derive(Clone, Eq, PartialEq, Debug, Hash)]
pub struct Descriptor {
pub body: String,
pub checksum: DescrChecksum,
}

impl Descriptor {
pub fn new(descriptor: &str, rpc: Arc<RpcClient>) -> Result<Self, BwtError> {
let info = rpc.get_descriptor_info(descriptor)?;
Ok(Self(info.descriptor))
}

pub fn checksum(&self) -> DescrChecksum {
// This assumes that the descriptor is valid ...
DescrChecksum(self.0.split("#").collect::<Vec<_>>()[1].to_string())
Ok(Self {
body: info.descriptor,
checksum: DescrChecksum(info.checksum),
})
}
}

impl fmt::Display for DescrChecksum {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl_string_serializer!(Descriptor, desc, format!("{}#{}", desc.body, desc.checksum));

0 comments on commit d9a689b

Please sign in to comment.