Skip to content

Commit

Permalink
Add block ID tests and remove protocol params from block wrapper (#1277)
Browse files Browse the repository at this point in the history
* WIP

* Block id method takes protocol parameters

* Tmp

* Add basic_block_id_transaction_payload

* Add validation_block_id

* Add client block_id method

* tmp

* Fixes

* Nit

* Nit

* Nit

* Nit

* Nit
  • Loading branch information
thibault-martinez authored Sep 21, 2023
1 parent f60ec69 commit 24a5524
Show file tree
Hide file tree
Showing 22 changed files with 369 additions and 195 deletions.
15 changes: 10 additions & 5 deletions bindings/core/src/method_handler/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ pub(crate) async fn call_client_method_internal(client: &Client, method: ClientM
)
.await?;

let block_id = block.id();
let block_id = client.block_id(&block).await?;

Response::BlockIdWithBlock(block_id, BlockWrapperDto::from(&block))
}
Expand All @@ -206,7 +206,7 @@ pub(crate) async fn call_client_method_internal(client: &Client, method: ClientM
),
ClientMethod::PostBlock { block } => Response::BlockId(
client
.post_block(&BlockWrapper::try_from_dto(
.post_block(&BlockWrapper::try_from_dto_with_params(
block,
client.get_protocol_parameters().await?,
)?)
Expand Down Expand Up @@ -313,9 +313,14 @@ pub(crate) async fn call_client_method_internal(client: &Client, method: ClientM
.await?;
Response::CustomJson(data)
}
ClientMethod::BlockId { block } => {
Response::BlockId(BlockWrapper::try_from_dto(block, client.get_protocol_parameters().await?)?.id())
}
ClientMethod::BlockId { block } => Response::BlockId(
client
.block_id(&BlockWrapper::try_from_dto_with_params(
block,
client.get_protocol_parameters().await?,
)?)
.await?,
),
};
Ok(response)
}
4 changes: 2 additions & 2 deletions bindings/core/src/method_handler/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ pub(crate) fn call_utils_method_internal(method: UtilsMethod) -> Result<Response
block,
protocol_parameters,
} => {
let block = BlockWrapper::try_from_dto(block, protocol_parameters)?;
Response::BlockId(block.id())
let block = BlockWrapper::try_from_dto_with_params(block, protocol_parameters.clone())?;
Response::BlockId(block.id(&protocol_parameters))
}
UtilsMethod::TransactionId { payload } => {
let payload = TransactionPayload::try_from_dto(payload)?;
Expand Down
2 changes: 1 addition & 1 deletion sdk/examples/client/block/00_block_no_payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ async fn main() -> Result<()> {
println!(
"Block with no payload sent: {}/block/{}",
std::env::var("EXPLORER_URL").unwrap(),
block.id()
client.block_id(&block).await?
);

Ok(())
Expand Down
2 changes: 1 addition & 1 deletion sdk/examples/client/block/01_block_confirmation_time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ async fn main() -> Result<()> {
None,
)
.await?;
let block_id = block.id();
let block_id = client.block_id(&block).await?;

println!("{block:#?}");

Expand Down
2 changes: 1 addition & 1 deletion sdk/examples/client/block/02_block_custom_parents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ async fn main() -> Result<()> {
println!(
"Block with custom parents sent: {}/block/{}",
std::env::var("EXPLORER_URL").unwrap(),
block.id()
client.block_id(&block).await?
);

Ok(())
Expand Down
2 changes: 1 addition & 1 deletion sdk/examples/client/block/03_block_custom_payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ async fn main() -> Result<()> {
println!(
"Block with custom payload sent: {}/block/{}",
std::env::var("EXPLORER_URL").unwrap(),
block.id()
client.block_id(&block).await?
);

Ok(())
Expand Down
2 changes: 1 addition & 1 deletion sdk/examples/client/block/04_block_tagged_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ async fn main() -> Result<()> {
println!(
"Block with tag and data sent: {}/block/{}",
std::env::var("EXPLORER_URL").unwrap(),
block.id()
client.block_id(&block).await?
);

Ok(())
Expand Down
5 changes: 4 additions & 1 deletion sdk/src/client/api/block_builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,11 @@ impl ClientInner {
issuing_time
});

let protocol_parameters = self.get_protocol_parameters().await?;

Ok(BlockWrapper::new(
&self.get_protocol_parameters().await?,
protocol_parameters.version(),
protocol_parameters.network_id(),
issuing_time,
commitment.id(),
latest_finalized_slot,
Expand Down
10 changes: 8 additions & 2 deletions sdk/src/client/node_api/core/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,10 @@ impl ClientInner {

let dto = self.get_request::<BlockWrapperDto>(path, None, false, true).await?;

Ok(BlockWrapper::try_from_dto(dto, self.get_protocol_parameters().await?)?)
Ok(BlockWrapper::try_from_dto_with_params(
dto,
self.get_protocol_parameters().await?,
)?)
}

/// Finds a block by its ID and returns it as raw bytes.
Expand Down Expand Up @@ -236,7 +239,10 @@ impl ClientInner {

let dto = self.get_request::<BlockWrapperDto>(path, None, true, true).await?;

Ok(BlockWrapper::try_from_dto(dto, self.get_protocol_parameters().await?)?)
Ok(BlockWrapper::try_from_dto_with_params(
dto,
self.get_protocol_parameters().await?,
)?)
}

/// Returns the earliest confirmed block containing the transaction with the given ID, as raw bytes.
Expand Down
6 changes: 5 additions & 1 deletion sdk/src/client/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::{
address::{Address, Bech32Address, Ed25519Address, Hrp, ToBech32Ext},
output::{AccountId, NftId},
payload::TaggedDataPayload,
ConvertTo,
BlockId, BlockWrapper, ConvertTo,
},
};

Expand Down Expand Up @@ -186,6 +186,10 @@ impl Client {
pub fn tagged_data_to_utf8(payload: &TaggedDataPayload) -> Result<(String, String)> {
Ok((Self::tag_to_utf8(payload)?, Self::data_to_utf8(payload)?))
}

pub async fn block_id(&self, block: &BlockWrapper) -> Result<BlockId> {
Ok(block.id(&self.get_protocol_parameters().await?))
}
}

/// A password wrapper that takes care of zeroing the memory when being dropped.
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/types/block/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use packable::{
pub use self::{
basic::{BasicBlock, BasicBlockBuilder},
validation::{ValidationBlock, ValidationBlockBuilder},
wrapper::BlockWrapper,
wrapper::{BlockHeader, BlockWrapper},
};
use crate::types::block::{
parent::{ShallowLikeParents, StrongParents, WeakParents},
Expand Down
73 changes: 38 additions & 35 deletions sdk/src/types/block/core/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,6 @@ pub struct BlockWrapper {
/// The block signature, used to validate issuance capabilities.
#[getset(get_copy = "pub")]
signature: Signature,
/// The identifier of the block.
#[getset(get_copy = "pub")]
id: BlockId,
}

impl BlockWrapper {
Expand All @@ -132,26 +129,27 @@ impl BlockWrapper {
/// Creates a new [`BlockWrapper`].
#[inline(always)]
pub fn new(
protocol_params: &ProtocolParameters,
protocol_version: u8,
network_id: u64,
issuing_time: u64,
slot_commitment_id: SlotCommitmentId,
latest_finalized_slot: SlotIndex,
issuer_id: IssuerId,
block: impl Into<Block>,
signature: impl Into<Signature>,
) -> Self {
let block = block.into();
let signature = signature.into();
let header = BlockHeader {
protocol_version: protocol_params.version(),
network_id: protocol_params.network_id(),
protocol_version,
network_id,
issuing_time,
slot_commitment_id,
latest_finalized_slot,
issuer_id,
};
let block = block.into();
let signature = signature.into();

Self {
id: Self::block_id(&header, &block, &signature, protocol_params),
header,
block,
signature,
Expand Down Expand Up @@ -195,15 +193,15 @@ impl BlockWrapper {
}

/// Computes the block identifier.
pub fn block_id(
block_header: &BlockHeader,
block: &Block,
signature: &Signature,
protocol_params: &ProtocolParameters,
) -> BlockId {
let id = [&block_header.hash()[..], &block.hash()[..], &signature.pack_to_vec()].concat();
pub fn id(&self, protocol_params: &ProtocolParameters) -> BlockId {
let id = [
&self.header.hash()[..],
&self.block.hash()[..],
&self.signature.pack_to_vec(),
]
.concat();
let block_hash = BlockHash::new(Blake2b256::digest(id).into());
block_hash.with_slot_index(protocol_params.slot_index(block_header.issuing_time()))
block_hash.with_slot_index(protocol_params.slot_index(self.header.issuing_time() / 1000000000))
}

/// Unpacks a [`BlockWrapper`] from a sequence of bytes doing syntactical checks and verifying that
Expand Down Expand Up @@ -271,7 +269,6 @@ impl Packable for BlockWrapper {
let signature = Signature::unpack::<_, VERIFY>(unpacker, &())?;

let wrapper = Self {
id: Self::block_id(&header, &block, &signature, protocol_params),
header,
block,
signature,
Expand Down Expand Up @@ -299,7 +296,7 @@ pub(crate) mod dto {

use super::*;
use crate::{
types::{block::core::dto::BlockDto, TryFromDto},
types::{block::core::dto::BlockDto, TryFromDto, ValidationParams},
utils::serde::string,
};

Expand Down Expand Up @@ -334,29 +331,35 @@ pub(crate) mod dto {
}
}

impl BlockWrapper {
pub fn try_from_dto(dto: BlockWrapperDto, protocol_params: ProtocolParameters) -> Result<Self, Error> {
if dto.protocol_version != protocol_params.version() {
return Err(Error::ProtocolVersionMismatch {
expected: protocol_params.version(),
actual: dto.protocol_version,
});
}

if dto.network_id != protocol_params.network_id() {
return Err(Error::NetworkIdMismatch {
expected: protocol_params.network_id(),
actual: dto.network_id,
});
impl TryFromDto for BlockWrapper {
type Dto = BlockWrapperDto;
type Error = Error;

fn try_from_dto_with_params_inner(dto: Self::Dto, params: ValidationParams<'_>) -> Result<Self, Self::Error> {
if let Some(protocol_params) = params.protocol_parameters() {
if dto.protocol_version != protocol_params.version() {
return Err(Error::ProtocolVersionMismatch {
expected: protocol_params.version(),
actual: dto.protocol_version,
});
}

if dto.network_id != protocol_params.network_id() {
return Err(Error::NetworkIdMismatch {
expected: protocol_params.network_id(),
actual: dto.network_id,
});
}
}

Ok(BlockWrapper::new(
&protocol_params,
dto.protocol_version,
dto.network_id,
dto.issuing_time,
dto.slot_commitment_id,
dto.latest_finalized_slot,
dto.issuer_id,
Block::try_from_dto_with_params(dto.block, &protocol_params)?,
Block::try_from_dto_with_params_inner(dto.block, params)?,
dto.signature,
))
}
Expand Down
3 changes: 2 additions & 1 deletion sdk/src/types/block/rand/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ pub fn rand_basic_block_builder_with_strong_parents(strong_parents: StrongParent
/// Generates a random block wrapper.
pub fn rand_block_wrapper_with_block(protocol_params: &ProtocolParameters, block: impl Into<Block>) -> BlockWrapper {
BlockWrapper::new(
protocol_params,
protocol_params.version(),
protocol_params.network_id(),
rand_number(),
rand_slot_commitment_id(),
rand_slot_index(),
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/types/block/slot/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl SlotIndex {
pub fn from_timestamp(timestamp: u64, genesis_unix_timestamp: u64, slot_duration_in_seconds: u8) -> SlotIndex {
timestamp
.checked_sub(genesis_unix_timestamp as u64)
.map(|diff| (diff / slot_duration_in_seconds as u64) + 1)
.map(|elapsed| (elapsed / slot_duration_in_seconds as u64) + 1)
.unwrap_or_default()
.into()
}
Expand Down
7 changes: 4 additions & 3 deletions sdk/src/wallet/account/operations/reissue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ where
) -> crate::wallet::Result<BlockId> {
log::debug!("[reissue_transaction_until_included]");

let protocol_parameters = self.client().get_protocol_parameters().await?;
let transaction = self.details().await.transactions.get(transaction_id).cloned();

if let Some(transaction) = transaction {
Expand Down Expand Up @@ -62,7 +63,7 @@ where
Some(Payload::Transaction(Box::new(transaction.payload.clone()))),
)
.await?
.id(),
.id(&protocol_parameters),
};

// Attachments of the Block to check inclusion state
Expand Down Expand Up @@ -111,7 +112,7 @@ where
Some(Payload::Transaction(Box::new(transaction.payload.clone()))),
)
.await?;
block_ids.push(reissued_block.id());
block_ids.push(reissued_block.id(&protocol_parameters));
}
}
// After we checked all our reissued blocks, check if the transaction got reissued in another block
Expand All @@ -127,7 +128,7 @@ where
e
}
})?;
return Ok(included_block.id());
return Ok(included_block.id(&protocol_parameters));
}
}
Err(ClientError::TangleInclusion(first_block_id.to_string()).into())
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/wallet/account/operations/syncing/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ where
confirmed_unknown_output = true;
updated_transaction_and_outputs(
transaction,
Some(included_block.id()),
Some(self.client().block_id(&included_block).await?),
// block metadata was Conflicting, but it's confirmed in another attachment
InclusionState::Confirmed,
&mut updated_transactions,
Expand Down
2 changes: 1 addition & 1 deletion sdk/tests/client/high_level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ async fn test_find_blocks() {
let blocks = client.find_blocks(&[block_id]).await.unwrap();

assert_eq!(blocks.len(), 1);
assert_eq!(blocks[0].id(), block_id);
assert_eq!(client.block_id(&blocks[0]).await.unwrap(), block_id);
}

#[ignore]
Expand Down
8 changes: 4 additions & 4 deletions sdk/tests/client/node_api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ const DEFAULT_DEVELOPMENT_SEED: &str = "0x256a818b2aac458941f7274985a410e57fb750
// Sends a tagged data block to the node to test against it.
async fn setup_tagged_data_block() -> BlockId {
let client = setup_client_with_node_health_ignored().await;

client
let block = client
.finish_basic_block_builder(
todo!("issuer id"),
todo!("block signature"),
Expand All @@ -37,8 +36,9 @@ async fn setup_tagged_data_block() -> BlockId {
))),
)
.await
.unwrap()
.id()
.unwrap();

client.block_id(&block).await.unwrap()
}

pub fn setup_secret_manager() -> SecretManager {
Expand Down
Loading

0 comments on commit 24a5524

Please sign in to comment.