Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions demo/node/src/tests/inherent_data_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ async fn block_proposal_cidp_should_be_created_correctly() {

let inherent_data_providers = ProposalCIDP::new(
test_create_inherent_data_config(),
TestApi::new(ScEpochNumber(2))
TestApi::new(ScEpochNumber(20))
.with_headers([(mock_header().hash(), mock_header())])
.with_pariticipation_data(vec![(past_block_slot(), past_block_author())])
.into(),
Expand Down Expand Up @@ -124,7 +124,7 @@ async fn block_verification_cidp_should_be_created_correctly() {

let verifier_cidp = VerifierCIDP::new(
create_inherent_data_config.clone(),
TestApi::new(ScEpochNumber(2))
TestApi::new(ScEpochNumber(20))
.with_pariticipation_data(vec![(past_block_slot(), past_block_author())])
.into(),
Arc::new(mc_hash_data_source),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,28 +62,30 @@ impl AriadneInherentDataProvider {
timestamp_millis,
)?;

let data_epoch = data_source.data_epoch(for_mc_epoch).await?;
let data_epoch = offset_data_epoch(&for_mc_epoch).map_err(|offset| {
InherentProviderCreationError::McEpochOffsetError(offset, for_mc_epoch)
})?;

// We could accept mc_reference at last slot of data_epoch, but calculations are much easier like that.
// Additionally, in current implementation, the inequality below is always true, thus there is no need to make it more accurate.
let scripts = client.runtime_api().get_main_chain_scripts(parent_hash)?;
if data_epoch < mc_reference_epoch {
Ok(AriadneInherentDataProvider::from_mc_data(data_source, for_mc_epoch, scripts)
.await?)
Ok(AriadneInherentDataProvider::from_mc_data(data_source, data_epoch, scripts).await?)
} else {
Ok(AriadneInherentDataProvider { data: None })
}
}

async fn from_mc_data(
candidate_data_source: &(dyn AuthoritySelectionDataSource + Send + Sync),
for_epoch: McEpochNumber,
data_epoch: McEpochNumber,
scripts: MainChainScripts,
) -> Result<Self, InherentProviderCreationError> {
use crate::authority_selection_inputs::authority_selection_inputs_from_mc_data;

Ok(Self {
data: Some(
authority_selection_inputs_from_mc_data(candidate_data_source, for_epoch, scripts)
authority_selection_inputs_from_mc_data(candidate_data_source, data_epoch, scripts)
.await?,
),
})
Expand All @@ -97,6 +99,10 @@ pub enum InherentProviderCreationError {
/// Couldn't convert timestamp to main chain epoch.
#[error("Couldn't convert timestamp to main chain epoch: {0}")]
McEpochDerivationError(#[from] sidechain_domain::mainchain_epoch::EpochDerivationError),
#[error(
"Could not apply data offset of {0} to MC epoch {1:?} for authority selection; this is caused either by a node misconfiguration or a bug."
)]
McEpochOffsetError(u32, McEpochNumber),
/// Runtime API call failed.
#[error("Runtime API call failed: {0}")]
ApiError(#[from] sp_api::ApiError),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ pub struct AriadneParameters {
#[async_trait::async_trait]
pub trait AuthoritySelectionDataSource {
/// Returns D-parameter and list of permissioned candidates that is effective for the given epoch.
/// The data from the latest block of `data_epoch(epoch)` will be used if available, otherwise returns data at the latest block of the chain.
async fn get_ariadne_parameters(
&self,
epoch_number: McEpochNumber,
Expand All @@ -59,7 +58,6 @@ pub trait AuthoritySelectionDataSource {
) -> Result<AriadneParameters, Box<dyn std::error::Error + Send + Sync>>;

/// Returns the list of registrations that is effective for the given epoch.
/// The data from the latest block of `data_epoch(epoch)` will be used if available, otherwise returns data at the latest block of the chain.
/// Each item is a list of one candidate registrations.
async fn get_candidates(
&self,
Expand All @@ -72,37 +70,24 @@ pub trait AuthoritySelectionDataSource {
&self,
epoch: McEpochNumber,
) -> Result<Option<EpochNonce>, Box<dyn std::error::Error + Send + Sync>>;

///
/// # Arguments
///
/// * `for_epoch`: main chain epoch number during which candidate data is meant to be used
///
/// returns: Result<McEpochNumber, Box<dyn std::error::Error + Send + Sync>> - data source methods called with `for_epoch` will query only for data which was stored on main chain in the returned epoch or earlier
///
///
async fn data_epoch(
&self,
for_epoch: McEpochNumber,
) -> Result<McEpochNumber, Box<dyn std::error::Error + Send + Sync>>;
}

#[cfg(feature = "std")]
pub(crate) async fn authority_selection_inputs_from_mc_data(
candidate_data_source: &(dyn AuthoritySelectionDataSource + Send + Sync),
for_epoch: McEpochNumber,
data_epoch: McEpochNumber,
scripts: sp_session_validator_management::MainChainScripts,
) -> Result<AuthoritySelectionInputs, AuthoritySelectionInputsCreationError> {
let ariadne_parameters_response = candidate_data_source
.get_ariadne_parameters(
for_epoch,
data_epoch,
scripts.d_parameter_policy_id.clone(),
scripts.permissioned_candidates_policy_id.clone(),
)
.await
.map_err(|err| {
AuthoritySelectionInputsCreationError::AriadneParametersQuery(
for_epoch,
data_epoch,
scripts.d_parameter_policy_id.clone(),
scripts.permissioned_candidates_policy_id.clone(),
err,
Expand All @@ -115,7 +100,7 @@ pub(crate) async fn authority_selection_inputs_from_mc_data(
None if no_permissioned_candidates_expected => Vec::new(),
None => {
return Err(AuthoritySelectionInputsCreationError::AriadneParametersQuery(
for_epoch,
data_epoch,
scripts.d_parameter_policy_id,
scripts.permissioned_candidates_policy_id,
("Expected Data Not Found: Permissioned Candidates List".to_string()).into(),
Expand All @@ -125,19 +110,19 @@ pub(crate) async fn authority_selection_inputs_from_mc_data(
};

let registered_candidates: Vec<CandidateRegistrations> = candidate_data_source
.get_candidates(for_epoch, scripts.committee_candidate_address.clone())
.get_candidates(data_epoch, scripts.committee_candidate_address.clone())
.await
.map_err(|err| {
AuthoritySelectionInputsCreationError::GetCandidatesQuery(
for_epoch,
data_epoch,
scripts.committee_candidate_address.to_string(),
err,
)
})?;
let epoch_nonce_response = candidate_data_source
.get_epoch_nonce(for_epoch)
.await
.map_err(|err| AuthoritySelectionInputsCreationError::GetEpochNonceQuery(for_epoch, err))?;
let epoch_nonce_response =
candidate_data_source.get_epoch_nonce(data_epoch).await.map_err(|err| {
AuthoritySelectionInputsCreationError::GetEpochNonceQuery(data_epoch, err)
})?;
let epoch_nonce = epoch_nonce_response.unwrap_or(EpochNonce(vec![]));

Ok(AuthoritySelectionInputs {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ impl Default for MockAuthoritySelectionDataSource {
fn default() -> Self {
Self {
candidates: vec![vec![], vec![]],
permissioned_candidates: vec![Some(vec![]), Some(vec![])],
permissioned_candidates: vec![Some(vec![]), Some(vec![]), Some(vec![])],
num_permissioned_candidates: 3,
}
}
Expand Down Expand Up @@ -80,11 +80,4 @@ impl AuthoritySelectionDataSource for MockAuthoritySelectionDataSource {
) -> Result<Option<EpochNonce>, Box<dyn std::error::Error + Send + Sync>> {
Ok(Some(EpochNonce(vec![42u8])))
}

async fn data_epoch(
&self,
for_epoch: McEpochNumber,
) -> Result<McEpochNumber, Box<dyn std::error::Error + Send + Sync>> {
Ok(for_epoch)
}
}
10 changes: 1 addition & 9 deletions toolkit/data-sources/db-sync/src/candidates/cached.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,6 @@ impl AuthoritySelectionDataSource for CandidateDataSourceCached {
) -> Result<Option<EpochNonce>, Box<dyn std::error::Error + Send + Sync>> {
self.inner.get_epoch_nonce(epoch).await
}

async fn data_epoch(
&self,
for_epoch: McEpochNumber,
) -> Result<McEpochNumber, Box<dyn std::error::Error + Send + Sync>> {
self.inner.data_epoch(for_epoch).await
}
}

#[derive(Debug, Clone, Deserialize)]
Expand Down Expand Up @@ -176,9 +169,8 @@ impl CandidateDataSourceCached {

async fn can_use_caching_for_request(
&self,
request_epoch: McEpochNumber,
data_epoch: McEpochNumber,
) -> Result<bool, Box<dyn std::error::Error + Send + Sync>> {
let data_epoch = self.inner.data_epoch(request_epoch).await?;
if let Ok(stable_epoch) = self.highest_seen_stable_epoch.lock() {
if stable_epoch.map_or(false, |stable_epoch| stable_epoch >= data_epoch) {
return Ok(true);
Expand Down
22 changes: 2 additions & 20 deletions toolkit/data-sources/db-sync/src/candidates/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ impl AuthoritySelectionDataSource for CandidatesDataSourceImpl {
d_parameter_policy: PolicyId,
permissioned_candidate_policy: PolicyId
) -> Result<AriadneParameters, Box<dyn std::error::Error + Send + Sync>> {
let epoch = EpochNumber::from(self.get_epoch_of_data_storage(epoch)?);
let epoch = EpochNumber::from(epoch);
let d_parameter_asset = Asset::new(d_parameter_policy);
let permissioned_candidate_asset = Asset::new(permissioned_candidate_policy);

Expand Down Expand Up @@ -97,7 +97,7 @@ impl AuthoritySelectionDataSource for CandidatesDataSourceImpl {
epoch: McEpochNumber,
committee_candidate_address: MainchainAddress
)-> Result<Vec<CandidateRegistrations>, Box<dyn std::error::Error + Send + Sync>> {
let epoch = EpochNumber::from(self.get_epoch_of_data_storage(epoch)?);
let epoch = EpochNumber::from(epoch);
let candidates = self.get_registered_candidates(epoch, committee_candidate_address).await?;
let stake_map = Self::make_stake_map(db_model::get_stake_distribution(&self.pool, epoch).await?);
Ok(Self::group_candidates_by_mc_pub_key(candidates).into_iter().map(|(mainchain_pub_key, candidate_registrations)| {
Expand All @@ -110,14 +110,9 @@ impl AuthoritySelectionDataSource for CandidatesDataSourceImpl {
}

async fn get_epoch_nonce(&self, epoch: McEpochNumber) -> Result<Option<EpochNonce>, Box<dyn std::error::Error + Send + Sync>> {
let epoch = self.get_epoch_of_data_storage(epoch)?;
let nonce = db_model::get_epoch_nonce(&self.pool, EpochNumber(epoch.0)).await?;
Ok(nonce.map(|n| EpochNonce(n.0)))
}

async fn data_epoch(&self, for_epoch: McEpochNumber) -> Result<McEpochNumber, Box<dyn std::error::Error + Send + Sync>> {
self.get_epoch_of_data_storage(for_epoch)
}
});

impl CandidatesDataSourceImpl {
Expand Down Expand Up @@ -310,17 +305,4 @@ impl CandidatesDataSourceImpl {
})
.collect()
}

fn get_epoch_of_data_storage(
&self,
epoch_of_data_usage: McEpochNumber,
) -> Result<McEpochNumber, Box<dyn std::error::Error + Send + Sync>> {
offset_data_epoch(&epoch_of_data_usage).map_err(|offset| {
BadRequest(format!(
"Minimum supported epoch of data usage is {offset}, but {} was provided",
epoch_of_data_usage.0
))
.into()
})
}
}
Loading
Loading