1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use core::mem::size_of;
use crate::{output::OutputId, payload::milestone::MilestoneIndex, BlockId};
const DEFAULT_BYTE_COST: u64 = 500;
const DEFAULT_BYTE_COST_FACTOR_KEY: u64 = 10;
const DEFAULT_BYTE_COST_FACTOR_DATA: u64 = 1;
type ConfirmationUnixTimestamp = u32;
#[derive(Default, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[must_use]
pub struct ByteCostConfigBuilder {
#[cfg_attr(feature = "serde", serde(alias = "vByteCost"))]
v_byte_cost: Option<u64>,
#[cfg_attr(feature = "serde", serde(alias = "vByteFactorKey"))]
v_byte_factor_key: Option<u64>,
#[cfg_attr(feature = "serde", serde(alias = "vByteFactorData"))]
v_byte_factor_data: Option<u64>,
}
impl ByteCostConfigBuilder {
pub fn new() -> Self {
Default::default()
}
pub fn byte_cost(mut self, byte_cost: u64) -> Self {
self.v_byte_cost.replace(byte_cost);
self
}
pub fn key_factor(mut self, weight: u64) -> Self {
self.v_byte_factor_key.replace(weight);
self
}
pub fn data_factor(mut self, weight: u64) -> Self {
self.v_byte_factor_data.replace(weight);
self
}
pub fn finish(self) -> ByteCostConfig {
let v_byte_factor_key = self.v_byte_factor_key.unwrap_or(DEFAULT_BYTE_COST_FACTOR_KEY);
let v_byte_factor_data = self.v_byte_factor_data.unwrap_or(DEFAULT_BYTE_COST_FACTOR_DATA);
let v_byte_offset = size_of::<OutputId>() as u64 * v_byte_factor_key
+ size_of::<BlockId>() as u64 * v_byte_factor_data
+ size_of::<MilestoneIndex>() as u64 * v_byte_factor_data
+ size_of::<ConfirmationUnixTimestamp>() as u64 * v_byte_factor_data;
ByteCostConfig {
v_byte_cost: self.v_byte_cost.unwrap_or(DEFAULT_BYTE_COST),
v_byte_factor_key,
v_byte_factor_data,
v_byte_offset,
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ByteCostConfig {
pub v_byte_cost: u64,
pub v_byte_factor_key: u64,
pub v_byte_factor_data: u64,
v_byte_offset: u64,
}
impl ByteCostConfig {
pub fn build() -> ByteCostConfigBuilder {
ByteCostConfigBuilder::new()
}
}
pub trait ByteCost {
fn weighted_bytes(&self, config: &ByteCostConfig) -> u64;
fn byte_cost(&self, config: &ByteCostConfig) -> u64 {
config.v_byte_cost * (self.weighted_bytes(config) + config.v_byte_offset)
}
}
impl<T: ByteCost, const N: usize> ByteCost for [T; N] {
fn weighted_bytes(&self, config: &ByteCostConfig) -> u64 {
self.iter().map(|elem| elem.weighted_bytes(config)).sum()
}
}