Skip to content

Commit cb30d62

Browse files
authored
Implement snapshot integration test (#275)
* update catalyst-toolbox
1 parent 525ec37 commit cb30d62

File tree

42 files changed

+601
-302
lines changed

Some content is hidden

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

42 files changed

+601
-302
lines changed

Cargo.lock

+91-59
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

iapyx/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ jormungandr-automation = { git = "https://github.com/input-output-hk/jormungandr
3131
thor = { git = "https://github.com/input-output-hk/jormungandr.git", branch = "master" }
3232
hersir = { git = "https://github.com/input-output-hk/jormungandr.git", branch = "master" }
3333
jortestkit = { git = "https://github.com/input-output-hk/jortestkit.git", branch = "master" }
34-
catalyst-toolbox = { git = "https://github.com/input-output-hk/catalyst-toolbox.git", branch = "test_api_for_snapshot", features=["test-api"]}
34+
catalyst-toolbox = { git = "https://github.com/input-output-hk/catalyst-toolbox.git", branch = "main", features=["test-api"]}
35+
snapshot-lib = { git = "https://github.com/input-output-hk/catalyst-toolbox.git", branch = "main", features=["proptest", "test-api"]}
3536
valgrind = { path = "../valgrind"}
3637
hyper = "0.13.6"
3738
thiserror = "1.0"

integration-tests/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ registration-service = { path = "../registration-service" }
2828
rand_chacha = "0.2"
2929
tokio = { version = "1.1", features = ["macros","rt","rt-multi-thread"] }
3030
chain-impl-mockchain = { git = "https://github.com/input-output-hk/chain-libs.git", branch = "master", features = [ "property-test-api" ] }
31-
catalyst-toolbox = { git = "https://github.com/input-output-hk/catalyst-toolbox.git", branch = "test_api_for_snapshot", features=["test-api"]}
32-
voting-hir = { git = "https://github.com/input-output-hk/catalyst-toolbox.git", branch = "test_api_for_snapshot"}
31+
catalyst-toolbox = { git = "https://github.com/input-output-hk/catalyst-toolbox.git", branch = "main", features=["test-api"]}
32+
snapshot-lib = { git = "https://github.com/input-output-hk/catalyst-toolbox.git", branch = "main", features=["proptest", "test-api"]}
3333
thiserror = "1.0"
3434
netstat2 = "0.9"
3535
image = "0.23.9"

integration-tests/src/common/mainnet_wallet_ext.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::common::MainnetWallet;
2+
use snapshot_lib::VoterHIR;
23
use vitup::config::Block0Initial;
3-
use voting_hir::VoterHIR;
44

55
pub trait MainnetWalletExtension {
66
fn as_initial_entry(&self) -> Block0Initial;

integration-tests/src/common/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,20 @@ mod assert;
22
pub mod load;
33
pub mod mainnet_wallet_ext;
44
pub mod registration;
5+
mod reps;
56
mod rewards;
67
pub mod snapshot;
8+
pub(crate) mod snapshot_filter;
79
mod static_data;
810
mod vote_plan_status;
911
mod wallet;
1012

13+
pub use reps::{empty_assigner, RepsVoterAssignerSource, DIRECT_VOTING_GROUP, REP_VOTING_GROUP};
14+
1115
pub use assert::*;
1216
pub use mainnet_tools::wallet::MainnetWallet;
1317
pub use rewards::{funded_proposals, VotesRegistry};
18+
pub use snapshot_filter::SnapshotFilter;
1419
pub use static_data::SnapshotExtensions;
1520
use thiserror::Error;
1621
pub use vote_plan_status::{CastedVote, VotePlanStatusProvider};

integration-tests/src/common/reps.rs

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use jormungandr_lib::crypto::account::Identifier;
2+
use snapshot_lib::voting_group::RepsVotersAssigner;
3+
use std::collections::HashSet;
4+
5+
pub const DIRECT_VOTING_GROUP: &str = "direct";
6+
pub const REP_VOTING_GROUP: &str = "rep";
7+
8+
pub trait RepsVoterAssignerSource {
9+
fn into_reps_voter_assigner(self) -> RepsVotersAssigner;
10+
}
11+
12+
impl RepsVoterAssignerSource for HashSet<Identifier> {
13+
fn into_reps_voter_assigner(self) -> RepsVotersAssigner {
14+
RepsVotersAssigner::new_from_repsdb(
15+
DIRECT_VOTING_GROUP.to_string(),
16+
REP_VOTING_GROUP.to_string(),
17+
self,
18+
)
19+
.unwrap()
20+
}
21+
}
22+
23+
pub fn empty_assigner() -> RepsVotersAssigner {
24+
HashSet::new().into_reps_voter_assigner()
25+
}

integration-tests/src/common/snapshot/controller.rs

+7-22
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
use catalyst_toolbox::snapshot::voting_group::VotingGroupAssigner;
2-
use catalyst_toolbox::snapshot::RawSnapshot;
3-
use catalyst_toolbox::snapshot::Snapshot;
4-
use catalyst_toolbox::snapshot::VotingRegistration;
5-
use fraction::Fraction;
61
use jortestkit::prelude::Wait;
2+
use snapshot_lib::registration::VotingRegistration;
73
use snapshot_trigger_service::client::rest::SnapshotRestClient;
4+
use snapshot_trigger_service::client::SnapshotResult;
85
use snapshot_trigger_service::config::Configuration;
96
use snapshot_trigger_service::config::JobParameters;
107
use std::process::Child;
@@ -36,33 +33,21 @@ impl SnapshotServiceController {
3633
&self.configuration
3734
}
3835

39-
pub fn snapshot(
40-
&self,
41-
job_params: JobParameters,
42-
threshold: u64,
43-
fraction: Fraction,
44-
voting_group_assigner: &impl VotingGroupAssigner,
45-
) -> Snapshot {
36+
pub fn snapshot(&self, job_params: JobParameters) -> SnapshotResult {
4637
let id = self.client().job_new(job_params.clone()).unwrap();
4738

48-
self.client()
39+
let status = self
40+
.client()
4941
.wait_for_job_finish(&id, Wait::new(std::time::Duration::from_secs(10), 5))
5042
.unwrap();
5143

5244
let snapshot_content = self
5345
.client()
5446
.get_snapshot(id, job_params.tag.as_ref().unwrap().to_string())
5547
.unwrap();
56-
let raw_snapshot: Vec<VotingRegistration> =
57-
serde_json::from_str(&snapshot_content).unwrap();
48+
let snapshot: Vec<VotingRegistration> = serde_json::from_str(&snapshot_content).unwrap();
5849

59-
Snapshot::from_raw_snapshot(
60-
RawSnapshot::from(raw_snapshot),
61-
threshold.into(),
62-
fraction,
63-
voting_group_assigner,
64-
)
65-
.unwrap()
50+
SnapshotResult::new(status, snapshot)
6651
}
6752
}
6853

integration-tests/src/common/snapshot/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ mod voter_hirs_asserts;
44

55
pub use controller::SnapshotServiceController;
66
pub use starter::SnapshotServiceStarter;
7-
pub use voter_hirs_asserts::VoterHIRAsserts;
7+
pub use voter_hirs_asserts::RegistrationAsserts;
88

99
use snapshot_trigger_service::client::do_snapshot as do_snapshot_internal;
1010
use snapshot_trigger_service::client::{Error as SnapshotClientError, SnapshotResult};

integration-tests/src/common/snapshot/voter_hirs_asserts.rs

+27-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,37 @@
11
use jormungandr_lib::crypto::account::Identifier;
22
use jormungandr_lib::interfaces::Value;
3-
use voting_hir::VoterHIR;
3+
use snapshot_lib::registration::{Delegations, VotingRegistration};
4+
use snapshot_lib::VoterHIR;
45

5-
pub trait VoterHIRAsserts {
6+
pub trait RegistrationAsserts {
67
fn assert_contains_voting_key_and_value(&self, identifier: &Identifier, value: Value);
78
fn assert_not_contain_voting_key(&self, identifier: &Identifier);
89
}
910

10-
impl VoterHIRAsserts for Vec<VoterHIR> {
11+
impl RegistrationAsserts for Vec<VotingRegistration> {
12+
fn assert_contains_voting_key_and_value(&self, identifier: &Identifier, value: Value) {
13+
assert!(self.iter().any(|x| {
14+
value == x.voting_power
15+
&& match &x.delegations {
16+
Delegations::New(hash_set) => {
17+
hash_set.iter().any(|(id, _weight)| id == identifier)
18+
}
19+
Delegations::Legacy(id) => id == identifier,
20+
}
21+
}));
22+
}
23+
24+
fn assert_not_contain_voting_key(&self, identifier: &Identifier) {
25+
assert!(!self.iter().any(|x| {
26+
match &x.delegations {
27+
Delegations::New(hash_set) => hash_set.iter().any(|(id, _weight)| id == identifier),
28+
Delegations::Legacy(id) => id == identifier,
29+
}
30+
}));
31+
}
32+
}
33+
34+
impl RegistrationAsserts for Vec<VoterHIR> {
1135
fn assert_contains_voting_key_and_value(&self, identifier: &Identifier, value: Value) {
1236
assert!(self
1337
.iter()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
use crate::common::RepsVoterAssignerSource;
2+
use chain_addr::Discrimination;
3+
use fraction::Fraction;
4+
use jormungandr_lib::crypto::account::Identifier;
5+
use jormungandr_lib::interfaces::InitialUTxO;
6+
use jormungandr_lib::interfaces::Value;
7+
use snapshot_lib::registration::VotingRegistration;
8+
use snapshot_lib::voting_group::VotingGroupAssigner;
9+
use snapshot_lib::{RawSnapshot, Snapshot, VoterHIR};
10+
use snapshot_trigger_service::client::SnapshotResult;
11+
use std::collections::HashSet;
12+
13+
pub trait SnapshotFilterSource {
14+
fn filter(
15+
&self,
16+
voting_threshold: Value,
17+
cap: Fraction,
18+
voting_group_assigner: &impl VotingGroupAssigner,
19+
) -> SnapshotFilter;
20+
fn filter_default(&self, reps: &HashSet<Identifier>) -> SnapshotFilter;
21+
}
22+
23+
impl SnapshotFilterSource for SnapshotResult {
24+
fn filter(
25+
&self,
26+
voting_threshold: Value,
27+
cap: Fraction,
28+
voting_group_assigner: &impl VotingGroupAssigner,
29+
) -> SnapshotFilter {
30+
SnapshotFilter::from_snapshot_result(self, voting_threshold, cap, voting_group_assigner)
31+
}
32+
33+
fn filter_default(&self, reps: &HashSet<Identifier>) -> SnapshotFilter {
34+
SnapshotFilter::from_snapshot_result_default(self, reps)
35+
}
36+
}
37+
38+
pub struct SnapshotFilter {
39+
snapshot: Snapshot,
40+
}
41+
42+
impl SnapshotFilter {
43+
pub(crate) fn from_snapshot_result_default(
44+
result: &SnapshotResult,
45+
reps: &HashSet<Identifier>,
46+
) -> Self {
47+
Self::from_snapshot_result(
48+
result,
49+
450u64.into(),
50+
Fraction::new(1u64, 3u64),
51+
&reps.clone().into_reps_voter_assigner(),
52+
)
53+
}
54+
}
55+
56+
impl SnapshotFilter {
57+
pub fn from_snapshot_result(
58+
snapshot_result: &SnapshotResult,
59+
voting_threshold: Value,
60+
cap: Fraction,
61+
voting_group_assigner: &impl VotingGroupAssigner,
62+
) -> SnapshotFilter {
63+
Self::from_voting_registrations(
64+
snapshot_result.registrations().to_vec(),
65+
voting_threshold,
66+
cap,
67+
voting_group_assigner,
68+
)
69+
}
70+
71+
pub fn from_voting_registrations(
72+
voting_registrations: Vec<VotingRegistration>,
73+
voting_threshold: Value,
74+
cap: Fraction,
75+
voting_group_assigner: &impl VotingGroupAssigner,
76+
) -> SnapshotFilter {
77+
Self {
78+
snapshot: Snapshot::from_raw_snapshot(
79+
RawSnapshot::from(voting_registrations),
80+
voting_threshold,
81+
cap,
82+
voting_group_assigner,
83+
)
84+
.unwrap(),
85+
}
86+
}
87+
88+
pub fn to_voters_hirs(&self) -> Vec<VoterHIR> {
89+
self.snapshot
90+
.voting_keys()
91+
.map(|vk| VoterHIR {
92+
voting_key: vk.clone(),
93+
voting_power: self
94+
.snapshot
95+
.contributions_for_voting_key(vk)
96+
.iter()
97+
.map(|c| c.value)
98+
.sum::<u64>()
99+
.into(),
100+
voting_group: "direct".to_string(),
101+
})
102+
.collect()
103+
}
104+
105+
pub fn to_block0_initials(&self) -> Vec<InitialUTxO> {
106+
self.snapshot.to_block0_initials(Discrimination::Production)
107+
}
108+
109+
pub fn snapshot(&self) -> Snapshot {
110+
self.snapshot.clone()
111+
}
112+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
use crate::common::snapshot::do_snapshot;
2+
use crate::common::snapshot_filter::SnapshotFilterSource;
3+
use crate::common::RepsVoterAssignerSource;
4+
use assert_fs::TempDir;
5+
use chain_addr::Discrimination;
6+
use fraction::Fraction;
7+
use snapshot_trigger_service::config::JobParameters;
8+
use std::collections::HashSet;
9+
use vit_servicing_station_tests::common::data::ArbitraryValidVotingTemplateGenerator;
10+
use vitup::config::Block0Initials;
11+
use vitup::config::ConfigBuilder;
12+
use vitup::config::SnapshotInitials;
13+
use vitup::testing::spawn_network;
14+
use vitup::testing::vitup_setup;
15+
16+
#[test]
17+
pub fn cip_36_support() {
18+
let testing_directory = TempDir::new().unwrap().into_persistent();
19+
let voting_threshold = 1;
20+
let tag = None;
21+
22+
let job_param = JobParameters {
23+
slot_no: None,
24+
tag: tag.clone(),
25+
};
26+
27+
let snapshot_result = do_snapshot(job_param).unwrap();
28+
let reps = HashSet::new();
29+
30+
let snapshot_filter = snapshot_result.filter(
31+
voting_threshold.into(),
32+
Fraction::new(1u64, 3u64),
33+
&reps.into_reps_voter_assigner(),
34+
);
35+
36+
let config = ConfigBuilder::default()
37+
.voting_power(voting_threshold)
38+
.block0_initials(Block0Initials::new_from_external(
39+
snapshot_filter.to_voters_hirs(),
40+
Discrimination::Production,
41+
))
42+
.snapshot_initials(SnapshotInitials::from_voters_hir(
43+
snapshot_filter.to_voters_hirs(),
44+
tag.unwrap_or_else(|| "".to_string()),
45+
))
46+
.build();
47+
48+
let mut template_generator = ArbitraryValidVotingTemplateGenerator::new();
49+
50+
let (mut controller, vit_parameters, network_params) =
51+
vitup_setup(&config, testing_directory.path().to_path_buf()).unwrap();
52+
let (_nodes, _vit_station, _wallet_proxy) = spawn_network(
53+
&mut controller,
54+
vit_parameters,
55+
network_params,
56+
&mut template_generator,
57+
)
58+
.unwrap();
59+
60+
std::thread::sleep(std::time::Duration::from_secs(3600))
61+
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
mod cip_36_support;
12
mod features;
23
mod rewards;
34
mod sanity;

0 commit comments

Comments
 (0)