Skip to content

Commit 439f084

Browse files
authored
fix hex-encoded string conversion for chain_proposal_id (#140)
An issue for extracting the correct bytes from a hex-encoded string is resolved. The fix was added to convert the 64-character hex-encoded digest of a Blake2b256 into the underlying 32-byte array used to define the `chain_proposal_id` field of the `FullProposalInfo` type.
2 parents 339b6ca + 467a248 commit 439f084

File tree

4 files changed

+37
-16
lines changed

4 files changed

+37
-16
lines changed

src/catalyst-toolbox/catalyst-toolbox/src/rewards/dreps.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -167,19 +167,19 @@ mod tests {
167167
let voters = snapshot.to_full_snapshot_info();
168168

169169
let snapshot = ArbitrarySnapshotGenerator::default().snapshot();
170-
let mut proposals = snapshot.proposals();
171-
// for some reasone they are base64 encoded and truncatin is just easier
172-
for proposal in &mut proposals {
173-
proposal.proposal.chain_proposal_id.truncate(32);
174-
}
170+
let proposals = snapshot.proposals();
171+
175172
let proposals_by_challenge =
176173
proposals
177174
.iter()
178175
.fold(<HashMap<_, Vec<_>>>::new(), |mut acc, prop| {
179176
acc.entry(prop.proposal.challenge_id)
180177
.or_default()
181178
.push(Hash::from(
182-
<[u8; 32]>::try_from(prop.proposal.chain_proposal_id.clone()).unwrap(),
179+
crate::rewards::chain_proposal_id_bytes(
180+
&prop.proposal.chain_proposal_id,
181+
)
182+
.unwrap(),
183183
));
184184
acc
185185
});

src/catalyst-toolbox/catalyst-toolbox/src/rewards/mod.rs

+19-3
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ pub type Funds = Decimal;
1010
pub type Rewards = Decimal;
1111
pub type VoteCount = HashMap<Identifier, HashSet<Hash>>;
1212

13+
use chain_impl_mockchain::certificate::ExternalProposalId;
1314
use jormungandr_lib::crypto::{account::Identifier, hash::Hash};
1415
use std::collections::{HashMap, HashSet};
16+
use std::str::FromStr;
1517
use thiserror::Error;
1618
use vit_servicing_station_lib::db::models::proposals::FullProposalInfo;
1719

@@ -21,6 +23,21 @@ pub enum Error {
2123
InvalidHash(Vec<u8>),
2224
}
2325

26+
/// Convert a slice of bytes that represent a valid `ExternalProposalId`, and returns an array of
27+
/// the decoded 32-byte array.
28+
pub(crate) fn chain_proposal_id_bytes(v: &[u8]) -> Result<[u8; 32], Error> {
29+
// the chain_proposal_id comes as hex-encoded string digest of a blake2b256 key
30+
// the first step is to decode the &str
31+
let chain_proposal_str =
32+
std::str::from_utf8(v).map_err(|_| Error::InvalidHash(v.to_owned()))?;
33+
// second step is to convert &str into a digest so that it can be converted into
34+
// [u8;32]
35+
let chain_proposal_id = ExternalProposalId::from_str(chain_proposal_str)
36+
.map_err(|_| Error::InvalidHash(v.to_owned()))?;
37+
let bytes: [u8; 32] = chain_proposal_id.into();
38+
Ok(bytes)
39+
}
40+
2441
pub struct Threshold {
2542
total: usize,
2643
per_challenge: HashMap<i32, usize>,
@@ -36,9 +53,8 @@ impl Threshold {
3653
let proposals = proposals
3754
.into_iter()
3855
.map(|p| {
39-
<[u8; 32]>::try_from(p.proposal.chain_proposal_id)
40-
.map_err(Error::InvalidHash)
41-
.map(|hash| (p.proposal.challenge_id, Hash::from(hash)))
56+
let bytes = chain_proposal_id_bytes(&p.proposal.chain_proposal_id)?;
57+
Ok((p.proposal.challenge_id, Hash::from(bytes)))
4258
})
4359
.collect::<Result<Vec<_>, Error>>()?;
4460
Ok(Self {

src/catalyst-toolbox/catalyst-toolbox/src/rewards/voters.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -397,19 +397,19 @@ mod tests {
397397
let voters = snapshot.to_full_snapshot_info();
398398

399399
let snapshot = ArbitrarySnapshotGenerator::default().snapshot();
400-
let mut proposals = snapshot.proposals();
401-
// for some reasone they are base64 encoded and truncatin is just easier
402-
for proposal in &mut proposals {
403-
proposal.proposal.chain_proposal_id.truncate(32);
404-
}
400+
let proposals = snapshot.proposals();
401+
405402
let proposals_by_challenge =
406403
proposals
407404
.iter()
408405
.fold(<HashMap<_, Vec<_>>>::new(), |mut acc, prop| {
409406
acc.entry(prop.proposal.challenge_id)
410407
.or_default()
411408
.push(Hash::from(
412-
<[u8; 32]>::try_from(prop.proposal.chain_proposal_id.clone()).unwrap(),
409+
crate::rewards::chain_proposal_id_bytes(
410+
&prop.proposal.chain_proposal_id,
411+
)
412+
.unwrap(),
413413
));
414414
acc
415415
});

src/vit-servicing-station/vit-servicing-station-tests/src/common/data/generator/arbitrary/snapshot_generator.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::common::data::ArbitraryGenerator;
22
use crate::common::data::ArbitraryValidVotingTemplateGenerator;
33
use crate::common::data::{Snapshot, ValidVotingTemplateGenerator};
4+
use chain_impl_mockchain::certificate::ExternalProposalId;
45
use std::collections::BTreeSet;
56
use std::iter;
67
use time::{Duration, OffsetDateTime};
@@ -129,6 +130,10 @@ impl ArbitrarySnapshotGenerator {
129130
let challenge_info = self
130131
.template_generator
131132
.proposals_challenge_info(&challenge.challenge_type);
133+
let chain_proposal_id = ExternalProposalId::from(self.id_generator.bytes())
134+
.to_string()
135+
.as_bytes()
136+
.to_vec();
132137
let proposal = Proposal {
133138
internal_id: id.abs(),
134139
proposal_id: id.abs().to_string(),
@@ -142,7 +147,7 @@ impl ArbitrarySnapshotGenerator {
142147
reviews_count: 0,
143148
proposal_files_url: proposal.files_url,
144149
proposer: self.template_generator.proposer(),
145-
chain_proposal_id: self.id_generator.hash().as_bytes().to_vec(),
150+
chain_proposal_id,
146151
chain_vote_options: proposal.chain_vote_options,
147152
chain_vote_start_time: voteplan.chain_vote_start_time,
148153
chain_vote_end_time: voteplan.chain_vote_end_time,

0 commit comments

Comments
 (0)