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 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_retries(retry_count)
|
||||||
.with_bincode();
|
.with_bincode();
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,10 @@ pub enum ExecuteMsg {
|
|||||||
UpdateAnnounceAddress {
|
UpdateAnnounceAddress {
|
||||||
new_address: String,
|
new_address: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
FixOldShare {
|
||||||
|
old_owner: String,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cw_serde]
|
#[cw_serde]
|
||||||
|
|||||||
@@ -296,6 +296,9 @@ impl std::error::Error for ReqwestErrorWrapper {}
|
|||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub enum HttpClientError {
|
pub enum HttpClientError {
|
||||||
|
#[error("did not provide any valid client URLs")]
|
||||||
|
NoUrlsProvided,
|
||||||
|
|
||||||
#[error("failed to construct inner reqwest client: {source}")]
|
#[error("failed to construct inner reqwest client: {source}")]
|
||||||
ReqwestBuildError {
|
ReqwestBuildError {
|
||||||
#[source]
|
#[source]
|
||||||
@@ -582,24 +585,29 @@ impl ClientBuilder {
|
|||||||
Self::new(alt)
|
Self::new(alt)
|
||||||
} else {
|
} else {
|
||||||
let url = url.to_url()?;
|
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
|
/// Create a client builder from network details with sensible defaults
|
||||||
#[cfg(feature = "network-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(
|
pub fn from_network(
|
||||||
network: &nym_network_defaults::NymNetworkDetails,
|
network: &nym_network_defaults::NymNetworkDetails,
|
||||||
) -> Result<Self, HttpClientError> {
|
) -> Result<Self, HttpClientError> {
|
||||||
let urls = network
|
let urls = network.nym_api_urls.as_ref().cloned().unwrap_or_default();
|
||||||
.nym_api_urls
|
Self::new_with_fronted_urls(urls.clone())
|
||||||
.as_ref()
|
}
|
||||||
.ok_or_else(|| {
|
|
||||||
HttpClientError::GenericRequestFailure(
|
/// Create a client builder using the provided set of domain-fronted URLs
|
||||||
"No API URLs configured in network details".to_string(),
|
#[cfg(feature = "network-defaults")]
|
||||||
)
|
pub fn new_with_fronted_urls(
|
||||||
})?
|
urls: Vec<nym_network_defaults::ApiUrl>,
|
||||||
.iter()
|
) -> Result<Self, HttpClientError> {
|
||||||
|
let urls = urls
|
||||||
|
.into_iter()
|
||||||
.map(|api_url| {
|
.map(|api_url| {
|
||||||
// Convert ApiUrl to our Url type with fronting support
|
// Convert ApiUrl to our Url type with fronting support
|
||||||
let mut url = Url::parse(&api_url.url)?;
|
let mut url = Url::parse(&api_url.url)?;
|
||||||
@@ -611,15 +619,19 @@ impl ClientBuilder {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|host| format!("https://{}", host))
|
.map(|host| format!("https://{}", host))
|
||||||
.collect();
|
.collect();
|
||||||
url = Url::new(api_url.url.clone(), Some(fronts))
|
url = Url::new(api_url.url.clone(), Some(fronts)).map_err(|source| {
|
||||||
.map_err(|e| HttpClientError::GenericRequestFailure(e.to_string()))?;
|
HttpClientError::MalformedUrl {
|
||||||
|
raw: api_url.url.clone(),
|
||||||
|
source,
|
||||||
|
}
|
||||||
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(url)
|
Ok(url)
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, HttpClientError>>()?;
|
.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)
|
// Enable domain fronting by default (on retry)
|
||||||
#[cfg(feature = "tunneling")]
|
#[cfg(feature = "tunneling")]
|
||||||
@@ -631,7 +643,11 @@ impl ClientBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a new http `ClientBuilder` from a valid url.
|
/// 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);
|
let urls = Self::check_urls(urls);
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
@@ -640,7 +656,7 @@ impl ClientBuilder {
|
|||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
let reqwest_client_builder = default_builder();
|
let reqwest_client_builder = default_builder();
|
||||||
|
|
||||||
ClientBuilder {
|
Ok(ClientBuilder {
|
||||||
urls,
|
urls,
|
||||||
timeout: None,
|
timeout: None,
|
||||||
custom_user_agent: false,
|
custom_user_agent: false,
|
||||||
@@ -651,7 +667,7 @@ impl ClientBuilder {
|
|||||||
|
|
||||||
retry_limit: 0,
|
retry_limit: 0,
|
||||||
serialization: SerializationFormat::Json,
|
serialization: SerializationFormat::Json,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add an additional URL to the set usable by this constructed `Client`
|
/// 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.
|
/// Returns the default builder with all registered configurations applied.
|
||||||
pub fn default_builder() -> ReqwestClientBuilder {
|
pub fn default_builder() -> ReqwestClientBuilder {
|
||||||
let mut b = ReqwestClientBuilder::new();
|
let mut b = ReqwestClientBuilder::new();
|
||||||
|
|
||||||
|
#[cfg(feature = "debug-inventory")]
|
||||||
|
let mut test_client = ReqwestClientBuilder::new();
|
||||||
|
|
||||||
let mut records: Vec<&'static ConfigRecord> =
|
let mut records: Vec<&'static ConfigRecord> =
|
||||||
inventory::iter::<ConfigRecord>.into_iter().collect();
|
inventory::iter::<ConfigRecord>.into_iter().collect();
|
||||||
records.sort_by_key(|r| r.priority); // lower runs first
|
records.sort_by_key(|r| r.priority); // lower runs first
|
||||||
@@ -35,6 +39,10 @@ pub fn default_builder() -> ReqwestClientBuilder {
|
|||||||
|
|
||||||
for r in records {
|
for r in records {
|
||||||
b = (r.apply)(b);
|
b = (r.apply)(b);
|
||||||
|
#[cfg(feature = "debug-inventory")]
|
||||||
|
{
|
||||||
|
test_client = (r.apply)(test_client);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "debug-inventory")]
|
#[cfg(feature = "debug-inventory")]
|
||||||
@@ -47,7 +55,7 @@ pub fn default_builder() -> ReqwestClientBuilder {
|
|||||||
eprintln!("[HTTP-INVENTORY] Building test client to verify configuration...");
|
eprintln!("[HTTP-INVENTORY] Building test client to verify configuration...");
|
||||||
|
|
||||||
// Try to build a client to see if it works
|
// Try to build a client to see if it works
|
||||||
match b.try_clone().unwrap().build() {
|
match test_client.build() {
|
||||||
Ok(client) => {
|
Ok(client) => {
|
||||||
eprintln!("[HTTP-INVENTORY] ✓ Client built successfully");
|
eprintln!("[HTTP-INVENTORY] ✓ Client built successfully");
|
||||||
eprintln!("[HTTP-INVENTORY] Client debug info: {:#?}", client);
|
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![
|
let client = ClientBuilder::new_with_urls(vec![
|
||||||
"http://broken.nym.badurl".parse()?,
|
"http://broken.nym.badurl".parse()?,
|
||||||
"http://example.com/".parse()?,
|
"http://example.com/".parse()?,
|
||||||
])
|
])?
|
||||||
.with_retries(3)
|
.with_retries(3)
|
||||||
.build()?;
|
.build()?;
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use crate::dealers::queries::{
|
|||||||
query_epoch_dealers_addresses_paged, query_epoch_dealers_paged,
|
query_epoch_dealers_addresses_paged, query_epoch_dealers_paged,
|
||||||
query_registered_dealer_details,
|
query_registered_dealer_details,
|
||||||
};
|
};
|
||||||
|
use crate::dealers::storage::{ensure_dealer, EPOCH_DEALERS_MAP};
|
||||||
use crate::dealers::transactions::{
|
use crate::dealers::transactions::{
|
||||||
try_add_dealer, try_transfer_ownership, try_update_announce_address,
|
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_can_advance_state, query_current_epoch, query_current_epoch_threshold,
|
||||||
query_epoch_at_height, query_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::{
|
use crate::epoch_state::transactions::{
|
||||||
try_advance_epoch_state, try_initiate_dkg, try_trigger_reset, try_trigger_resharing,
|
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::error::ContractError;
|
||||||
use crate::state::queries::query_state;
|
use crate::state::queries::query_state;
|
||||||
use crate::state::storage::{DKG_ADMIN, MULTISIG, 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::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_commit_verification_key_share;
|
||||||
use crate::verification_key_shares::transactions::try_verify_verification_key_share;
|
use crate::verification_key_shares::transactions::try_verify_verification_key_share;
|
||||||
use cosmwasm_std::{
|
use cosmwasm_std::{
|
||||||
@@ -134,6 +137,36 @@ pub fn execute(
|
|||||||
ExecuteMsg::UpdateAnnounceAddress { new_address } => {
|
ExecuteMsg::UpdateAnnounceAddress { new_address } => {
|
||||||
try_update_announce_address(deps, info, 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)?;
|
set_build_information!(deps.storage)?;
|
||||||
cw2::ensure_from_older_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
|
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())
|
Ok(Response::new())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ pub fn try_transfer_ownership(
|
|||||||
DEALERS_INDICES.save(deps.storage, &transfer_to, ¤t_index)?;
|
DEALERS_INDICES.save(deps.storage, &transfer_to, ¤t_index)?;
|
||||||
DEALERS_INDICES.remove(deps.storage, &info.sender);
|
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
|
// ideally, we'd have only updated the current epoch, but the way the contract is constructed
|
||||||
// forbids that otherwise we'd have introduced inconsistency
|
// forbids that otherwise we'd have introduced inconsistency
|
||||||
for epoch_id in 0..=epoch.epoch_id {
|
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.remove(deps.storage, (epoch_id, &info.sender));
|
||||||
EPOCH_DEALERS_MAP.save(deps.storage, (epoch_id, &transfer_to), &details)?;
|
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 {
|
let Some(transaction_info) = env.transaction else {
|
||||||
@@ -262,6 +267,7 @@ mod tests_with_mock {
|
|||||||
contract.run_initial_dummy_dkg();
|
contract.run_initial_dummy_dkg();
|
||||||
let old_index = DEALERS_INDICES.load(&contract, &group_member)?;
|
let old_index = DEALERS_INDICES.load(&contract, &group_member)?;
|
||||||
let old_details = EPOCH_DEALERS_MAP.load(&contract, (0, &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 not_group_member = contract.addr_make("not_group_member");
|
||||||
let (deps, env) = contract.deps_mut_env();
|
let (deps, env) = contract.deps_mut_env();
|
||||||
@@ -291,13 +297,20 @@ mod tests_with_mock {
|
|||||||
assert!(EPOCH_DEALERS_MAP
|
assert!(EPOCH_DEALERS_MAP
|
||||||
.may_load(&contract, (0, &group_member))?
|
.may_load(&contract, (0, &group_member))?
|
||||||
.is_none());
|
.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_index = DEALERS_INDICES.load(&contract, &new_group_member)?;
|
||||||
let new_details = EPOCH_DEALERS_MAP.load(&contract, (0, &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
|
// the underlying info hasn't changed
|
||||||
assert_eq!(old_index, new_index);
|
assert_eq!(old_index, new_index);
|
||||||
assert_eq!(old_details, new_details);
|
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!(
|
assert_eq!(
|
||||||
OWNERSHIP_TRANSFER_LOG.load(
|
OWNERSHIP_TRANSFER_LOG.load(
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ async fn run(
|
|||||||
.clone()
|
.clone()
|
||||||
.expect("rust sdk mainnet default missing api_url");
|
.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()
|
.no_hickory_dns()
|
||||||
.with_timeout(nym_api_client_timeout)
|
.with_timeout(nym_api_client_timeout)
|
||||||
.build()?;
|
.build()?;
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ impl Monitor {
|
|||||||
.expect("rust sdk mainnet default missing api_url");
|
.expect("rust sdk mainnet default missing api_url");
|
||||||
|
|
||||||
let nym_api =
|
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()
|
.no_hickory_dns()
|
||||||
.with_timeout(self.nym_api_client_timeout)
|
.with_timeout(self.nym_api_client_timeout)
|
||||||
.build()?;
|
.build()?;
|
||||||
|
|||||||
Reference in New Issue
Block a user