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

Add a protocol parameters hash test #1195

Merged
merged 14 commits into from
Sep 15, 2023
12 changes: 11 additions & 1 deletion sdk/src/types/block/address/bech32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,22 @@ use packable::{

use crate::types::block::{address::Address, ConvertTo, Error};

#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Hrp {
inner: [u8; 83],
len: u8,
}

impl core::fmt::Debug for Hrp {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Hrp")
.field("display", &self.to_string())
.field("inner", &prefix_hex::encode(&self.inner[..self.len as usize]))
thibault-martinez marked this conversation as resolved.
Show resolved Hide resolved
.field("len", &self.len)
.finish()
}
}

impl Hrp {
/// Convert a string to an Hrp without checking validity.
pub const fn from_str_unchecked(hrp: &str) -> Self {
Expand Down
93 changes: 58 additions & 35 deletions sdk/src/types/block/output/rent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@

use core::mem::size_of;

use packable::{
error::{UnpackError, UnpackErrorExt},
packer::Packer,
unpacker::Unpacker,
Packable,
};
use packable::Packable;

use crate::types::block::{
address::{Address, Ed25519Address},
Expand All @@ -23,9 +18,13 @@ use crate::types::block::{
const DEFAULT_BYTE_COST: u32 = 100;
const DEFAULT_BYTE_COST_FACTOR_KEY: u8 = 10;
const DEFAULT_BYTE_COST_FACTOR_DATA: u8 = 1;
// TODO: fill in the real values
const DEFAULT_BYTE_COST_FACTOR_DELEGATION: u8 = 1;
const DEFAULT_BYTE_COST_FACTOR_STAKING_FEATURE: u8 = 1;
const DEFAULT_BYTE_COST_FACTOR_ISSUER_KEYS: u8 = 1;

/// Specifies the current parameters for the byte cost computation.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Packable)]
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
Expand All @@ -34,29 +33,48 @@ const DEFAULT_BYTE_COST_FACTOR_DATA: u8 = 1;
pub struct RentStructure {
/// Cost in tokens per virtual byte.
v_byte_cost: u32,
/// The weight factor used for key fields in the outputs.
v_byte_factor_key: u8,
/// The weight factor used for data fields in the outputs.
v_byte_factor_data: u8,
/// The weight factor used for key fields in the outputs.
v_byte_factor_key: u8,
/// The weight factor used for block issuer key fields in the outputs.
v_byte_factor_issuer_keys: u8,
/// The weight factor used for staking fields in the outputs.
v_byte_factor_staking_feature: u8,
/// The weight factor used for delegation fields in the outputs.
v_byte_factor_delegation: u8,
}

impl Default for RentStructure {
fn default() -> Self {
Self {
v_byte_cost: DEFAULT_BYTE_COST,
v_byte_factor_key: DEFAULT_BYTE_COST_FACTOR_KEY,
v_byte_factor_data: DEFAULT_BYTE_COST_FACTOR_DATA,
v_byte_factor_key: DEFAULT_BYTE_COST_FACTOR_KEY,
v_byte_factor_issuer_keys: DEFAULT_BYTE_COST_FACTOR_ISSUER_KEYS,
v_byte_factor_staking_feature: DEFAULT_BYTE_COST_FACTOR_STAKING_FEATURE,
v_byte_factor_delegation: DEFAULT_BYTE_COST_FACTOR_DELEGATION,
}
}
}

impl RentStructure {
/// Creates a new [`RentStructure`].
pub fn new(byte_cost: u32, byte_factor_key: u8, byte_factor_data: u8) -> Self {
pub fn new(
byte_cost: u32,
byte_factor_data: u8,
byte_factor_key: u8,
byte_factor_issuer_keys: u8,
byte_factor_staking_feature: u8,
byte_factor_delegation: u8,
) -> Self {
Self {
v_byte_cost: byte_cost,
v_byte_factor_key: byte_factor_key,
v_byte_factor_data: byte_factor_data,
v_byte_factor_key: byte_factor_key,
v_byte_factor_issuer_keys: byte_factor_issuer_keys,
v_byte_factor_staking_feature: byte_factor_staking_feature,
v_byte_factor_delegation: byte_factor_delegation,
}
}

Expand All @@ -78,6 +96,24 @@ impl RentStructure {
self
}

/// Sets the virtual byte weight for the delegation fields.
pub fn with_byte_factor_delegation(mut self, byte_factor_delegation: u8) -> Self {
self.v_byte_factor_delegation = byte_factor_delegation;
self
}

/// Sets the virtual byte weight for the staking fields.
pub fn with_byte_factor_staking_feature(mut self, byte_factor_staking_feature: u8) -> Self {
self.v_byte_factor_staking_feature = byte_factor_staking_feature;
self
}

/// Sets the virtual byte weight for the block issuer key fields.
pub fn with_byte_factor_issuer_keys(mut self, byte_factor_issuer_keys: u8) -> Self {
self.v_byte_factor_issuer_keys = byte_factor_issuer_keys;
self
}

/// Returns the byte cost of the [`RentStructure`].
pub fn byte_cost(&self) -> u32 {
self.v_byte_cost
Expand All @@ -92,33 +128,20 @@ impl RentStructure {
pub fn byte_factor_data(&self) -> u8 {
self.v_byte_factor_data
}
}

impl Packable for RentStructure {
type UnpackError = Error;
type UnpackVisitor = ();

fn pack<P: Packer>(&self, packer: &mut P) -> Result<(), P::Error> {
self.v_byte_cost.pack(packer)?;
self.v_byte_factor_data.pack(packer)?;
self.v_byte_factor_key.pack(packer)?;

Ok(())
/// Returns the delegation byte factor of the [`RentStructure`].
pub const fn byte_factor_delegation(&self) -> u8 {
self.v_byte_factor_delegation
}

fn unpack<U: Unpacker, const VERIFY: bool>(
unpacker: &mut U,
visitor: &Self::UnpackVisitor,
) -> Result<Self, UnpackError<Self::UnpackError, U::Error>> {
let v_byte_cost = u32::unpack::<_, VERIFY>(unpacker, visitor).coerce()?;
let v_byte_factor_data = u8::unpack::<_, VERIFY>(unpacker, visitor).coerce()?;
let v_byte_factor_key = u8::unpack::<_, VERIFY>(unpacker, visitor).coerce()?;
/// Returns the staking byte factor of the [`RentStructure`].
pub const fn byte_factor_staking_feature(&self) -> u8 {
self.v_byte_factor_staking_feature
}

Ok(Self {
v_byte_cost,
v_byte_factor_key,
v_byte_factor_data,
})
/// Returns the block issuer key byte factor of the [`RentStructure`].
pub const fn byte_factor_issuer_keys(&self) -> u8 {
self.v_byte_factor_issuer_keys
}
}

Expand Down
86 changes: 85 additions & 1 deletion sdk/src/types/block/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ use crate::types::block::{helper::network_name_to_id, output::RentStructure, Con
)]
#[getset(get_copy = "pub")]
pub struct ProtocolParameters {
/// The layout type.
#[serde(rename = "type")]
pub(crate) kind: u8,
thibault-martinez marked this conversation as resolved.
Show resolved Hide resolved
/// The version of the protocol running.
pub(crate) version: u8,
/// The human friendly name of the network.
Expand Down Expand Up @@ -82,6 +85,7 @@ impl Borrow<()> for ProtocolParameters {
impl Default for ProtocolParameters {
fn default() -> Self {
Self {
kind: 0,
version: PROTOCOL_VERSION,
// Unwrap: Known to be valid
network_name: String::from("iota-core-testnet").try_into().unwrap(),
Expand Down Expand Up @@ -303,7 +307,7 @@ pub fn protocol_parameters() -> ProtocolParameters {
2,
"testnet",
"rms",
crate::types::block::output::RentStructure::new(500, 10, 1),
crate::types::block::output::RentStructure::new(500, 1, 10, 1, 1, 1),
1_813_620_509_061_365,
1582328545,
10,
Expand All @@ -320,3 +324,83 @@ impl_id!(

#[cfg(feature = "serde")]
string_serde_impl!(ProtocolParametersHash);

#[cfg(test)]
mod test {
use super::*;

#[test]
fn params_serde_hash() {
thibault-martinez marked this conversation as resolved.
Show resolved Hide resolved
// Data from https://github.com/iotaledger/tips-draft/blob/tip49/tips/TIP-0049/tip-0049.md#protocol-parameter-example
let protocol_params_json = serde_json::json!(
{
"type": 0,
"version": 3,
"networkName": "xxxNetwork",
"bech32Hrp": "xxx",
"rentStructure": {
"vByteCost": 6,
"vByteFactorData": 7,
"vByteFactorKey": 8,
"vByteFactorIssuerKeys": 9,
"vByteFactorStakingFeature": 10,
"vByteFactorDelegation": 10
},
"workScoreStructure": {
"dataKilobyte": 1,
"block": 2,
"missingParent": 3,
"input": 4,
"contextInput": 5,
"output": 6,
"nativeToken": 7,
"staking": 8,
"blockIssuer": 9,
"allotment": 10,
"signatureEd25519": 11,
"minStrongParentsThreshold": 12
},
"tokenSupply": "1234567890987654321",
"genesisUnixTimestamp": "1681373293",
"slotDurationInSeconds": 10,
"slotsPerEpochExponent": 13,
"manaStructure": {
"manaBitsCount": 1,
"manaGenerationRate": 1,
"manaGenerationRateExponent": 27,
"manaDecayFactors": [ 10, 20 ],
"manaDecayFactorsExponent": 32,
"manaDecayFactorEpochsSum": 1337,
"manaDecayFactorEpochsSumExponent": 20
},
"stakingUnbondingPeriod": "11",
"validationBlocksPerSlot": 10,
"livenessThreshold": "3",
"minCommittableAge": "10",
"maxCommittableAge": "20",
"epochNearingThreshold": "24",
"congestionControlParameters": {
"rmcMin": "500",
"increase": "500",
"decrease": "500",
"increaseThreshold": 800000,
"decreaseThreshold": 500000,
"schedulerRate": 100000,
"minMana": "1",
"maxBufferSize": 3276800
},
"versionSignaling": {
"windowSize": 3,
"windowTargetRatio": 4,
"activationOffset": 1
}
}
);
let protocol_params = serde_json::from_value::<ProtocolParameters>(protocol_params_json).unwrap();
let hash = protocol_params.hash();
assert_eq!(
hash.to_string(),
"0xd379bdceb68aa77dada50ae7e3493b8f0b6ed28d26813620ce893afad541eb29"
);
}
}
2 changes: 1 addition & 1 deletion sdk/src/wallet/account/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ fn serialize() {
2,
"testnet",
"rms",
crate::types::block::output::RentStructure::new(500, 10, 1),
crate::types::block::output::RentStructure::new(500, 1, 10, 1, 1, 1),
1_813_620_509_061_365,
1582328545,
10,
Expand Down
14 changes: 12 additions & 2 deletions sdk/tests/types/rent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,21 @@ use iota_sdk::types::block::{
};

const BYTE_COST: u32 = 1;
const FACTOR_KEY: u8 = 10;
const FACTOR_DATA: u8 = 1;
const FACTOR_KEY: u8 = 10;
const FACTOR_DELEGATION: u8 = 1;
const FACTOR_STAKING_FEATURE: u8 = 1;
const FACTOR_ISSUER_KEYS: u8 = 1;

fn config() -> RentStructure {
thibault-martinez marked this conversation as resolved.
Show resolved Hide resolved
RentStructure::new(BYTE_COST, FACTOR_KEY, FACTOR_DATA)
RentStructure::new(
BYTE_COST,
FACTOR_DATA,
FACTOR_KEY,
FACTOR_DELEGATION,
FACTOR_STAKING_FEATURE,
FACTOR_ISSUER_KEYS,
)
}
thibault-martinez marked this conversation as resolved.
Show resolved Hide resolved

fn output_in_range(output: Output, range: std::ops::RangeInclusive<u64>) {
Expand Down