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 work score trait and impls #1235

Merged
merged 60 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
80a2eda
add workscore calc
Alex6323 Sep 15, 2023
f7cffb6
Merge branch '2.0' into feat/workscore
Alex6323 Sep 15, 2023
29843e5
fix merge
Alex6323 Sep 15, 2023
5da94e4
finish calculations
Alex6323 Sep 19, 2023
9d8d0cd
nits
Alex6323 Sep 20, 2023
5cd1d54
merge import
Alex6323 Sep 20, 2023
8ade41a
Merge branch '2.0' into feat/workscore; Add WorkScore trait;
Alex6323 Sep 20, 2023
00ddccf
nits
Alex6323 Sep 20, 2023
cca95f3
Merge branch '2.0' into feat/workscore
Alex6323 Sep 20, 2023
ab3b9fe
rename trait fn
Alex6323 Oct 8, 2023
25f183c
Merge branch '2.0' into feat/workscore
Alex6323 Oct 9, 2023
830ff47
update work score computations
Alex6323 Oct 9, 2023
6306da5
nit
Alex6323 Oct 9, 2023
7e8a204
move work score types into own module
Alex6323 Oct 9, 2023
f917fd9
add and impl mana cost fn
Alex6323 Oct 9, 2023
1ee7870
PR suggestions 1
Alex6323 Oct 10, 2023
9b64653
Merge branch '2.0' into feat/workscore
Alex6323 Nov 6, 2023
7fe6244
Merge branch '2.0' into feat/workscore
Alex6323 Nov 6, 2023
8789e80
is_signature
Alex6323 Nov 9, 2023
0797c70
remove todo
Alex6323 Nov 9, 2023
1766d74
Merge branch '2.0' into feat/workscore
Alex6323 Nov 9, 2023
363a153
Merge branch 'upstream/2.0' into feat/workscore
Alex6323 Nov 20, 2023
fac3fd2
review 1
Alex6323 Nov 20, 2023
4665f7f
Merge branch '2.0' into feat/workscore
Alex6323 Nov 20, 2023
7aaae7d
review 2
Alex6323 Nov 20, 2023
d7929c6
review 3
Alex6323 Nov 20, 2023
ecf08e3
fix copyright year
Alex6323 Nov 20, 2023
7098d84
Merge branch '2.0' into feat/workscore
Alex6323 Nov 20, 2023
05edd44
Merge branch '2.0' into feat/workscore
Alex6323 Nov 20, 2023
15bfd4f
Merge branch '2.0' into feat/workscore
thibault-martinez Nov 21, 2023
711c35b
StorageScore :heart: WorkScore
Alex6323 Nov 21, 2023
8d6b744
Fix def_is_as_opt panic message (#1659)
thibault-martinez Nov 21, 2023
5f8e14f
Remove native tokens from AnchorOutput (#1660)
thibault-martinez Nov 21, 2023
21217b9
Python: add multi address (#1658)
Alex6323 Nov 21, 2023
e449156
fmt
Alex6323 Nov 21, 2023
f48a8cf
align + more impls
Alex6323 Nov 21, 2023
dc921e8
Merge branch '2.0' into feat/workscore
Alex6323 Nov 21, 2023
913a5b6
nit
Alex6323 Nov 21, 2023
87d56af
default impl for all features
Alex6323 Nov 22, 2023
9861038
default impl for all unlocks
Alex6323 Nov 22, 2023
d778512
self
Alex6323 Nov 22, 2023
751935c
Merge branch '2.0' into feat/workscore
Alex6323 Nov 22, 2023
620598b
Merge branch '2.0' into feat/workscore
thibault-martinez Nov 22, 2023
5d3d1e0
rm WorkScore impl for NativeTokens type
Alex6323 Nov 23, 2023
d23fb61
review suggestions
Alex6323 Nov 23, 2023
2fad332
align and improve
Alex6323 Nov 24, 2023
52dc638
cleanup
Alex6323 Nov 24, 2023
dfe23e9
Merge branch '2.0' into feat/workscore
Alex6323 Nov 24, 2023
01906c0
cleanup 2
Alex6323 Nov 24, 2023
3a303e0
forward work score in NativeTokenFeature
Alex6323 Nov 24, 2023
3fa452a
cleanup 3
Alex6323 Nov 24, 2023
d002ed1
forward 2
Alex6323 Nov 24, 2023
f5ee525
let's see if we're faster than thibault
Alex6323 Nov 24, 2023
f19d7dc
unnecessary import
Alex6323 Nov 24, 2023
80d2f38
underscore
Alex6323 Nov 24, 2023
34a0b99
Merge branch '2.0' into feat/workscore
Alex6323 Nov 24, 2023
787067c
final touches
Alex6323 Nov 24, 2023
ab6501e
remove todo
Alex6323 Nov 24, 2023
9f751e0
rm mana_cost fn from work score trait
Alex6323 Nov 27, 2023
80d982c
Merge branch '2.0' into feat/workscore
Alex6323 Nov 27, 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
2 changes: 1 addition & 1 deletion sdk/src/client/node_api/core/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ impl ClientInner {
/// Returns the information of committee members at the given epoch index. If epoch index is not provided, the
/// current committee members are returned.
/// GET /api/core/v3/committee/?epochIndex
pub async fn get_committee(&self, epoch_index: impl Into<Option<EpochIndex>>) -> Result<CommitteeResponse> {
pub async fn get_committee(&self, epoch_index: impl Into<Option<EpochIndex>> + Send) -> Result<CommitteeResponse> {
const PATH: &str = "api/core/v3/committee";

let epoch_index = epoch_index.into().map(|i| format!("epochIndex={i}"));
Expand Down
17 changes: 16 additions & 1 deletion sdk/src/types/block/core/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::types::block::{
core::{verify_parents, Block},
parent::{ShallowLikeParents, StrongParents, WeakParents},
payload::{OptionalPayload, Payload},
protocol::ProtocolParameters,
protocol::{ProtocolParameters, WorkScore, WorkScoreStructure},
Error,
};

Expand Down Expand Up @@ -141,6 +141,21 @@ impl BasicBlock {
}
}

impl WorkScore for BasicBlock {
fn workscore(&self, workscore_structure: WorkScoreStructure) -> u32 {
let mut score = workscore_structure.block;
let min_strong_parents_threshold = workscore_structure.min_strong_parents_threshold as usize;
if self.strong_parents.len() < min_strong_parents_threshold {
let missing_parents_count = min_strong_parents_threshold - self.strong_parents.len();
score += workscore_structure.missing_parent * missing_parents_count as u32;
}
if let Some(payload) = &*self.payload {
score += payload.workscore(workscore_structure);
}
score
}
}

impl Packable for BasicBlock {
type UnpackError = Error;
type UnpackVisitor = ProtocolParameters;
Expand Down
12 changes: 11 additions & 1 deletion sdk/src/types/block/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ pub use self::{
validation::{ValidationBlock, ValidationBlockBuilder},
wrapper::BlockWrapper,
};
use super::protocol::WorkScore;
thibault-martinez marked this conversation as resolved.
Show resolved Hide resolved
use crate::types::block::{
parent::{ShallowLikeParents, StrongParents, WeakParents},
protocol::{ProtocolParameters, ProtocolParametersHash},
protocol::{ProtocolParameters, ProtocolParametersHash, WorkScoreStructure},
Error,
};

Expand Down Expand Up @@ -105,6 +106,15 @@ impl Block {
}
}

impl WorkScore for Block {
fn workscore(&self, workscore_structure: WorkScoreStructure) -> u32 {
match self {
Self::Basic(basic) => basic.workscore(workscore_structure),
Self::Validation(validation) => validation.workscore(workscore_structure),
}
}
}

impl Packable for Block {
type UnpackError = Error;
type UnpackVisitor = ProtocolParameters;
Expand Down
9 changes: 8 additions & 1 deletion sdk/src/types/block/core/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use packable::{
use crate::types::block::{
core::{verify_parents, Block},
parent::{ShallowLikeParents, StrongParents, WeakParents},
protocol::{ProtocolParameters, ProtocolParametersHash},
protocol::{ProtocolParameters, ProtocolParametersHash, WorkScore, WorkScoreStructure},
Error,
};

Expand Down Expand Up @@ -146,6 +146,13 @@ impl ValidationBlock {
}
}

impl WorkScore for ValidationBlock {
fn workscore(&self, workscore_structure: WorkScoreStructure) -> u32 {
// The work score of a validation block is `0`.
0
}
}

impl Packable for ValidationBlock {
type UnpackError = Error;
type UnpackVisitor = ProtocolParameters;
Expand Down
21 changes: 19 additions & 2 deletions sdk/src/types/block/core/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use packable::{
use crate::types::block::{
block_id::{BlockHash, BlockId},
core::{BasicBlock, ValidationBlock},
protocol::ProtocolParameters,
protocol::{ProtocolParameters, WorkScore, WorkScoreStructure},
signature::Signature,
slot::{SlotCommitmentId, SlotIndex},
Block, Error, IssuerId,
Expand Down Expand Up @@ -51,6 +51,13 @@ impl BlockHeader {
}
}

impl WorkScore for BlockHeader {
fn workscore(&self, workscore_structure: WorkScoreStructure) -> u32 {
// The work score of a block header is `0`.
0
}
}

impl Packable for BlockHeader {
type UnpackError = Error;
type UnpackVisitor = ProtocolParameters;
Expand Down Expand Up @@ -246,6 +253,16 @@ impl BlockWrapper {
}
}

impl WorkScore for BlockWrapper {
fn workscore(&self, workscore_structure: WorkScoreStructure) -> u32 {
let mut score = workscore_structure.data_kilobyte * self.packed_len() as u32 / 1024;
score += self.header.workscore(workscore_structure);
score += self.block.workscore(workscore_structure);
score += self.signature.workscore(workscore_structure);
score
}
}

impl Packable for BlockWrapper {
type UnpackError = Error;
type UnpackVisitor = ProtocolParameters;
Expand Down Expand Up @@ -350,7 +367,7 @@ pub(crate) mod dto {
});
}

Ok(BlockWrapper::new(
Ok(Self::new(
&protocol_params,
dto.issuing_time,
dto.slot_commitment_id,
Expand Down
10 changes: 10 additions & 0 deletions sdk/src/types/block/payload/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub(crate) use self::{
tagged_data::{TagLength, TaggedDataLength},
transaction::{ContextInputCount, InputCount, OutputCount},
};
use super::protocol::{WorkScore, WorkScoreStructure};
use crate::types::block::{protocol::ProtocolParameters, Error};

/// A generic payload that can represent different types defining block payloads.
Expand Down Expand Up @@ -63,6 +64,15 @@ impl Payload {
}
}

impl WorkScore for Payload {
fn workscore(&self, workscore_structure: WorkScoreStructure) -> u32 {
match self {
Self::Transaction(transaction_payload) => transaction_payload.workscore(workscore_structure),
Self::TaggedData(tagged_data_payload) => tagged_data_payload.workscore(workscore_structure),
}
}
}

impl Packable for Payload {
type UnpackError = Error;
type UnpackVisitor = ProtocolParameters;
Expand Down
12 changes: 11 additions & 1 deletion sdk/src/types/block/payload/tagged_data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ use packable::{
Packable,
};

use crate::types::block::{BlockWrapper, Error};
use crate::types::block::{
protocol::{WorkScore, WorkScoreStructure},
BlockWrapper, Error,
};

pub(crate) type TagLength =
BoundedU8<{ *TaggedDataPayload::TAG_LENGTH_RANGE.start() }, { *TaggedDataPayload::TAG_LENGTH_RANGE.end() }>;
Expand Down Expand Up @@ -60,6 +63,13 @@ impl TaggedDataPayload {
}
}

impl WorkScore for TaggedDataPayload {
fn workscore(&self, workscore_structure: WorkScoreStructure) -> u32 {
// The work score of a tagged data payload is `0`.
0
}
}

impl core::fmt::Debug for TaggedDataPayload {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("TaggedDataPayload")
Expand Down
31 changes: 29 additions & 2 deletions sdk/src/types/block/payload/transaction/essence/regular.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ use crate::types::{
context_input::{ContextInput, CONTEXT_INPUT_COUNT_RANGE},
input::{Input, INPUT_COUNT_RANGE},
mana::{verify_mana_allotments_sum, ManaAllotment, ManaAllotments},
output::{InputsCommitment, NativeTokens, Output, OUTPUT_COUNT_RANGE},
output::{Feature, InputsCommitment, NativeTokens, Output, TokenScheme, OUTPUT_COUNT_RANGE},
payload::{OptionalPayload, Payload},
protocol::ProtocolParameters,
protocol::{ProtocolParameters, WorkScore, WorkScoreStructure},
slot::SlotIndex,
Error,
},
Expand Down Expand Up @@ -274,6 +274,33 @@ impl RegularTransactionEssence {
}
}

impl WorkScore for RegularTransactionEssence {
fn workscore(&self, workscore_structure: WorkScoreStructure) -> u32 {
let mut score = self.inputs().len() as u32 * workscore_structure.input;
score += self.context_inputs().len() as u32 * workscore_structure.context_input;
for output in self.outputs() {
score += workscore_structure.output;
if let Some(nts) = output.native_tokens() {
score += nts.len() as u32 * workscore_structure.native_token;
}
if matches!(output, Output::Foundry(foundry) if foundry.token_scheme().is_simple()) {
score += workscore_structure.native_token
}
if let Some(features) = output.features() {
for feature in features.iter() {
score += match feature {
Feature::BlockIssuer(_) => workscore_structure.block_issuer,
Feature::Staking(_) => workscore_structure.staking,
_ => 0,
}
}
}
}
score += self.mana_allotments().len() as u32 * workscore_structure.allotment;
score
}
}

fn verify_network_id<const VERIFY: bool>(network_id: &u64, visitor: &ProtocolParameters) -> Result<(), Error> {
if VERIFY {
let expected = visitor.network_id();
Expand Down
18 changes: 17 additions & 1 deletion sdk/src/types/block/payload/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ pub use self::{
essence::{RegularTransactionEssence, RegularTransactionEssenceBuilder, TransactionEssence},
transaction_id::TransactionId,
};
use crate::types::block::{protocol::ProtocolParameters, unlock::Unlocks, Error};
use crate::types::block::{
protocol::{ProtocolParameters, WorkScore, WorkScoreStructure},
unlock::{Unlock, Unlocks},
Error,
};

/// A transaction to move funds.
#[derive(Clone, Debug, Eq, PartialEq)]
Expand Down Expand Up @@ -55,6 +59,18 @@ impl TransactionPayload {
}
}

impl WorkScore for TransactionPayload {
fn workscore(&self, workscore_structure: WorkScoreStructure) -> u32 {
let mut score = self.essence().workscore(workscore_structure);
for unlock in self.unlocks.iter() {
if matches!(unlock, Unlock::Signature(_)) {
score += workscore_structure.signature_ed25519;
}
}
score
}
}

impl Packable for TransactionPayload {
type UnpackError = Error;
type UnpackVisitor = ProtocolParameters;
Expand Down
31 changes: 18 additions & 13 deletions sdk/src/types/block/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,30 +179,30 @@ impl ProtocolParameters {
#[packable(unpack_error = Error)]
#[getset(get_copy = "pub")]
pub struct WorkScoreStructure {
/// Modifier for network traffic per byte.
data_kilobyte: u32,
/// Modifier for network traffic per kilobyte.
pub(crate) data_kilobyte: u32,
/// Modifier for work done to process a block.
block: u32,
pub(crate) block: u32,
/// Modifier for slashing when there are insufficient strong tips.
missing_parent: u32,
pub(crate) missing_parent: u32,
/// Modifier for loading UTXOs and performing mana calculations.
input: u32,
pub(crate) input: u32,
/// Modifier for loading and checking the context input.
context_input: u32,
pub(crate) context_input: u32,
/// Modifier for storing UTXOs.
output: u32,
pub(crate) output: u32,
/// Modifier for calculations using native tokens.
native_token: u32,
pub(crate) native_token: u32,
/// Modifier for storing staking features.
staking: u32,
pub(crate) staking: u32,
/// Modifier for storing block issuer features.
block_issuer: u32,
pub(crate) block_issuer: u32,
/// Modifier for accessing the account-based ledger to transform mana to Block Issuance Credits.
allotment: u32,
pub(crate) allotment: u32,
/// Modifier for the block signature check.
signature_ed25519: u32,
pub(crate) signature_ed25519: u32,
/// The minimum count of strong parents in a basic block.
min_strong_parents_threshold: u8,
pub(crate) min_strong_parents_threshold: u8,
}

impl Default for WorkScoreStructure {
Expand All @@ -224,6 +224,11 @@ impl Default for WorkScoreStructure {
}
}

/// A trait to facilitate the computation of the work score of a block, which is central to mana cost calculation.
pub trait WorkScore {
fn workscore(&self, workscore_structure: WorkScoreStructure) -> u32;
DaughterOfMars marked this conversation as resolved.
Show resolved Hide resolved
}

/// Defines the parameters used to calculate the Reference Mana Cost (RMC).
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Packable, CopyGetters)]
#[cfg_attr(
Expand Down
9 changes: 9 additions & 0 deletions sdk/src/types/block/signature/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ mod ed25519;
use derive_more::From;

pub use self::ed25519::Ed25519Signature;
use super::protocol::{WorkScore, WorkScoreStructure};
use crate::types::block::Error;

/// A `Signature` contains a signature which is used to unlock a transaction input.
Expand Down Expand Up @@ -51,3 +52,11 @@ impl Signature {
sig
}
}

impl WorkScore for Signature {
fn workscore(&self, workscore_structure: WorkScoreStructure) -> u32 {
match self {
Self::Ed25519(_) => workscore_structure.signature_ed25519,
}
}
}
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 @@ -60,7 +60,7 @@ impl SlotIndex {

/// Gets the slot index of a unix timestamp.
/// Slots are counted starting from `1` with `0` being reserved for times before the genesis.
pub fn from_timestamp(timestamp: u64, genesis_unix_timestamp: u64, slot_duration_in_seconds: u8) -> SlotIndex {
pub fn from_timestamp(timestamp: u64, genesis_unix_timestamp: u64, slot_duration_in_seconds: u8) -> Self {
timestamp
.checked_sub(genesis_unix_timestamp as u64)
.map(|diff| (diff / slot_duration_in_seconds as u64) + 1)
Expand Down