Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update info response and related structs #1028

Merged
merged 36 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
8b975e4
Update info response and related structs
Aug 16, 2023
c4aac92
display
Aug 16, 2023
7f229d8
fix wasm, no_std and test
Aug 16, 2023
ec0a0f9
fix one more test
Aug 17, 2023
89b3616
Merge branch '2.0' into feat/info-response
Aug 17, 2023
3f11a3b
Merge branch '2.0' into feat/info-response
Aug 18, 2023
d729d29
Merge branch '2.0' into feat/info-response
Aug 18, 2023
7c2dec2
Implement mapped params, epoch index, helpers
Aug 21, 2023
c342573
fix tests, wasm
Aug 21, 2023
f8010d1
copy/paste oopsie
Aug 22, 2023
ab9e87e
Merge branch '2.0' into feat/info-response
Aug 22, 2023
4a3c845
tangle time
Aug 22, 2023
a96ad21
suggestions
Aug 22, 2023
c3da95e
more renames
Aug 22, 2023
1818887
Merge branch '2.0' into feat/info-response
Aug 22, 2023
7e11228
More cleanup
Aug 23, 2023
1bab1db
Merge branch '2.0' into feat/info-response
Aug 23, 2023
70c39f3
Merge branch '2.0' into feat/info-response
Aug 23, 2023
d682450
as -> to
Aug 23, 2023
e4cc3a5
harmony and peace
Aug 23, 2023
13b2a7c
derive
Aug 23, 2023
668b190
suggestion
Aug 23, 2023
ecb3212
another missed derive
Aug 23, 2023
2f77a9c
oops
Aug 23, 2023
bf7d87b
Always get v3 params for now. Add flexible epoch index calculation fo…
Aug 23, 2023
b58353a
fix wasm
Aug 23, 2023
a2f7132
add a test and impl suggestions
Aug 24, 2023
229293b
Merge branch '2.0' into feat/info-response
Aug 24, 2023
3668f72
Update sdk/src/types/block/slot/epoch.rs
Aug 25, 2023
2beba6b
Revert "Update sdk/src/types/block/slot/epoch.rs"
Aug 25, 2023
5532ffb
add another fail condition, a test, and remove TODOs
Aug 25, 2023
6611c69
Updates and add example comments
Aug 25, 2023
e8bd69f
Updates from TIP
Aug 25, 2023
18c2236
doc comments
Aug 25, 2023
3da8e7f
fix test and comment
Aug 25, 2023
24d04e1
fix other test
Aug 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions sdk/src/client/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ impl ClientInner {
}
let info = self.get_info().await?.node_info;
let mut client_network_info = self.network_info.write().await;
client_network_info.protocol_parameters = info.protocol.clone();
client_network_info.protocol_parameters = info.protocol_parameters[0].parameters.clone();

*LAST_SYNC.lock().unwrap() = Some(current_time + CACHE_NETWORK_INFO_TIMEOUT_IN_SECONDS);
}
Expand All @@ -124,7 +124,7 @@ impl ClientInner {

/// Gets the protocol version of the node we're connecting to.
pub async fn get_protocol_version(&self) -> Result<u8> {
Ok(self.get_network_info().await?.protocol_parameters.protocol_version())
Ok(self.get_network_info().await?.protocol_parameters.version())
}

/// Gets the network name of the node we're connecting to.
Expand All @@ -139,12 +139,7 @@ impl ClientInner {

/// Gets the bech32 HRP of the node we're connecting to.
pub async fn get_bech32_hrp(&self) -> Result<Hrp> {
Ok(*self.get_network_info().await?.protocol_parameters.bech32_hrp())
}

/// Gets the below maximum depth of the node we're connecting to.
pub async fn get_below_max_depth(&self) -> Result<u8> {
Ok(self.get_network_info().await?.protocol_parameters.below_max_depth())
Ok(self.get_network_info().await?.protocol_parameters.bech32_hrp())
}

/// Gets the rent structure of the node we're connecting to.
Expand Down
10 changes: 6 additions & 4 deletions sdk/src/client/node_manager/syncing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,14 @@ impl ClientInner {
match crate::client::Client::get_node_info(node.url.as_ref(), node.auth.clone()).await {
Ok(info) => {
if info.status.is_healthy || ignore_node_health {
match network_nodes.get_mut(info.protocol.network_name()) {
// TODO: is it okay to index like this?
thibault-martinez marked this conversation as resolved.
Show resolved Hide resolved
let network_name = info.protocol_parameters[0].parameters.network_name();
match network_nodes.get_mut(network_name) {
Some(network_node_entry) => {
network_node_entry.push((info, node.clone()));
}
None => {
network_nodes
.insert(info.protocol.network_name().to_owned(), vec![(info, node.clone())]);
network_nodes.insert(network_name.to_owned(), vec![(info, node.clone())]);
}
}
} else {
Expand All @@ -106,8 +107,9 @@ impl ClientInner {
let mut network_info = self.network_info.write().await;

// TODO change to one of the new timestamps, which ones ?
// TODO: okay to index here?
// network_info.latest_milestone_timestamp = info.status.latest_milestone.timestamp;
network_info.protocol_parameters = info.protocol.clone();
network_info.protocol_parameters = info.protocol_parameters[0].parameters.clone();
}

for (info, node_url) in nodes {
Expand Down
4 changes: 2 additions & 2 deletions sdk/src/client/secret/ledger_nano.rs
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ fn merge_unlocks(
// address already at this point, because the reference index needs to be lower
// than the current block index
if !input_address.is_ed25519() {
return Err(Error::MissingInputWithEd25519Address)?;
return Err(Error::MissingInputWithEd25519Address);
}

let unlock = unlocks.next().ok_or(Error::MissingInputWithEd25519Address)?;
Expand All @@ -561,7 +561,7 @@ fn merge_unlocks(
let Signature::Ed25519(ed25519_signature) = signature_unlock.signature();
let ed25519_address = match input_address {
Address::Ed25519(ed25519_address) => ed25519_address,
_ => return Err(Error::MissingInputWithEd25519Address)?,
_ => return Err(Error::MissingInputWithEd25519Address),
};
ed25519_signature.is_valid(&hashed_essence, &ed25519_address)?;
}
Expand Down
60 changes: 37 additions & 23 deletions sdk/src/types/api/core/response.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// Copyright 2020-2023 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use alloc::{string::String, vec::Vec};
use alloc::{boxed::Box, string::String, vec::Vec};

use crate::types::block::{
output::{dto::OutputDto, OutputId, OutputMetadata, OutputWithMetadata},
protocol::ProtocolParameters,
slot::SlotIndex,
slot::{SlotCommitmentId, SlotIndex},
BlockId,
};

Expand All @@ -23,10 +23,9 @@ pub struct InfoResponse {
pub version: String,
pub status: StatusResponse,
pub metrics: MetricsResponse,
pub supported_protocol_versions: Vec<u8>,
pub protocol: ProtocolParameters,
pub protocol_parameters: Box<[ProtocolParametersResponse]>,
pub base_token: BaseTokenResponse,
pub features: Vec<String>,
pub features: Box<[String]>,
}

#[cfg(feature = "serde")]
Expand All @@ -46,19 +45,19 @@ impl core::fmt::Display for InfoResponse {
)]
pub struct StatusResponse {
pub is_healthy: bool,
#[cfg_attr(feature = "serde", serde(with = "crate::utils::serde::string"))]
#[serde(with = "crate::utils::serde::string")]
pub accepted_tangle_time: u64,
#[cfg_attr(feature = "serde", serde(with = "crate::utils::serde::string"))]
#[serde(with = "crate::utils::serde::string")]
pub relative_accepted_tangle_time: u64,
#[cfg_attr(feature = "serde", serde(with = "crate::utils::serde::string"))]
#[serde(with = "crate::utils::serde::string")]
pub confirmed_tangle_time: u64,
abdulmth marked this conversation as resolved.
Show resolved Hide resolved
#[cfg_attr(feature = "serde", serde(with = "crate::utils::serde::string"))]
#[serde(with = "crate::utils::serde::string")]
pub relative_confirmed_tangle_time: u64,
pub latest_committed_slot: SlotIndex,
pub latest_commitment_id: SlotCommitmentId,
pub latest_finalized_slot: SlotIndex,
pub latest_accepted_block_slot: BlockId,
pub latest_confirmed_block_slot: BlockId,
thibault-martinez marked this conversation as resolved.
Show resolved Hide resolved
pub pruning_slot: SlotIndex,
pub latest_accepted_block_id: BlockId,
pub latest_confirmed_block_id: BlockId,
}

/// Returned in [`InfoResponse`].
Expand All @@ -70,11 +69,26 @@ pub struct StatusResponse {
serde(rename_all = "camelCase")
)]
pub struct MetricsResponse {
#[serde(with = "crate::utils::serde::string")]
pub blocks_per_second: f64,
#[serde(with = "crate::utils::serde::string")]
pub confirmed_blocks_per_second: f64,
#[serde(with = "crate::utils::serde::string")]
pub confirmed_rate: f64,
Thoralf-M marked this conversation as resolved.
Show resolved Hide resolved
}

#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(rename_all = "camelCase")
)]
pub struct ProtocolParametersResponse {
// TODO: should this be a number?
pub start_epoch: String,
Thoralf-M marked this conversation as resolved.
Show resolved Hide resolved
pub parameters: ProtocolParameters,
}

/// Returned in [`InfoResponse`].
/// Information about the base token.
#[derive(Clone, Debug, Eq, PartialEq)]
Expand All @@ -87,9 +101,9 @@ pub struct BaseTokenResponse {
pub name: String,
pub ticker_symbol: String,
pub unit: String,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
pub subunit: Option<String>,
pub decimals: u32,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub subunit: Option<String>,
pub use_metric_prefix: bool,
}

Expand Down Expand Up @@ -142,19 +156,19 @@ pub struct BlockMetadataResponse {
pub block_id: BlockId,
pub parents: Vec<BlockId>,
pub is_solid: bool,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub referenced_by_milestone_index: Option<u32>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub milestone_index: Option<u32>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ledger_inclusion_state: Option<LedgerInclusionState>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub conflict_reason: Option<u8>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub white_flag_index: Option<u32>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub should_promote: Option<bool>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub should_reattach: Option<bool>,
}

Expand Down Expand Up @@ -256,11 +270,11 @@ pub enum Relation {
pub struct PeerResponse {
pub id: String,
pub multi_addresses: Vec<String>,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub alias: Option<String>,
pub relation: Relation,
pub connected: bool,
#[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub gossip: Option<Gossip>,
}

Expand Down
4 changes: 2 additions & 2 deletions sdk/src/types/block/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,9 @@ impl Packable for BasicBlock {

let protocol_version = u8::unpack::<_, VERIFY>(unpacker, &()).coerce()?;

if VERIFY && protocol_version != protocol_params.protocol_version() {
if VERIFY && protocol_version != protocol_params.version() {
return Err(UnpackError::Packable(Error::ProtocolVersionMismatch {
expected: protocol_params.protocol_version(),
expected: protocol_params.version(),
actual: protocol_version,
}));
}
Expand Down
11 changes: 6 additions & 5 deletions sdk/src/types/block/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,9 @@ impl Packable for Block {

let protocol_version = u8::unpack::<_, VERIFY>(unpacker, &()).coerce()?;

if VERIFY && protocol_version != protocol_params.protocol_version() {
if VERIFY && protocol_version != protocol_params.version() {
return Err(UnpackError::Packable(Error::ProtocolVersionMismatch {
expected: protocol_params.protocol_version(),
expected: protocol_params.version(),
actual: protocol_version,
}));
}
Expand Down Expand Up @@ -220,7 +220,7 @@ impl<B> BlockWrapper<B> {
/// Returns the protocol version of a [`Block`].
#[inline(always)]
pub fn protocol_version(&self) -> u8 {
self.protocol_params.protocol_version
self.protocol_params.version()
}

/// Returns the protocol parameters of a [`Block`].
Expand Down Expand Up @@ -321,6 +321,7 @@ impl Block {

/// Creates a new [`BlockBuilder`] to construct an instance of a [`ValidationBlock`].
#[inline(always)]
#[allow(clippy::too_many_arguments)]
thibault-martinez marked this conversation as resolved.
Show resolved Hide resolved
pub fn build_validation(
protocol_params: ProtocolParameters,
issuing_time: u64,
Expand Down Expand Up @@ -694,9 +695,9 @@ pub(crate) mod dto {

impl Block {
pub fn try_from_dto(dto: BlockDto, protocol_params: ProtocolParameters) -> Result<Self, Error> {
if dto.protocol_version != protocol_params.protocol_version() {
if dto.protocol_version != protocol_params.version() {
return Err(Error::ProtocolVersionMismatch {
expected: protocol_params.protocol_version(),
expected: protocol_params.version(),
actual: dto.protocol_version,
});
}
Expand Down
79 changes: 77 additions & 2 deletions sdk/src/types/block/error.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
// Copyright 2020-2021 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use alloc::string::{FromUtf8Error, String};
use alloc::{
boxed::Box,
string::{FromUtf8Error, String},
};
use core::{convert::Infallible, fmt};

use crypto::Error as CryptoError;
// use packable::bounded::BoundedU8;
use packable::prefix::UnpackPrefixError;
use prefix_hex::Error as HexError;
use primitive_types::U256;

Expand Down Expand Up @@ -83,6 +86,10 @@ pub enum Error {
InvalidMetadataFeatureLength(<MetadataFeatureLength as TryFrom<usize>>::Error),
InvalidNativeTokenCount(<NativeTokenCount as TryFrom<usize>>::Error),
InvalidNetworkName(FromUtf8Error),
InvalidEpochNearingThreshold(FromUtf8Error),
InvalidManaDecayFactors(UnpackOptionError<Infallible>),
InvalidLivenessThreshold(UnpackOptionError<FromUtf8Error>),
InvalidOption(Box<UnpackOptionError<Self>>),
InvalidNftIndex(<UnlockIndex as TryFrom<u16>>::Error),
InvalidOutputAmount(u64),
InvalidOutputCount(<OutputCount as TryFrom<usize>>::Error),
Expand Down Expand Up @@ -245,6 +252,10 @@ impl fmt::Display for Error {
}
Self::InvalidNativeTokenCount(count) => write!(f, "invalid native token count: {count}"),
Self::InvalidNetworkName(err) => write!(f, "invalid network name: {err}"),
Self::InvalidEpochNearingThreshold(err) => write!(f, "invalid epoch nearing threshold: {err}"),
Self::InvalidManaDecayFactors(err) => write!(f, "invalid mana decay factors: {err}"),
Self::InvalidLivenessThreshold(err) => write!(f, "invalid liveness threshold: {err}"),
Self::InvalidOption(err) => write!(f, "invalid optional field: {err}"),
Self::InvalidNftIndex(index) => write!(f, "invalid nft index: {index}"),
Self::InvalidOutputAmount(amount) => write!(f, "invalid output amount: {amount}"),
Self::InvalidOutputCount(count) => write!(f, "invalid output count: {count}"),
Expand Down Expand Up @@ -360,6 +371,70 @@ impl fmt::Display for Error {
}
}

#[derive(Debug)]
pub struct UnpackOptionError<E>(packable::option::UnpackOptionError<E>);

impl<E: PartialEq> PartialEq for UnpackOptionError<E> {
fn eq(&self, other: &Self) -> bool {
use packable::option::UnpackOptionError as OtherErr;
match (&self.0, &other.0) {
(OtherErr::UnknownTag(t1), OtherErr::UnknownTag(t2)) => t1 == t2,
(OtherErr::Inner(e1), OtherErr::Inner(e2)) => e1 == e2,
_ => false,
}
}
}
impl<E: Eq> Eq for UnpackOptionError<E> {}

impl<E> UnpackOptionError<E> {
fn map_opt_err<F: Fn(E) -> U, U>(self, f: F) -> UnpackOptionError<U> {
use packable::option::UnpackOptionError as OtherErr;
UnpackOptionError(match self.0 {
OtherErr::UnknownTag(t) => OtherErr::UnknownTag(t),
OtherErr::Inner(e) => OtherErr::Inner(f(e)),
})
}
}

#[cfg(feature = "std")]
impl<E: fmt::Debug + fmt::Display> std::error::Error for UnpackOptionError<E> {}

impl<E: fmt::Display> fmt::Display for UnpackOptionError<E> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use packable::option::UnpackOptionError as OtherErr;
match &self.0 {
OtherErr::UnknownTag(t) => write!(f, "unknown tag: {t}"),
OtherErr::Inner(e) => write!(f, "{e}"),
}
}
}

pub(crate) trait UnpackPrefixOptionErrorExt<E> {
fn into_opt_error(self) -> UnpackOptionError<E>;
}

impl<E> UnpackPrefixOptionErrorExt<E> for packable::option::UnpackOptionError<E> {
fn into_opt_error(self) -> UnpackOptionError<E> {
UnpackOptionError(self)
}
}

impl<E> UnpackPrefixOptionErrorExt<E> for packable::option::UnpackOptionError<UnpackPrefixError<E, Infallible>> {
fn into_opt_error(self) -> UnpackOptionError<E> {
use packable::option::UnpackOptionError as OtherErr;
UnpackOptionError(match self {
Self::UnknownTag(t) => OtherErr::UnknownTag(t),
Self::Inner(e) => OtherErr::Inner(e.into_item_err()),
})
}
}

impl<E: Into<Self>> From<packable::option::UnpackOptionError<E>> for Error {
fn from(value: packable::option::UnpackOptionError<E>) -> Self {
Self::InvalidOption(value.into_opt_error().map_opt_err(Into::into).into())
}
}

thibault-martinez marked this conversation as resolved.
Show resolved Hide resolved
impl From<CryptoError> for Error {
fn from(error: CryptoError) -> Self {
Self::Crypto(error)
Expand Down
Loading
Loading