Skip to content

Commit 02f7400

Browse files
committed
Merge branch 'main' into golddydev/stake-addresses-in-spo-state
2 parents 5af169f + 260c00f commit 02f7400

File tree

43 files changed

+880
-131
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+880
-131
lines changed

Cargo.lock

Lines changed: 17 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ members = [
2020
"modules/stake_delta_filter", # Filters address deltas
2121
"modules/epoch_activity_counter", # Counts fees and block producers for rewards
2222
"modules/accounts_state", # Tracks stake and reward accounts
23+
"modules/assets_state", # Tracks native asset mints and burns
2324

2425
# Process builds
2526
"processes/omnibus", # All-inclusive omnibus process

common/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ tracing = "0.1.40"
3333
futures = "0.3.31"
3434
minicbor = { version = "0.26.0", features = ["std", "half", "derive"] }
3535
num-traits = "0.2"
36+
imbl = { version = "5.0.0", features = ["serde"] }
3637

3738
[lib]
3839
crate-type = ["rlib"]

common/src/calculations.rs

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,86 @@
11
//! Common calculations for Cardano
22
33
const BYRON_SLOTS_PER_EPOCH: u64 = 21_600;
4-
pub const SHELLEY_SLOTS_PER_EPOCH: u64 = 432_000;
5-
const SHELLEY_START_SLOT: u64 = 4_492_800;
6-
const SHELLEY_START_EPOCH: u64 = 208;
74

85
/// Derive an epoch number from a slot, handling Byron/Shelley era changes
9-
pub fn slot_to_epoch(slot: u64) -> u64 {
10-
slot_to_epoch_with_shelley_params(slot, SHELLEY_START_EPOCH, SHELLEY_SLOTS_PER_EPOCH)
11-
}
12-
136
pub fn slot_to_epoch_with_shelley_params(
147
slot: u64,
158
shelley_epoch: u64,
169
shelley_epoch_len: u64,
17-
) -> u64 {
10+
) -> (u64, u64) {
1811
let shelley_start_slot = shelley_epoch * BYRON_SLOTS_PER_EPOCH;
1912
if slot < shelley_start_slot {
20-
slot / BYRON_SLOTS_PER_EPOCH
13+
(slot / BYRON_SLOTS_PER_EPOCH, slot % BYRON_SLOTS_PER_EPOCH)
2114
} else {
22-
shelley_epoch + (slot - shelley_start_slot) / shelley_epoch_len
15+
let slots_since_shelley_start = slot - shelley_start_slot;
16+
(
17+
shelley_epoch + slots_since_shelley_start / shelley_epoch_len,
18+
slots_since_shelley_start % shelley_epoch_len,
19+
)
20+
}
21+
}
22+
23+
pub fn slot_to_timestamp_with_params(slot: u64, byron_timestamp: u64, shelley_epoch: u64) -> u64 {
24+
let shelley_start_slot = shelley_epoch * BYRON_SLOTS_PER_EPOCH;
25+
if slot < shelley_start_slot {
26+
byron_timestamp + slot * 20
27+
} else {
28+
let shelley_timestamp = byron_timestamp + shelley_start_slot * 20;
29+
shelley_timestamp + (slot - shelley_start_slot)
2330
}
2431
}
2532

2633
// -- Tests --
2734
#[cfg(test)]
2835
mod tests {
2936
use super::*;
37+
const SHELLEY_START_EPOCH: u64 = 208;
38+
const SHELLEY_SLOTS_PER_EPOCH: u64 = 432_000;
39+
const BYRON_START_TIMESTAMP: u64 = 1506203091;
40+
41+
fn slot_to_epoch(slot: u64) -> (u64, u64) {
42+
slot_to_epoch_with_shelley_params(slot, SHELLEY_START_EPOCH, SHELLEY_SLOTS_PER_EPOCH)
43+
}
44+
45+
fn slot_to_timestamp(slot: u64) -> u64 {
46+
slot_to_timestamp_with_params(slot, BYRON_START_TIMESTAMP, SHELLEY_START_EPOCH)
47+
}
3048

3149
#[test]
3250
fn byron_epoch_0() {
33-
assert_eq!(0, slot_to_epoch(0));
51+
assert_eq!(slot_to_epoch(0), (0, 0));
52+
assert_eq!(slot_to_timestamp(0), 1506203091);
3453
}
3554

3655
#[test]
3756
fn byron_epoch_1() {
38-
assert_eq!(1, slot_to_epoch(21_600));
57+
assert_eq!(slot_to_epoch(21_600), (1, 0));
58+
assert_eq!(slot_to_timestamp(21_600), 1506635091);
3959
}
4060

4161
#[test]
4262
fn byron_last_slot() {
43-
assert_eq!(slot_to_epoch(4_492_799), 207);
63+
assert_eq!(slot_to_epoch(4_492_799), (207, 21_599));
64+
assert_eq!(slot_to_timestamp(4_492_799), 1596059071);
4465
}
4566

4667
#[test]
4768
fn shelley_first_slot() {
48-
assert_eq!(slot_to_epoch(4_492_800), 208);
69+
assert_eq!(slot_to_epoch(4_492_800), (208, 0));
70+
assert_eq!(slot_to_timestamp(4_492_800), 1596059091);
4971
}
5072

5173
#[test]
5274
fn shelley_epoch_209_start() {
5375
// 432_000 slots later
54-
assert_eq!(slot_to_epoch(4_492_800 + 432_000), 209);
55-
}
56-
57-
#[test]
58-
fn before_transition_boundary() {
59-
// One slot before Shelley starts
60-
assert_eq!(slot_to_epoch(4_492_799), 207);
61-
}
62-
63-
#[test]
64-
fn after_transition_boundary() {
65-
// First Shelley slot
66-
assert_eq!(slot_to_epoch(4_492_800), 208);
76+
assert_eq!(slot_to_epoch(4_492_800 + 432_000), (209, 0));
77+
assert_eq!(slot_to_timestamp(4_492_800 + 432_000), 1596491091);
6778
}
6879

6980
#[test]
7081
fn mainnet_example_from_cexplorer() {
7182
// Slot 98_272_003 maps to epoch 425
72-
assert_eq!(slot_to_epoch(98_272_003), 425);
83+
assert_eq!(slot_to_epoch(98_272_003), (425, 35_203));
84+
assert_eq!(slot_to_timestamp(98_272_003), 1689838294);
7385
}
7486
}

common/src/genesis_values.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use crate::calculations::{slot_to_epoch_with_shelley_params, slot_to_timestamp_with_params};
2+
3+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
4+
pub struct GenesisValues {
5+
pub byron_timestamp: u64,
6+
pub shelley_epoch: u64,
7+
pub shelley_epoch_len: u64,
8+
}
9+
10+
impl GenesisValues {
11+
pub fn mainnet() -> Self {
12+
Self {
13+
byron_timestamp: 1506203091,
14+
shelley_epoch: 208,
15+
shelley_epoch_len: 432000,
16+
}
17+
}
18+
19+
pub fn slot_to_epoch(&self, slot: u64) -> (u64, u64) {
20+
slot_to_epoch_with_shelley_params(slot, self.shelley_epoch, self.shelley_epoch_len)
21+
}
22+
pub fn slot_to_timestamp(&self, slot: u64) -> u64 {
23+
slot_to_timestamp_with_params(slot, self.byron_timestamp, self.shelley_epoch)
24+
}
25+
}

common/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ pub mod address;
44
pub mod calculations;
55
pub mod cip19;
66
pub mod crypto;
7+
pub mod genesis_values;
78
pub mod ledger_state;
89
pub mod messages;
910
pub mod params;

common/src/messages.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// We don't use these messages in the acropolis_common crate itself
44
#![allow(dead_code)]
55

6+
use crate::genesis_values::GenesisValues;
67
use crate::ledger_state::SPOState;
78
use crate::protocol_params::ProtocolParams;
89
use crate::queries::parameters::{ParametersStateQuery, ParametersStateQueryResponse};
@@ -58,7 +59,9 @@ pub struct RawTxsMessage {
5859

5960
/// Genesis completion message
6061
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
61-
pub struct GenesisCompleteMessage {}
62+
pub struct GenesisCompleteMessage {
63+
pub values: GenesisValues,
64+
}
6265

6366
/// Message encapsulating multiple UTXO deltas, in order
6467
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
@@ -67,6 +70,13 @@ pub struct UTXODeltasMessage {
6770
pub deltas: Vec<UTXODelta>,
6871
}
6972

73+
/// Message encapsulating multiple asset deltas
74+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
75+
pub struct AssetDeltasMessage {
76+
/// Ordered set of deltas
77+
pub deltas: NativeAssetsDelta,
78+
}
79+
7080
/// Message encapsulating multiple transaction certificates, in order
7181
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
7282
pub struct TxCertificatesMessage {
@@ -225,6 +235,7 @@ pub enum CardanoMessage {
225235
ReceivedTxs(RawTxsMessage), // Transaction available
226236
GenesisComplete(GenesisCompleteMessage), // Genesis UTXOs done + genesis params
227237
UTXODeltas(UTXODeltasMessage), // UTXO deltas received
238+
AssetDeltas(AssetDeltasMessage), // Asset mint and burn deltas
228239
TxCertificates(TxCertificatesMessage), // Transaction certificates received
229240
AddressDeltas(AddressDeltasMessage), // Address deltas received
230241
Withdrawals(WithdrawalsMessage), // Withdrawals from reward accounts

common/src/protocol_params.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ pub struct ShelleyProtocolParams {
6666
pub minfee_b: u32,
6767
pub pool_deposit: u64,
6868

69-
/// AKA desired_number_of_stake_pools, n_opt, technical parameter k
69+
/// AKA desired_number_of_stake_pools, optimal_pool_count, n_opt, technical parameter k
7070
/// Important: *not to be mixed* with security parameter k, which is not here
7171
#[serde(rename = "nOpt")]
7272
pub stake_pool_target_num: u32,

common/src/queries/assets.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
use crate::{AssetName, PolicyId};
2+
3+
pub const DEFAULT_ASSETS_QUERY_TOPIC: (&str, &str) =
4+
("assets-state-query-topic", "cardano.query.assets");
5+
16
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
27
pub enum AssetsStateQuery {
38
GetAssetsList,
@@ -10,7 +15,7 @@ pub enum AssetsStateQuery {
1015

1116
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
1217
pub enum AssetsStateQueryResponse {
13-
AssetsList(AssetsList),
18+
AssetsList(imbl::HashMap<PolicyId, imbl::HashMap<AssetName, u64>>),
1419
AssetInfo(AssetInfo),
1520
AssetHistory(AssetHistory),
1621
AssetTransactions(AssetTransactions),

common/src/types.rs

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,15 @@ pub struct BlockInfo {
101101
/// Epoch number
102102
pub epoch: u64,
103103

104+
/// Epoch slot number
105+
pub epoch_slot: u64,
106+
104107
/// Does this block start a new epoch?
105108
pub new_epoch: bool,
106109

110+
/// UNIX timestamp
111+
pub timestamp: u64,
112+
107113
/// Protocol era
108114
pub era: Era,
109115
}
@@ -147,6 +153,23 @@ pub struct StakeRewardDelta {
147153
pub delta: i64,
148154
}
149155

156+
pub type PolicyId = [u8; 28];
157+
pub type NativeAssets = Vec<(PolicyId, Vec<NativeAsset>)>;
158+
pub type NativeAssetsDelta = Vec<(PolicyId, Vec<NativeAssetDelta>)>;
159+
pub type AssetName = Vec<u8>;
160+
161+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
162+
pub struct NativeAsset {
163+
pub name: AssetName,
164+
pub amount: u64,
165+
}
166+
167+
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
168+
pub struct NativeAssetDelta {
169+
pub name: AssetName,
170+
pub amount: i64,
171+
}
172+
150173
/// Value (lovelace + multiasset)
151174
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
152175
pub struct Value {
@@ -167,11 +190,11 @@ impl Value {
167190
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
168191
pub struct ValueDelta {
169192
pub lovelace: i64,
170-
pub assets: Vec<(PolicyId, Vec<NativeAssetDelta>)>,
193+
pub assets: NativeAssetsDelta,
171194
}
172195

173196
impl ValueDelta {
174-
pub fn new(lovelace: i64, assets: Vec<(PolicyId, Vec<NativeAssetDelta>)>) -> Self {
197+
pub fn new(lovelace: i64, assets: NativeAssetsDelta) -> Self {
175198
Self { lovelace, assets }
176199
}
177200
}
@@ -212,23 +235,6 @@ impl Neg for ValueDelta {
212235
}
213236
}
214237

215-
pub type PolicyId = [u8; 28];
216-
pub type NativeAssets = Vec<(PolicyId, Vec<NativeAsset>)>;
217-
pub type NativeAssetsDelta = Vec<(PolicyId, Vec<NativeAssetDelta>)>;
218-
pub type AssetName = Vec<u8>;
219-
220-
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
221-
pub struct NativeAsset {
222-
pub name: AssetName,
223-
pub amount: u64,
224-
}
225-
226-
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
227-
pub struct NativeAssetDelta {
228-
pub name: AssetName,
229-
pub amount: i64,
230-
}
231-
232238
/// Transaction output (UTXO)
233239
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
234240
pub struct TxOutput {

0 commit comments

Comments
 (0)