Skip to content

Commit

Permalink
Add support for contract id alias and key name to `stellar snapshot c…
Browse files Browse the repository at this point in the history
…reate`. (#1662)
  • Loading branch information
fnando authored Oct 10, 2024
1 parent 9880ad6 commit 18fd1ff
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 11 deletions.
6 changes: 4 additions & 2 deletions FULL_HELP_DOCS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1249,18 +1249,20 @@ Create a ledger snapshot using a history archive.

Filters (address, wasm-hash) specify what ledger entries to include.

Account addresses include the account, and trust lines.
Account addresses include the account, and trustlines.

Contract addresses include the related wasm, contract data.

If a contract is a Stellar asset contract, it includes the asset issuer's account and trust lines, but does not include all the trust lines of other accounts holding the asset. To include them specify the addresses of relevant accounts.

Any invalid contract id passed as `--address` will be ignored.

**Usage:** `stellar snapshot create [OPTIONS] --output <OUTPUT>`

###### **Options:**

* `--ledger <LEDGER>` — The ledger sequence number to snapshot. Defaults to latest history archived ledger
* `--address <ADDRESS>` — Account or contract address to include in the snapshot
* `--address <ADDRESS>` — Account or contract address/alias to include in the snapshot
* `--wasm-hash <WASM_HASHES>` — WASM hashes to include in the snapshot
* `--output <OUTPUT>` — Format of the out file

Expand Down
61 changes: 52 additions & 9 deletions cmd/soroban-cli/src/commands/snapshot/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ use tokio::io::BufReader;
use tokio_util::io::StreamReader;
use url::Url;

use crate::utils::http;
use crate::{
commands::{config::data, global, HEADING_RPC},
config::{self, locator, network::passphrase},
print,
tx::builder,
utils::get_name_from_stellar_asset_contract_storage,
};
use crate::{config::address::Address, utils::http};

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, ValueEnum)]
pub enum Output {
Expand All @@ -55,24 +55,27 @@ fn default_out_path() -> PathBuf {
///
/// Filters (address, wasm-hash) specify what ledger entries to include.
///
/// Account addresses include the account, and trust lines.
/// Account addresses include the account, and trustlines.
///
/// Contract addresses include the related wasm, contract data.
///
/// If a contract is a Stellar asset contract, it includes the asset issuer's
/// account and trust lines, but does not include all the trust lines of other
/// accounts holding the asset. To include them specify the addresses of
/// relevant accounts.
///
/// Any invalid contract id passed as `--address` will be ignored.
///
#[derive(Parser, Debug, Clone)]
#[group(skip)]
#[command(arg_required_else_help = true)]
pub struct Cmd {
/// The ledger sequence number to snapshot. Defaults to latest history archived ledger.
#[arg(long)]
ledger: Option<u32>,
/// Account or contract address to include in the snapshot.
/// Account or contract address/alias to include in the snapshot.
#[arg(long = "address", help_heading = "Filter Options")]
address: Vec<ScAddress>,
address: Vec<String>,
/// WASM hashes to include in the snapshot.
#[arg(long = "wasm-hash", help_heading = "Filter Options")]
wasm_hashes: Vec<Hash>,
Expand Down Expand Up @@ -213,11 +216,13 @@ impl Cmd {
}

// Search the buckets using the user inputs as the starting inputs.
let (account_ids, contract_ids): (HashSet<AccountId>, HashSet<ScAddress>) =
self.address.iter().cloned().partition_map(|a| match a {
ScAddress::Account(account_id) => Either::Left(account_id),
ScAddress::Contract(_) => Either::Right(a),
});
let (account_ids, contract_ids): (HashSet<AccountId>, HashSet<ScAddress>) = self
.address
.iter()
.cloned()
.filter_map(|a| self.resolve_address(&a, network_passphrase))
.partition_map(|a| a);

let mut current = SearchInputs {
account_ids,
contract_ids,
Expand Down Expand Up @@ -388,6 +393,44 @@ impl Cmd {
})
.ok_or(Error::ArchiveUrlNotConfigured)
}

fn resolve_address(
&self,
address: &str,
network_passphrase: &str,
) -> Option<Either<AccountId, ScAddress>> {
self.resolve_contract(address, network_passphrase)
.map(Either::Right)
.or_else(|| self.resolve_account(address).map(Either::Left))
}

// Resolve an account address to an account id. The address can be a
// G-address or a key name (as in `stellar keys address NAME`).
fn resolve_account(&self, address: &str) -> Option<AccountId> {
let address: Address = address.parse().ok()?;

Some(AccountId(xdr::PublicKey::PublicKeyTypeEd25519(
match address.resolve_muxed_account(&self.locator, None).ok()? {
xdr::MuxedAccount::Ed25519(uint256) => uint256,
xdr::MuxedAccount::MuxedEd25519(xdr::MuxedAccountMed25519 { ed25519, .. }) => {
ed25519
}
},
)))
}
// Resolve a contract address to a contract id. The contract can be a
// C-address or a contract alias.
fn resolve_contract(&self, address: &str, network_passphrase: &str) -> Option<ScAddress> {
address.parse().ok().or_else(|| {
Some(ScAddress::Contract(
self.locator
.resolve_contract_id(address, network_passphrase)
.ok()?
.0
.into(),
))
})
}
}

async fn get_history(
Expand Down

0 comments on commit 18fd1ff

Please sign in to comment.