Skip to content

Commit

Permalink
Add some checks for capabilities (#1551)
Browse files Browse the repository at this point in the history
* Fix rust capabilities

* nodejs

* python

* rust trim

* validate serialized capabilities

* remove trim

* add some more checking and tests

* suggestion

* comments

* Update sdk/src/types/block/error.rs

Co-authored-by: Tadeusz Sośnierz <[email protected]>

---------

Co-authored-by: Thibault Martinez <[email protected]>
Co-authored-by: Tadeusz Sośnierz <[email protected]>
  • Loading branch information
3 people authored Nov 7, 2023
1 parent 16d7f9a commit da32fad
Show file tree
Hide file tree
Showing 9 changed files with 258 additions and 70 deletions.
19 changes: 13 additions & 6 deletions bindings/nodejs/lib/types/block/address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ class RestrictedAddress extends Address {
/**
* The allowed capabilities bitflags.
*/
private allowedCapabilities: HexEncodedString = '0x';
private allowedCapabilities?: HexEncodedString;
/**
* @param address An address.
*/
Expand All @@ -227,7 +227,7 @@ class RestrictedAddress extends Address {
allowedCapabilities.byteLength,
).toString('hex');
} else {
this.allowedCapabilities = '0x';
this.allowedCapabilities = undefined;
}
}

Expand All @@ -239,13 +239,20 @@ class RestrictedAddress extends Address {
}

getAllowedCapabilities(): Uint8Array {
return Uint8Array.from(
Buffer.from(this.allowedCapabilities.substring(2), 'hex'),
);
return this.allowedCapabilities !== undefined
? Uint8Array.from(
Buffer.from(this.allowedCapabilities.substring(2), 'hex'),
)
: new Uint8Array();
}

toString(): string {
return this.address.toString() + this.allowedCapabilities.substring(2);
return (
this.address.toString() +
(this.allowedCapabilities !== undefined
? this.allowedCapabilities.substring(2)
: '')
);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class Transaction {

readonly allotments: ManaAllotment[];

private capabilities: HexEncodedString = '0x';
private capabilities?: HexEncodedString;

@Type(() => Payload, {
discriminator: PayloadDiscriminator,
Expand Down Expand Up @@ -91,7 +91,7 @@ class Transaction {
capabilities.byteLength,
).toString('hex');
} else {
this.capabilities = '0x';
this.capabilities = undefined;
}
}

Expand All @@ -102,9 +102,11 @@ class Transaction {

/** Get the capability bitflags of the transaction. */
getCapabilities(): Uint8Array {
return Uint8Array.from(
Buffer.from(this.capabilities.substring(2), 'hex'),
);
return this.capabilities !== undefined
? Uint8Array.from(
Buffer.from(this.capabilities.substring(2), 'hex'),
)
: new Uint8Array();
}
}

Expand Down
9 changes: 6 additions & 3 deletions bindings/python/iota_sdk/types/address.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from enum import IntEnum
from dataclasses import dataclass, field
from typing import Any, Dict, List, TypeAlias, Union
from typing import Any, Dict, List, Optional, TypeAlias, Union
from iota_sdk.types.common import HexStr, json


Expand Down Expand Up @@ -118,7 +118,7 @@ class RestrictedAddress:
allowed_capabilities: The allowed capabilities bitflags.
"""
address: Union[Ed25519Address, AccountAddress, NFTAddress]
allowed_capabilities: HexStr = field(default='0x', init=False)
allowed_capabilities: Optional[HexStr] = field(default=None, init=False)
type: int = field(default_factory=lambda: int(
AddressType.RESTRICTED), init=False)

Expand All @@ -127,7 +127,10 @@ def with_allowed_capabilities(self, capabilities: bytes):
Attributes:
capabilities: The allowed capabilities bitflags.
"""
self.allowed_capabilities = '0x' + capabilities.hex()
if any(c != 0 for c in capabilities):
self.allowed_capabilities = '0x' + capabilities.hex()
else:
self.allowed_capabilities = None


@json
Expand Down
7 changes: 5 additions & 2 deletions bindings/python/iota_sdk/types/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class Transaction:
context_inputs: List[ContextInput]
inputs: List[UtxoInput]
allotments: List[ManaAllotment]
capabilities: HexStr = field(default='0x', init=False)
capabilities: Optional[HexStr] = field(default=None, init=False)
outputs: List[Output]
payload: Optional[Payload] = None

Expand All @@ -47,4 +47,7 @@ def with_capabilities(self, capabilities: bytes):
Attributes:
capabilities: The transaction capabilities bitflags.
"""
self.capabilities = '0x' + capabilities.hex()
if any(c != 0 for c in capabilities):
self.capabilities = '0x' + capabilities.hex()
else:
self.capabilities = None
3 changes: 2 additions & 1 deletion bindings/python/iota_sdk/wallet/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,8 @@ def get_output(self, output_id: OutputId) -> OutputData:
}
))

def get_transaction(self, transaction_id: HexStr) -> TransactionWithMetadata:
def get_transaction(
self, transaction_id: HexStr) -> TransactionWithMetadata:
"""Get transaction.
"""
return TransactionWithMetadata.from_dict(self._call_account_method(
Expand Down
18 changes: 4 additions & 14 deletions sdk/src/types/block/address/restricted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,21 +157,18 @@ pub type AddressCapabilities = Capabilities<AddressCapabilityFlag>;

#[cfg(feature = "serde")]
pub(crate) mod dto {
use alloc::boxed::Box;

use serde::{Deserialize, Serialize};

use super::*;
use crate::utils::serde::prefix_hex_bytes;

#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RestrictedAddressDto {
#[serde(rename = "type")]
kind: u8,
pub address: Address,
#[serde(with = "prefix_hex_bytes")]
pub allowed_capabilities: Box<[u8]>,
#[serde(default, skip_serializing_if = "AddressCapabilities::is_none")]
pub allowed_capabilities: AddressCapabilities,
}

impl core::ops::Deref for RestrictedAddressDto {
Expand All @@ -187,7 +184,7 @@ pub(crate) mod dto {
Self {
kind: RestrictedAddress::KIND,
address: value.address.clone(),
allowed_capabilities: value.allowed_capabilities.iter().copied().collect(),
allowed_capabilities: value.allowed_capabilities.clone(),
}
}
}
Expand All @@ -196,14 +193,7 @@ pub(crate) mod dto {
type Error = Error;

fn try_from(value: RestrictedAddressDto) -> Result<Self, Self::Error> {
Ok(
Self::new(value.address)?.with_allowed_capabilities(AddressCapabilities::from_bytes(
value
.allowed_capabilities
.try_into()
.map_err(Error::InvalidCapabilitiesCount)?,
)),
)
Ok(Self::new(value.address)?.with_allowed_capabilities(value.allowed_capabilities))
}
}

Expand Down
Loading

0 comments on commit da32fad

Please sign in to comment.