Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 58b808602a | |||
| 85030069f1 | |||
| df512d6d3a | |||
| e30576eed3 | |||
| 9f9639950b | |||
| 111a0b20b6 |
@@ -151,7 +151,7 @@ pub async fn gateways_for_init(
|
||||
}
|
||||
|
||||
let retry_count = retry_count.unwrap_or(DEFAULT_NYM_API_RETRIES);
|
||||
let mut builder = nym_http_api_client::ClientBuilder::new_with_urls(nym_api_urls.clone())
|
||||
let mut builder = nym_http_api_client::ClientBuilder::new_with_urls(nym_api_urls.clone())?
|
||||
.with_retries(retry_count)
|
||||
.with_bincode();
|
||||
|
||||
|
||||
@@ -84,6 +84,10 @@ pub enum ExecuteMsg {
|
||||
UpdateAnnounceAddress {
|
||||
new_address: String,
|
||||
},
|
||||
|
||||
FixOldShare {
|
||||
old_owner: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[cw_serde]
|
||||
|
||||
@@ -296,6 +296,9 @@ impl std::error::Error for ReqwestErrorWrapper {}
|
||||
#[derive(Debug, Error)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum HttpClientError {
|
||||
#[error("did not provide any valid client URLs")]
|
||||
NoUrlsProvided,
|
||||
|
||||
#[error("failed to construct inner reqwest client: {source}")]
|
||||
ReqwestBuildError {
|
||||
#[source]
|
||||
@@ -582,24 +585,29 @@ impl ClientBuilder {
|
||||
Self::new(alt)
|
||||
} else {
|
||||
let url = url.to_url()?;
|
||||
Ok(Self::new_with_urls(vec![url]))
|
||||
Self::new_with_urls(vec![url])
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a client builder from network details with sensible defaults
|
||||
#[cfg(feature = "network-defaults")]
|
||||
// deprecating function since it's not clear from its signature whether the client
|
||||
// would be constructed using `nym_api_urls` or `nym_vpn_api_urls`
|
||||
#[deprecated(note = "use explicit Self::new_with_fronted_urls instead")]
|
||||
pub fn from_network(
|
||||
network: &nym_network_defaults::NymNetworkDetails,
|
||||
) -> Result<Self, HttpClientError> {
|
||||
let urls = network
|
||||
.nym_api_urls
|
||||
.as_ref()
|
||||
.ok_or_else(|| {
|
||||
HttpClientError::GenericRequestFailure(
|
||||
"No API URLs configured in network details".to_string(),
|
||||
)
|
||||
})?
|
||||
.iter()
|
||||
let urls = network.nym_api_urls.as_ref().cloned().unwrap_or_default();
|
||||
Self::new_with_fronted_urls(urls.clone())
|
||||
}
|
||||
|
||||
/// Create a client builder using the provided set of domain-fronted URLs
|
||||
#[cfg(feature = "network-defaults")]
|
||||
pub fn new_with_fronted_urls(
|
||||
urls: Vec<nym_network_defaults::ApiUrl>,
|
||||
) -> Result<Self, HttpClientError> {
|
||||
let urls = urls
|
||||
.into_iter()
|
||||
.map(|api_url| {
|
||||
// Convert ApiUrl to our Url type with fronting support
|
||||
let mut url = Url::parse(&api_url.url)?;
|
||||
@@ -611,15 +619,19 @@ impl ClientBuilder {
|
||||
.iter()
|
||||
.map(|host| format!("https://{}", host))
|
||||
.collect();
|
||||
url = Url::new(api_url.url.clone(), Some(fronts))
|
||||
.map_err(|e| HttpClientError::GenericRequestFailure(e.to_string()))?;
|
||||
url = Url::new(api_url.url.clone(), Some(fronts)).map_err(|source| {
|
||||
HttpClientError::MalformedUrl {
|
||||
raw: api_url.url.clone(),
|
||||
source,
|
||||
}
|
||||
})?;
|
||||
}
|
||||
|
||||
Ok(url)
|
||||
})
|
||||
.collect::<Result<Vec<_>, HttpClientError>>()?;
|
||||
|
||||
let mut builder = Self::new_with_urls(urls);
|
||||
let mut builder = Self::new_with_urls(urls)?;
|
||||
|
||||
// Enable domain fronting by default (on retry)
|
||||
#[cfg(feature = "tunneling")]
|
||||
@@ -631,7 +643,11 @@ impl ClientBuilder {
|
||||
}
|
||||
|
||||
/// Constructs a new http `ClientBuilder` from a valid url.
|
||||
pub fn new_with_urls(urls: Vec<Url>) -> Self {
|
||||
pub fn new_with_urls(urls: Vec<Url>) -> Result<Self, HttpClientError> {
|
||||
if urls.is_empty() {
|
||||
return Err(HttpClientError::NoUrlsProvided);
|
||||
}
|
||||
|
||||
let urls = Self::check_urls(urls);
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
@@ -640,7 +656,7 @@ impl ClientBuilder {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
let reqwest_client_builder = default_builder();
|
||||
|
||||
ClientBuilder {
|
||||
Ok(ClientBuilder {
|
||||
urls,
|
||||
timeout: None,
|
||||
custom_user_agent: false,
|
||||
@@ -651,7 +667,7 @@ impl ClientBuilder {
|
||||
|
||||
retry_limit: 0,
|
||||
serialization: SerializationFormat::Json,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Add an additional URL to the set usable by this constructed `Client`
|
||||
|
||||
@@ -21,6 +21,10 @@ inventory::collect!(ConfigRecord);
|
||||
/// Returns the default builder with all registered configurations applied.
|
||||
pub fn default_builder() -> ReqwestClientBuilder {
|
||||
let mut b = ReqwestClientBuilder::new();
|
||||
|
||||
#[cfg(feature = "debug-inventory")]
|
||||
let mut test_client = ReqwestClientBuilder::new();
|
||||
|
||||
let mut records: Vec<&'static ConfigRecord> =
|
||||
inventory::iter::<ConfigRecord>.into_iter().collect();
|
||||
records.sort_by_key(|r| r.priority); // lower runs first
|
||||
@@ -35,6 +39,10 @@ pub fn default_builder() -> ReqwestClientBuilder {
|
||||
|
||||
for r in records {
|
||||
b = (r.apply)(b);
|
||||
#[cfg(feature = "debug-inventory")]
|
||||
{
|
||||
test_client = (r.apply)(test_client);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "debug-inventory")]
|
||||
@@ -47,7 +55,7 @@ pub fn default_builder() -> ReqwestClientBuilder {
|
||||
eprintln!("[HTTP-INVENTORY] Building test client to verify configuration...");
|
||||
|
||||
// Try to build a client to see if it works
|
||||
match b.try_clone().unwrap().build() {
|
||||
match test_client.build() {
|
||||
Ok(client) => {
|
||||
eprintln!("[HTTP-INVENTORY] ✓ Client built successfully");
|
||||
eprintln!("[HTTP-INVENTORY] Client debug info: {:#?}", client);
|
||||
|
||||
@@ -93,7 +93,7 @@ async fn api_client_retry() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let client = ClientBuilder::new_with_urls(vec![
|
||||
"http://broken.nym.badurl".parse()?,
|
||||
"http://example.com/".parse()?,
|
||||
])
|
||||
])?
|
||||
.with_retries(3)
|
||||
.build()?;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::dealers::queries::{
|
||||
query_epoch_dealers_addresses_paged, query_epoch_dealers_paged,
|
||||
query_registered_dealer_details,
|
||||
};
|
||||
use crate::dealers::storage::{ensure_dealer, EPOCH_DEALERS_MAP};
|
||||
use crate::dealers::transactions::{
|
||||
try_add_dealer, try_transfer_ownership, try_update_announce_address,
|
||||
};
|
||||
@@ -18,14 +19,16 @@ use crate::epoch_state::queries::{
|
||||
query_can_advance_state, query_current_epoch, query_current_epoch_threshold,
|
||||
query_epoch_at_height, query_epoch_threshold,
|
||||
};
|
||||
use crate::epoch_state::storage::save_epoch;
|
||||
use crate::epoch_state::storage::{load_current_epoch, save_epoch};
|
||||
use crate::epoch_state::transactions::{
|
||||
try_advance_epoch_state, try_initiate_dkg, try_trigger_reset, try_trigger_resharing,
|
||||
};
|
||||
use crate::epoch_state::utils::check_epoch_state;
|
||||
use crate::error::ContractError;
|
||||
use crate::state::queries::query_state;
|
||||
use crate::state::storage::{DKG_ADMIN, MULTISIG, STATE};
|
||||
use crate::verification_key_shares::queries::{query_vk_share, query_vk_shares_paged};
|
||||
use crate::verification_key_shares::storage::vk_shares;
|
||||
use crate::verification_key_shares::transactions::try_commit_verification_key_share;
|
||||
use crate::verification_key_shares::transactions::try_verify_verification_key_share;
|
||||
use cosmwasm_std::{
|
||||
@@ -134,6 +137,36 @@ pub fn execute(
|
||||
ExecuteMsg::UpdateAnnounceAddress { new_address } => {
|
||||
try_update_announce_address(deps, info, new_address)
|
||||
}
|
||||
ExecuteMsg::FixOldShare { old_owner } => {
|
||||
let old_owner = deps.api.addr_validate(&old_owner)?;
|
||||
|
||||
let epoch = load_current_epoch(deps.storage)?;
|
||||
|
||||
// make sure we're not mid-exchange
|
||||
check_epoch_state(deps.storage, EpochState::InProgress)?;
|
||||
|
||||
// make sure the requester is actually a dealer for this epoch
|
||||
ensure_dealer(deps.storage, &info.sender, epoch.epoch_id)?;
|
||||
|
||||
for epoch_id in 0..=epoch.epoch_id {
|
||||
if let Some(mut vk_share) =
|
||||
vk_shares().may_load(deps.storage, (&old_owner, epoch_id))?
|
||||
{
|
||||
vk_share.owner = info.sender.clone();
|
||||
vk_shares().remove(deps.storage, (&old_owner, epoch_id))?;
|
||||
vk_shares().save(deps.storage, (&info.sender, epoch_id), &vk_share)?;
|
||||
}
|
||||
|
||||
if let Some(mut vk_share) =
|
||||
vk_shares().may_load(deps.storage, (&info.sender, epoch_id))?
|
||||
{
|
||||
vk_share.owner = info.sender.clone();
|
||||
vk_shares().save(deps.storage, (&info.sender, epoch_id), &vk_share)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Response::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,7 +292,7 @@ pub fn migrate(deps: DepsMut<'_>, env: Env, _msg: MigrateMsg) -> Result<Response
|
||||
set_build_information!(deps.storage)?;
|
||||
cw2::ensure_from_older_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
|
||||
|
||||
crate::queued_migrations::introduce_historical_epochs(deps, env)?;
|
||||
// crate::queued_migrations::introduce_historical_epochs(deps, env)?;
|
||||
|
||||
Ok(Response::new())
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ pub fn try_transfer_ownership(
|
||||
DEALERS_INDICES.save(deps.storage, &transfer_to, ¤t_index)?;
|
||||
DEALERS_INDICES.remove(deps.storage, &info.sender);
|
||||
|
||||
// update registration detail for every epoch the current dealer has participated in the protocol
|
||||
// update registration detail and share information for every epoch the current dealer has participated in the protocol
|
||||
// ideally, we'd have only updated the current epoch, but the way the contract is constructed
|
||||
// forbids that otherwise we'd have introduced inconsistency
|
||||
for epoch_id in 0..=epoch.epoch_id {
|
||||
@@ -118,6 +118,11 @@ pub fn try_transfer_ownership(
|
||||
EPOCH_DEALERS_MAP.remove(deps.storage, (epoch_id, &info.sender));
|
||||
EPOCH_DEALERS_MAP.save(deps.storage, (epoch_id, &transfer_to), &details)?;
|
||||
}
|
||||
if let Some(mut vk_share) = vk_shares().may_load(deps.storage, (&info.sender, epoch_id))? {
|
||||
vk_shares().remove(deps.storage, (&info.sender, epoch_id))?;
|
||||
vk_share.owner = transfer_to.clone();
|
||||
vk_shares().save(deps.storage, (&transfer_to, epoch_id), &vk_share)?;
|
||||
}
|
||||
}
|
||||
|
||||
let Some(transaction_info) = env.transaction else {
|
||||
@@ -262,6 +267,7 @@ mod tests_with_mock {
|
||||
contract.run_initial_dummy_dkg();
|
||||
let old_index = DEALERS_INDICES.load(&contract, &group_member)?;
|
||||
let old_details = EPOCH_DEALERS_MAP.load(&contract, (0, &group_member))?;
|
||||
let old_share = vk_shares().load(&contract, (&group_member, 0))?;
|
||||
|
||||
let not_group_member = contract.addr_make("not_group_member");
|
||||
let (deps, env) = contract.deps_mut_env();
|
||||
@@ -291,13 +297,20 @@ mod tests_with_mock {
|
||||
assert!(EPOCH_DEALERS_MAP
|
||||
.may_load(&contract, (0, &group_member))?
|
||||
.is_none());
|
||||
assert!(vk_shares()
|
||||
.may_load(&contract, (&group_member, 0))?
|
||||
.is_none());
|
||||
|
||||
let new_index = DEALERS_INDICES.load(&contract, &new_group_member)?;
|
||||
let new_details = EPOCH_DEALERS_MAP.load(&contract, (0, &new_group_member))?;
|
||||
let new_share = vk_shares().load(&contract, (&new_group_member, 0))?;
|
||||
|
||||
// the underlying info hasn't changed
|
||||
assert_eq!(old_index, new_index);
|
||||
assert_eq!(old_details, new_details);
|
||||
assert_ne!(old_share, new_share);
|
||||
assert_eq!(old_share.owner, group_member);
|
||||
assert_eq!(new_share.owner, new_group_member);
|
||||
|
||||
assert_eq!(
|
||||
OWNERSHIP_TRANSFER_LOG.load(
|
||||
|
||||
@@ -57,7 +57,7 @@ async fn run(
|
||||
.clone()
|
||||
.expect("rust sdk mainnet default missing api_url");
|
||||
|
||||
let nym_api = nym_http_api_client::ClientBuilder::new_with_urls(vec![default_api_url.into()])
|
||||
let nym_api = nym_http_api_client::ClientBuilder::new_with_urls(vec![default_api_url.into()])?
|
||||
.no_hickory_dns()
|
||||
.with_timeout(nym_api_client_timeout)
|
||||
.build()?;
|
||||
|
||||
@@ -98,7 +98,7 @@ impl Monitor {
|
||||
.expect("rust sdk mainnet default missing api_url");
|
||||
|
||||
let nym_api =
|
||||
nym_http_api_client::ClientBuilder::new_with_urls(vec![default_api_url.into()])
|
||||
nym_http_api_client::ClientBuilder::new_with_urls(vec![default_api_url.into()])?
|
||||
.no_hickory_dns()
|
||||
.with_timeout(self.nym_api_client_timeout)
|
||||
.build()?;
|
||||
|
||||
Reference in New Issue
Block a user