Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(rotate): Handle consensus logs that are not ScheduledChange #69

Merged
merged 4 commits into from
Nov 6, 2024
Merged
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
2 changes: 1 addition & 1 deletion primitives/src/rotate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ fn verify_encoding_epoch_end_header(
decode_scale_compact_int(header_bytes[cursor..cursor + 5].to_vec());
cursor += decoded_byte_length;

// Verify the next byte after encoded scheduled change message is scheduled change enum flags.
// Verify the next byte after encoded scheduled change message is the ScheduledChange enum flag.
assert_eq!(header_bytes[cursor], 1u8);

cursor += 1;
Expand Down
4 changes: 2 additions & 2 deletions script/bin/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ async fn main() -> anyhow::Result<()> {
setup_logger();

// Supply an initial authority set id, trusted block, and target block.
let authority_set_id = 64u64;
let authority_set_id = 282u64;
let trusted_block = 305130;
let target_block = 305160;

let proof_type = ProofType::HeaderRangeProof;
let proof_type = ProofType::RotateProof;

let fetcher = RpcDataFetcher::new().await;
let mut stdin: SP1Stdin = SP1Stdin::new();
Expand Down
54 changes: 50 additions & 4 deletions services/src/input.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use anyhow::Result;
use avail_subxt::primitives::grandpa::{AuthorityId, ConsensusLog};
use log::info;
use sp1_vector_primitives::types::{
CircuitJustification, HeaderRangeInputs, HeaderRotateData, Precommit, RotateInputs,
};
Expand Down Expand Up @@ -454,6 +456,39 @@ impl RpcDataFetcher {
.await
}

/// Filter the authority set changes from the header at the end of the epoch associated with the
/// given authority set id.
/// Source: https://github.com/Rahul8869/avail-light/blob/1ee54e10c037474d2ee99a0762e6ffee43f0df1c/src/utils.rs#L78
pub async fn filter_auth_set_changes(
&self,
authority_set_id: u64,
) -> Vec<Vec<(AuthorityId, u64)>> {
let epoch_end_block = self.last_justified_block(authority_set_id).await;
if epoch_end_block == 0 {
panic!("Current authority set is still active!");
}

let header = self.get_header(epoch_end_block).await;

let new_auths = header
.digest
.logs
.iter()
.filter_map(|e| match &e {
avail_subxt::config::substrate::DigestItem::Consensus(
[b'F', b'R', b'N', b'K'],
data,
) => match ConsensusLog::<u32>::decode(&mut data.as_slice()) {
Ok(ConsensusLog::ScheduledChange(x)) => Some(x.next_authorities),
Ok(ConsensusLog::ForcedChange(_, x)) => Some(x.next_authorities),
_ => None,
},
_ => None,
})
.collect::<Vec<_>>();
new_auths
}

/// This function takes in a block_number as input, and fetches the new authority set specified
/// in the epoch end block. It returns the data necessary to prove the new authority set, which
/// specifies the new authority set hash, the number of authorities, and the start and end
Expand Down Expand Up @@ -484,10 +519,21 @@ impl RpcDataFetcher {
// Note: Two bytes are skipped between the consensus id and value.
if let DigestItem::Consensus(consensus_id, value) = log {
if consensus_id == [70, 82, 78, 75] {
found_correct_log = true;

// Denotes that this is a `ScheduledChange` log.
assert_eq!(value[0], 1);
// Decode the consensus log. Only if this is the correct log, will we continue.
match ConsensusLog::<u32>::decode(&mut value.as_slice()) {
Ok(ConsensusLog::ScheduledChange(x)) => {
println!("Found ScheduledChange log!");
found_correct_log = true;
}
Ok(ConsensusLog::ForcedChange(_, x)) => {
println!("Found ForcedChange log!");
found_correct_log = true;
}
_ => {
position += encoded_log.len();
continue;
}
}

// The bytes after the prefix are the compact encoded number of authorities.
// Follows the encoding format: https://docs.substrate.io/reference/scale-codec/#fn-1
Expand Down
Loading