diff --git a/src/bin/rgb/command.rs b/src/bin/rgb/command.rs index d484786..65a8c8b 100644 --- a/src/bin/rgb/command.rs +++ b/src/bin/rgb/command.rs @@ -27,7 +27,7 @@ use amplify::confinement::U16; use bitcoin::bip32::ExtendedPubKey; use bitcoin::psbt::Psbt; use bp::seals::txout::{CloseMethod, ExplicitSeal, TxPtr}; -use rgb::{Runtime, RuntimeError}; +use rgb::{BlockchainResolver, Runtime, RuntimeError}; use rgbstd::containers::{Bindle, Transfer, UniversalBindle}; use rgbstd::contract::{ContractId, GenesisSeal, GraphSeal, StateType}; use rgbstd::interface::{ContractBuilder, SchemaIfaces, TypedState}; @@ -224,7 +224,11 @@ pub enum Command { } impl Command { - pub fn exec(self, runtime: &mut Runtime) -> Result<(), RuntimeError> { + pub fn exec( + self, + runtime: &mut Runtime, + resolver: &mut BlockchainResolver, + ) -> Result<(), RuntimeError> { match self { Command::Schemata => { for id in runtime.schema_ids()? { @@ -301,14 +305,10 @@ impl Command { } UniversalBindle::Contract(bindle) => { let id = bindle.id(); - let contract = - bindle - .unbindle() - .validate(runtime.resolver()) - .map_err(|c| { - c.validation_status().expect("just validated").to_string() - })?; - runtime.import_contract(contract)?; + let contract = bindle.unbindle().validate(resolver).map_err(|c| { + c.validation_status().expect("just validated").to_string() + })?; + runtime.import_contract(contract, resolver)?; eprintln!("Contract {id} imported to the stash"); } UniversalBindle::Transfer(_) => { @@ -341,7 +341,13 @@ impl Command { contract_id, iface, } => { - let wallet = wallet.map(|w| runtime.wallet(&w)).transpose()?; + let wallet = wallet + .map(|w| -> Result<_, RuntimeError> { + let mut wallet = runtime.wallet(&w)?; + wallet.update(resolver)?; + Ok(wallet) + }) + .transpose()?; let iface = runtime.iface_by_name(&tn!(iface))?.clone(); let contract = runtime.contract_iface(contract_id, iface.iface_id())?; @@ -516,10 +522,10 @@ impl Command { let contract = builder.issue_contract().expect("failure issuing contract"); let id = contract.contract_id(); let validated_contract = contract - .validate(runtime.resolver()) + .validate(resolver) .map_err(|_| RuntimeError::IncompleteContract)?; runtime - .import_contract(validated_contract) + .import_contract(validated_contract, resolver) .expect("failure importing issued contract"); eprintln!( "A new contract {id} is issued and added to the stash.\nUse `export` command \ @@ -681,7 +687,7 @@ impl Command { } Command::Validate { file } => { let bindle = Bindle::::load(file)?; - let status = match bindle.unbindle().validate(runtime.resolver()) { + let status = match bindle.unbindle().validate(resolver) { Ok(consignment) => consignment.into_validation_status(), Err(consignment) => consignment.into_validation_status(), } @@ -690,12 +696,9 @@ impl Command { } Command::Accept { force, file } => { let bindle = Bindle::::load(file)?; - let transfer = bindle - .unbindle() - .validate(runtime.resolver()) - .unwrap_or_else(|c| c); + let transfer = bindle.unbindle().validate(resolver).unwrap_or_else(|c| c); eprintln!("{}", transfer.validation_status().expect("just validated")); - runtime.accept_transfer(transfer, force)?; + runtime.accept_transfer(transfer, resolver, force)?; eprintln!("Transfer accepted into the stash"); } Command::SetHost { method, psbt_file } => { diff --git a/src/bin/rgb/main.rs b/src/bin/rgb/main.rs index 39cb96f..697987a 100644 --- a/src/bin/rgb/main.rs +++ b/src/bin/rgb/main.rs @@ -35,7 +35,7 @@ mod command; use std::process::ExitCode; use clap::Parser; -use rgb::{DefaultResolver, Runtime, RuntimeError}; +use rgb::{BlockchainResolver, DefaultResolver, Runtime, RuntimeError}; pub use crate::command::Command; pub use crate::loglevel::LogLevel; @@ -73,8 +73,9 @@ fn run() -> Result<(), RuntimeError> { .electrum .unwrap_or_else(|| opts.chain.default_resolver()); - let mut runtime = Runtime::load(opts.data_dir.clone(), opts.chain, &electrum)?; + let mut resolver = BlockchainResolver::with(&electrum)?; + let mut runtime = Runtime::load(opts.data_dir.clone(), opts.chain)?; debug!("Executing command: {}", opts.command); - opts.command.exec(&mut runtime)?; + opts.command.exec(&mut runtime, &mut resolver)?; Ok(()) } diff --git a/src/runtime.rs b/src/runtime.rs index 59f2686..ec333b2 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -104,8 +104,6 @@ pub struct Runtime { wallets: HashMap, #[getter(as_copy)] chain: Chain, - #[getter(skip)] - resolver: BlockchainResolver, } impl Deref for Runtime { @@ -118,7 +116,7 @@ impl DerefMut for Runtime { } impl Runtime { - pub fn load(mut data_dir: PathBuf, chain: Chain, electrum: &str) -> Result { + pub fn load(mut data_dir: PathBuf, chain: Chain) -> Result { data_dir.push(chain.to_string()); debug!("Using data directory '{}'", data_dir.display()); fs::create_dir_all(&data_dir)?; @@ -146,22 +144,17 @@ impl Runtime { serde_yaml::from_reader(&wallets_fd)? }; - let resolver = BlockchainResolver::with(electrum)?; - Ok(Self { stock_path, wallets_path, stock, wallets, chain, - resolver, }) } pub fn unload(self) -> () {} - pub fn resolver(&mut self) -> &mut BlockchainResolver { &mut self.resolver } - pub fn create_wallet( &mut self, name: &Ident, @@ -183,26 +176,26 @@ impl Runtime { .wallets .get(name) .ok_or(RuntimeError::WalletUnknown(name.clone()))?; - let mut wallet = RgbWallet::new(descr.clone()); - wallet.update(&mut self.resolver)?; - Ok(wallet) + Ok(RgbWallet::new(descr.clone())) } pub fn import_contract( &mut self, contract: Contract, + resolver: &mut BlockchainResolver, ) -> Result { self.stock - .import_contract(contract, &mut self.resolver) + .import_contract(contract, resolver) .map_err(RuntimeError::from) } pub fn validate_transfer<'transfer>( &mut self, transfer: Transfer, + resolver: &mut BlockchainResolver, ) -> Result { transfer - .validate(&mut self.resolver) + .validate(resolver) .map_err(|invalid| invalid.validation_status().expect("just validated").clone()) .map_err(RuntimeError::from) } @@ -210,10 +203,11 @@ impl Runtime { pub fn accept_transfer( &mut self, transfer: Transfer, + resolver: &mut BlockchainResolver, force: bool, ) -> Result { self.stock - .accept_transfer(transfer, &mut self.resolver, force) + .accept_transfer(transfer, resolver, force) .map_err(RuntimeError::from) } }