Skip to content

Commit

Permalink
Automatically load wallet (ordinals#1210)
Browse files Browse the repository at this point in the history
  • Loading branch information
raphjaph authored Jan 16, 2023
1 parent 782605e commit 63e7eb3
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 24 deletions.
2 changes: 1 addition & 1 deletion src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ impl<T> BitcoinCoreRpcResultExt<T> for Result<T, bitcoincore_rpc::Error> {

impl Index {
pub(crate) fn open(options: &Options) -> Result<Self> {
let rpc_url = options.rpc_url(false);
let rpc_url = options.rpc_url();
let cookie_file = options.cookie_file()?;

log::info!(
Expand Down
37 changes: 19 additions & 18 deletions src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,14 @@ impl Options {
}
}

pub(crate) fn rpc_url(&self, with_wallet: bool) -> String {
let mut rpc_url = self
.rpc_url
.clone()
.unwrap_or_else(|| format!("127.0.0.1:{}", self.chain().default_rpc_port()));

if with_wallet {
rpc_url.push_str(&format!("/wallet/{}", self.wallet));
}

rpc_url.to_string()
pub(crate) fn rpc_url(&self) -> String {
self.rpc_url.clone().unwrap_or_else(|| {
format!(
"127.0.0.1:{}/wallet/{}",
self.chain().default_rpc_port(),
self.wallet
)
})
}

pub(crate) fn cookie_file(&self) -> Result<PathBuf> {
Expand Down Expand Up @@ -123,10 +120,10 @@ impl Options {
)
}

pub(crate) fn bitcoin_rpc_client(&self, with_wallet: bool) -> Result<Client> {
pub(crate) fn bitcoin_rpc_client(&self) -> Result<Client> {
let cookie_file = self.cookie_file()?;

let rpc_url = self.rpc_url(with_wallet);
let rpc_url = self.rpc_url();

log::info!(
"Connecting to Bitcoin Core RPC server at {rpc_url} using credentials from `{}`",
Expand Down Expand Up @@ -154,7 +151,7 @@ impl Options {
}

pub(crate) fn bitcoin_rpc_client_for_wallet_command(&self, create: bool) -> Result<Client> {
let client = self.bitcoin_rpc_client(true)?;
let client = self.bitcoin_rpc_client()?;

const MIN_VERSION: usize = 240000;

Expand All @@ -168,6 +165,10 @@ impl Options {
}

if !create {
if !client.list_wallets()?.contains(&self.wallet) {
client.load_wallet(&self.wallet)?;
}

let descriptors = client.list_descriptors(None)?.descriptors;

let tr = descriptors
Expand Down Expand Up @@ -199,7 +200,7 @@ mod tests {
Arguments::try_parse_from(["ord", "--rpc-url=127.0.0.1:1234", "--chain=signet", "index"])
.unwrap()
.options
.rpc_url(false),
.rpc_url(),
"127.0.0.1:1234"
);
}
Expand All @@ -220,7 +221,7 @@ mod tests {
fn use_default_network() {
let arguments = Arguments::try_parse_from(["ord", "index"]).unwrap();

assert_eq!(arguments.options.rpc_url(false), "127.0.0.1:8332");
assert_eq!(arguments.options.rpc_url(), "127.0.0.1:8332/wallet/ord");

assert!(arguments
.options
Expand All @@ -233,7 +234,7 @@ mod tests {
fn uses_network_defaults() {
let arguments = Arguments::try_parse_from(["ord", "--chain=signet", "index"]).unwrap();

assert_eq!(arguments.options.rpc_url(false), "127.0.0.1:38332");
assert_eq!(arguments.options.rpc_url(), "127.0.0.1:38332/wallet/ord");

assert!(arguments
.options
Expand Down Expand Up @@ -432,7 +433,7 @@ mod tests {
.unwrap();

assert_eq!(
options.bitcoin_rpc_client(false).unwrap_err().to_string(),
options.bitcoin_rpc_client().unwrap_err().to_string(),
"Bitcoin RPC server is on testnet but ord is on mainnet"
);
}
Expand Down
12 changes: 8 additions & 4 deletions src/subcommand/preview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ struct KillOnDrop(process::Child);

impl Drop for KillOnDrop {
fn drop(&mut self) {
self.0.kill().unwrap()
Command::new("kill")
.arg("-SIGINT")
.arg(self.0.id().to_string())
.spawn()
.expect("failed to SIGINT kill process");
}
}

Expand Down Expand Up @@ -50,7 +54,7 @@ impl Preview {
};

for attempt in 0.. {
if options.bitcoin_rpc_client(false).is_ok() {
if options.bitcoin_rpc_client().is_ok() {
break;
}

Expand All @@ -61,10 +65,10 @@ impl Preview {
thread::sleep(Duration::from_millis(50));
}

let rpc_client = options.bitcoin_rpc_client(false)?;

super::wallet::create::run(options.clone())?;

let rpc_client = options.bitcoin_rpc_client_for_wallet_command(false)?;

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

Expand Down
6 changes: 6 additions & 0 deletions test-bitcoincore-rpc/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,4 +145,10 @@ pub trait Api {

#[rpc(name = "listdescriptors")]
fn list_descriptors(&self) -> Result<ListDescriptorsResult, jsonrpc_core::Error>;

#[rpc(name = "loadwallet")]
fn load_wallet(&self, wallet: String) -> Result<LoadWalletResult, jsonrpc_core::Error>;

#[rpc(name = "listwallets")]
fn list_wallets(&self) -> Result<Vec<String>, jsonrpc_core::Error>;
}
4 changes: 4 additions & 0 deletions test-bitcoincore-rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,10 @@ impl Handle {
Network::Regtest => Network::Regtest.to_string(),
}
}

pub fn loaded_wallets(&self) -> BTreeSet<String> {
self.state().loaded_wallets.clone()
}
}

impl Drop for Handle {
Expand Down
23 changes: 23 additions & 0 deletions test-bitcoincore-rpc/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,4 +562,27 @@ impl Api for Server {
.collect(),
})
}

fn load_wallet(&self, wallet: String) -> Result<LoadWalletResult, jsonrpc_core::Error> {
if self.state().wallets.contains(&wallet) {
self.state().loaded_wallets.insert(wallet.clone());
Ok(LoadWalletResult {
name: wallet,
warning: None,
})
} else {
Err(Self::not_found())
}
}

fn list_wallets(&self) -> Result<Vec<String>, jsonrpc_core::Error> {
Ok(
self
.state()
.loaded_wallets
.clone()
.into_iter()
.collect::<Vec<String>>(),
)
}
}
2 changes: 2 additions & 0 deletions test-bitcoincore-rpc/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub(crate) struct State {
pub(crate) version: usize,
pub(crate) wallet_name: String,
pub(crate) wallets: BTreeSet<String>,
pub(crate) loaded_wallets: BTreeSet<String>,
}

impl State {
Expand Down Expand Up @@ -47,6 +48,7 @@ impl State {
version,
wallet_name: wallet_name.to_string(),
wallets: BTreeSet::new(),
loaded_wallets: BTreeSet::new(),
}
}

Expand Down
6 changes: 5 additions & 1 deletion tests/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ struct KillOnDrop(std::process::Child);

impl Drop for KillOnDrop {
fn drop(&mut self) {
self.0.kill().unwrap()
Command::new("kill")
.arg("-SIGINT")
.arg(self.0.id().to_string())
.spawn()
.expect("failed to SIGINT kill process");
}
}

Expand Down
5 changes: 5 additions & 0 deletions tests/wallet/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@ fn transactions() {
let rpc_server = test_bitcoincore_rpc::spawn();
create_wallet(&rpc_server);

assert!(rpc_server.loaded_wallets().is_empty());

CommandBuilder::new("wallet transactions")
.rpc_server(&rpc_server)
.run();

assert_eq!(rpc_server.loaded_wallets().len(), 1);
assert_eq!(rpc_server.loaded_wallets().first().unwrap(), "ord");

rpc_server.mine_blocks(1);

CommandBuilder::new("wallet transactions")
Expand Down

0 comments on commit 63e7eb3

Please sign in to comment.