diff --git a/bindings/core/src/method/utils.rs b/bindings/core/src/method/utils.rs index 9eacde8567..30374ec523 100644 --- a/bindings/core/src/method/utils.rs +++ b/bindings/core/src/method/utils.rs @@ -13,7 +13,7 @@ use iota_sdk::{ dto::{SignedTransactionPayloadDto, TransactionDto}, TransactionId, }, - protocol::ProtocolParameters, + protocol::{ProtocolParameters, WorkScoreParameters}, signature::Ed25519Signature, slot::{SlotCommitment, SlotIndex}, unlock::Unlock, @@ -187,4 +187,13 @@ pub enum UtilsMethod { }, IotaMainnetProtocolParameters, ShimmerMainnetProtocolParameters, + /// Returns the work score of a block. + /// Expected response: [`WorkScore`](crate::Response::WorkScore) + #[serde(rename_all = "camelCase")] + BlockWorkScore { + /// Block + block: BlockDto, + /// Work score parameters + work_score_parameters: WorkScoreParameters, + }, } diff --git a/bindings/core/src/method_handler/utils.rs b/bindings/core/src/method_handler/utils.rs index 8933f10600..57e31fb54a 100644 --- a/bindings/core/src/method_handler/utils.rs +++ b/bindings/core/src/method_handler/utils.rs @@ -13,9 +13,10 @@ use iota_sdk::{ input::UtxoInput, output::{FoundryId, MinimumOutputAmount, Output, OutputId, TokenId}, payload::{signed_transaction::Transaction, SignedTransactionPayload}, + protocol::WorkScore, semantic::SemanticValidationContext, signature::SignatureError, - Block, + Block, BlockBody, }, TryFromDto, }, @@ -169,6 +170,18 @@ pub(crate) fn call_utils_method_internal(method: UtilsMethod) -> Result Response::ProtocolParameters( iota_sdk::types::block::protocol::shimmer_mainnet_protocol_parameters().clone(), ), + UtilsMethod::BlockWorkScore { + block, + work_score_parameters, + } => { + let block = Block::try_from_dto(block)?; + let work_score = match block.body() { + BlockBody::Basic(basic) => basic.work_score(work_score_parameters), + // Validation blocks have a work score of 0. + BlockBody::Validation(_validation) => 0, + }; + Response::WorkScore(work_score) + } }; Ok(response) diff --git a/bindings/core/src/response.rs b/bindings/core/src/response.rs index 928e877dfc..9523642b78 100644 --- a/bindings/core/src/response.rs +++ b/bindings/core/src/response.rs @@ -225,6 +225,8 @@ pub enum Response { CustomJson(serde_json::Value), /// Response for [`ComputeSlotCommitmentId`](crate::method::UtilsMethod::ComputeSlotCommitmentId) SlotCommitmentId(SlotCommitmentId), + /// Response for [`BlockWorkScore`](crate::method::UtilsMethod::BlockWorkScore) + WorkScore(u32), // Responses in client and wallet /// Response for: diff --git a/bindings/nodejs/CHANGELOG.md b/bindings/nodejs/CHANGELOG.md index a4b670d13a..7a8cb85589 100644 --- a/bindings/nodejs/CHANGELOG.md +++ b/bindings/nodejs/CHANGELOG.md @@ -21,6 +21,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## 2.0.0-alpha.2 - 2024-MM-DD +### Added + +- `Utils::blockWorkScore()`; + ### Fixed - `RestrictedAddress` discriminator usage; diff --git a/bindings/nodejs/lib/types/utils/bridge/index.ts b/bindings/nodejs/lib/types/utils/bridge/index.ts index 22de248ba6..59191cedab 100644 --- a/bindings/nodejs/lib/types/utils/bridge/index.ts +++ b/bindings/nodejs/lib/types/utils/bridge/index.ts @@ -28,6 +28,7 @@ import type { __BlockBytes__, __IotaMainnetProtocolParameters__, __ShimmerMainnetProtocolParameters__, + __BlockWorkScore__, } from './utils'; export type __UtilsMethods__ = @@ -59,4 +60,5 @@ export type __UtilsMethods__ = | __VerifyTransactionSyntax__ | __BlockBytes__ | __IotaMainnetProtocolParameters__ - | __ShimmerMainnetProtocolParameters__; + | __ShimmerMainnetProtocolParameters__ + | __BlockWorkScore__; diff --git a/bindings/nodejs/lib/types/utils/bridge/utils.ts b/bindings/nodejs/lib/types/utils/bridge/utils.ts index b27576946e..82d8123e69 100644 --- a/bindings/nodejs/lib/types/utils/bridge/utils.ts +++ b/bindings/nodejs/lib/types/utils/bridge/utils.ts @@ -17,6 +17,7 @@ import { import { AccountId } from '../../block/id'; import { SlotCommitment } from '../../block/slot'; import { InputSigningData } from '../../client'; +import { WorkScoreParameters } from '../../models'; import { NumericString } from '../numeric'; export interface __GenerateMnemonicMethod__ { @@ -242,3 +243,11 @@ export interface __IotaMainnetProtocolParameters__ { export interface __ShimmerMainnetProtocolParameters__ { name: 'shimmerMainnetProtocolParameters'; } + +export interface __BlockWorkScore__ { + name: 'blockWorkScore'; + data: { + block: Block; + workScoreParameters: WorkScoreParameters; + }; +} diff --git a/bindings/nodejs/lib/utils/utils.ts b/bindings/nodejs/lib/utils/utils.ts index d70e553722..d32e660f7e 100644 --- a/bindings/nodejs/lib/utils/utils.ts +++ b/bindings/nodejs/lib/utils/utils.ts @@ -22,6 +22,7 @@ import { DecayedMana, NumericString, Ed25519Address, + WorkScoreParameters, } from '../types'; import { AccountId, @@ -638,4 +639,24 @@ export class Utils { }); return params; } + + /** + * Returns the work score of a block. + * + * @param block The block. + * @param workScoreParameters The WorkScoreParameters. + * @returns The work score of the block. + */ + static blockWorkScore( + block: Block, + workScoreParameters: WorkScoreParameters, + ): number { + return callUtilsMethod({ + name: 'blockWorkScore', + data: { + block, + workScoreParameters, + }, + }); + } } diff --git a/bindings/nodejs/tests/utils/utils.spec.ts b/bindings/nodejs/tests/utils/utils.spec.ts index 683f93de8b..5b517f7de8 100644 --- a/bindings/nodejs/tests/utils/utils.spec.ts +++ b/bindings/nodejs/tests/utils/utils.spec.ts @@ -8,8 +8,11 @@ import 'dotenv/config'; import { BasicOutput, BlockId, OutputId, TransactionId, Utils } from '../../out'; import '../customMatchers'; import { SlotCommitment } from '../../out/types/block/slot'; -import * as protocol_parameters from '../../../../sdk/tests/types/fixtures/protocol_parameters.json'; import { ProtocolParameters } from '../../lib/types/models/api'; +import * as protocol_parameters from '../../../../sdk/tests/types/fixtures/protocol_parameters.json'; +import * as basic_block_transaction_payload_json from '../../../../sdk/tests/types/fixtures/basic_block_transaction_payload.json'; +import * as validation_block_json from '../../../../sdk/tests/types/fixtures/validation_block.json'; +import { parseBlock } from '../../lib'; describe('Utils methods', () => { it('invalid mnemonic error', () => { @@ -147,4 +150,15 @@ describe('Utils methods', () => { BigInt(output.amount) - minimumOutputAmount, creationSlot, targetSlot, protocolParameters) expect(decayedPotentialMana).toBe(BigInt(2502459)); }); + + it('compute block work score', async () => { + const block = parseBlock(basic_block_transaction_payload_json.block); + const workScore = Utils.blockWorkScore(block, protocol_parameters.params.workScoreParameters); + expect(workScore).toEqual(basic_block_transaction_payload_json.workScore); + + const validationBlock = parseBlock(validation_block_json.block); + const validationBlockWorkScore = Utils.blockWorkScore(validationBlock, protocol_parameters.params.workScoreParameters); + expect(validationBlockWorkScore).toEqual(0); + }); + }); diff --git a/bindings/python/iota_sdk/utils.py b/bindings/python/iota_sdk/utils.py index 2ed5a9466e..742fbbd576 100644 --- a/bindings/python/iota_sdk/utils.py +++ b/bindings/python/iota_sdk/utils.py @@ -11,7 +11,7 @@ from iota_sdk.types.common import HexStr from iota_sdk.types.decayed_mana import DecayedMana from iota_sdk.types.payload import Transaction, SignedTransactionPayload -from iota_sdk.types.node_info import ProtocolParameters +from iota_sdk.types.node_info import ProtocolParameters, WorkScoreParameters from iota_sdk.types.output import Output from iota_sdk.types.output_id import OutputId from iota_sdk.types.unlock import Unlock @@ -286,6 +286,16 @@ def shimmer_mainnet_protocol_parameters() -> ProtocolParameters: return ProtocolParameters.from_dict( _call_method('shimmerMainnetProtocolParameters')) + @staticmethod + def block_work_score( + block: Block, work_score_parameters: WorkScoreParameters) -> int: + """Returns the work score of a block. + """ + return _call_method('blockWorkScore', { + 'block': block, + 'workScoreParameters': work_score_parameters, + }) + class UtilsError(Exception): """A utils error.""" diff --git a/bindings/python/tests/test_block.py b/bindings/python/tests/test_block.py index e630e73155..8642e2533d 100644 --- a/bindings/python/tests/test_block.py +++ b/bindings/python/tests/test_block.py @@ -2,22 +2,24 @@ # SPDX-License-Identifier: Apache-2.0 import json -# from iota_sdk import Block, ProtocolParameters +from iota_sdk import Block, ProtocolParameters, Utils protocol_params_json = {} with open('../../sdk/tests/types/fixtures/protocol_parameters.json', "r", encoding="utf-8") as params: protocol_params_json = json.load(params) -# def test_basic_block_tagged_data_payload(): -# basic_block_tagged_data_payload_json = {} -# with open('../../sdk/tests/types/fixtures/basic_block_tagged_data_payload.json', "r", encoding="utf-8") as payload: -# basic_block_tagged_data_payload_json = json.load(payload) -# block = Block.from_dict(basic_block_tagged_data_payload_json['block']) -# protocol_params = ProtocolParameters.from_dict( -# protocol_params_json['params']) -# expected_id = basic_block_tagged_data_payload_json['id'] -# assert block.id(protocol_params) == expected_id +def test_basic_block_tagged_data_payload(): + basic_block_tagged_data_payload_json = {} + with open('../../sdk/tests/types/fixtures/basic_block_tagged_data_payload.json', "r", encoding="utf-8") as payload: + basic_block_tagged_data_payload_json = json.load(payload) + block = Block.from_dict(basic_block_tagged_data_payload_json['block']) + protocol_params = ProtocolParameters.from_dict( + protocol_params_json['params']) + expected_id = basic_block_tagged_data_payload_json['id'] + assert block.id(protocol_params) == expected_id + assert Utils.block_work_score( + block, protocol_params.work_score_parameters) == basic_block_tagged_data_payload_json['workScore'] # def test_basic_block_transaction_payload():