Skip to content

Commit

Permalink
Merge pull request #6 from mangata-finance/feature/extended_header
Browse files Browse the repository at this point in the history
include seed in block header
  • Loading branch information
mateuszaaa authored Sep 15, 2021
2 parents 6b0e372 + 3ae0424 commit 4178681
Show file tree
Hide file tree
Showing 23 changed files with 144 additions and 334 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/mangata-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ jobs:
- name: Check Cargo version
run: |
cargo --version
- name: Run cargo check
- name: Build UT
uses: actions-rs/cargo@v1
with:
toolchain: nightly-2020-10-01
command: check
- name: Test cargo check
command: build
args: --tests
- name: Run UT
uses: actions-rs/cargo@v1
with:
toolchain: nightly-2020-10-01
Expand Down
13 changes: 1 addition & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 7 additions & 6 deletions client/block-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,13 @@ use sp_runtime::{
traits::{BlakeTwo256, Header as HeaderT, Hash, Block as BlockT, HashFor, DigestFor, NumberFor, One},
};
use sp_blockchain::Error;
use sp_core::ExecutionContext;
use sp_core::{ExecutionContext, ShufflingSeed};
use sp_api::{
Core, ApiExt, ApiErrorFor, ApiRef, ProvideRuntimeApi, StorageChanges, StorageProof,
TransactionOutcome,
};
use sp_consensus::RecordProof;

use pallet_random_seed::SeedType;
use extrinsic_info_runtime_api::runtime_api::ExtrinsicInfoRuntimeApi;
pub use sp_block_builder::BlockBuilder as BlockBuilderApi;
use sp_blockchain::Backend;
Expand Down Expand Up @@ -233,7 +232,7 @@ where
/// The storage proof will be `Some(_)` when proof recording was enabled.
pub fn build(
mut self,
seed: SeedType,
seed: ShufflingSeed,
) -> Result<BuiltBlock<Block, backend::StateBackendFor<B, Block>>, ApiErrorFor<A, Block>> {
let parent_hash = self.parent_hash;
let block_id = &self.block_id;
Expand All @@ -253,7 +252,7 @@ where
&self.api,
&self.block_id,
previous_block_extrinsics,
seed,
&seed.seed
)
};

Expand Down Expand Up @@ -287,6 +286,7 @@ where
self.extrinsics.iter().map(Encode::encode).collect(),
);
header.set_extrinsics_root(extrinsics_root);
header.set_seed(seed);

let proof = self.api.extract_proof();

Expand Down Expand Up @@ -315,10 +315,11 @@ where
pub fn create_inherents(
&mut self,
inherent_data: sp_inherents::InherentData,
) -> Result<(SeedType, Vec<Block::Extrinsic>), ApiErrorFor<A, Block>> {
) -> Result<(ShufflingSeed, Vec<Block::Extrinsic>), ApiErrorFor<A, Block>> {
let block_id = self.block_id.clone();
let seed = pallet_random_seed::extract_inherent_data(&inherent_data)
.map_err(|_| String::from("cannot read random seed from inherents data"))?;

self.api
.execute_in_transaction(move |api| {
// `create_inherents` should not change any state, to ensure this we always rollback
Expand All @@ -329,7 +330,7 @@ where
inherent_data,
))
})
.map(|inherents| (seed, inherents))
.map(|inherents| (ShufflingSeed{seed: seed.seed.into(), proof: seed.proof.into()}, inherents))
}
}

Expand Down
1 change: 0 additions & 1 deletion client/consensus/babe/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ merlin = "2.0"
pdqselect = "0.1.0"
derive_more = "0.99.2"
retain_mut = "0.1.1"
random-seed-runtime-api = {path="../../../frame/random-seed/runtime-api", version="2.0.0"}
pallet-random-seed = { path='../../../frame/random-seed', version='2.0.0' }
extrinsic-shuffler = { path='../../../client/shuffler', version='0.8.0' }

Expand Down
64 changes: 26 additions & 38 deletions client/consensus/babe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ use sp_consensus::{ImportResult, CanAuthorWith};
use sp_consensus::import_queue::{
BoxJustificationImport, BoxFinalityProofImport,
};
use sp_core::{vrf::make_transcript, sr25519, crypto::Public, traits::BareCryptoStore, vrf};
use sp_core::{vrf::make_transcript, sr25519, crypto::Public, traits::BareCryptoStore, ShufflingSeed, vrf};
use sp_application_crypto::AppKey;
use sp_runtime::{
generic::{BlockId, OpaqueDigestItemId}, Justification,
Expand Down Expand Up @@ -125,9 +125,7 @@ use sp_blockchain::{
use schnorrkel::{vrf::VRFOutput, vrf::VRFProof, SignatureError};
use codec::{Encode, Decode};
use sp_api::ApiExt;
use extrinsic_shuffler::{apply_inherents_and_fetch_seed, fetch_seed};
use pallet_random_seed::{RandomSeedInherentDataProvider, SeedType};
use random_seed_runtime_api::RandomSeedApi;
use pallet_random_seed::RandomSeedInherentDataProvider;
use sp_inherents::ProvideInherentData;

mod verification;
Expand Down Expand Up @@ -257,7 +255,7 @@ enum Error<B: BlockT> {
Runtime(sp_inherents::Error),
ForkTree(Box<fork_tree::Error<sp_blockchain::Error>>),
#[display(fmt = "Bad shuffling seed: {:X?}", _0)]
BadSeed([u8; 32]),
BadSeed(sp_core::H256),
#[display(fmt = "Seed verification problem: {}", _0)]
SeedVerificationErrorStr(String),
}
Expand Down Expand Up @@ -387,7 +385,7 @@ pub fn start_babe<B, C, SC, E, I, SO, CAW, Error>(BabeParams {
B: BlockT,
C: ProvideRuntimeApi<B> + ProvideCache<B> + ProvideUncles<B> + BlockchainEvents<B>
+ HeaderBackend<B> + HeaderMetadata<B, Error = ClientError> + Send + Sync + 'static,
C::Api: BabeApi<B> + random_seed_runtime_api::RandomSeedApi<B>,
C::Api: BabeApi<B>,
SC: SelectChain<B> + 'static,
E: Environment<B, Error = Error> + Send + Sync + 'static,
E::Proposer: Proposer<B, Error = Error, Transaction = sp_api::TransactionFor<C, B>>,
Expand Down Expand Up @@ -488,7 +486,7 @@ impl<B, C, E, I, Error, SO> sc_consensus_slots::SimpleSlotWorker<B> for BabeSlot
ProvideCache<B> +
HeaderBackend<B> +
HeaderMetadata<B, Error = ClientError>,
C::Api: BabeApi<B> + random_seed_runtime_api::RandomSeedApi<B>,
C::Api: BabeApi<B>,
E: Environment<B, Error = Error>,
E::Proposer: Proposer<B, Error = Error, Transaction = sp_api::TransactionFor<C, B>>,
I: BlockImport<B, Transaction = sp_api::TransactionFor<C, B>> + Send + Sync + 'static,
Expand Down Expand Up @@ -678,11 +676,11 @@ impl<B, C, E, I, Error, SO> sc_consensus_slots::SimpleSlotWorker<B> for BabeSlot
fn inject_inherents<'a>(
keystore: KeyStorePtr,
public: &'a sr25519::Public,
seed: SeedType,
prev_seed: &'a ShufflingSeed,
epoch: Epoch,
slot_info: &'a mut SlotInfo,
) -> Result<(), sp_consensus::Error> {
let transcript_data = create_shuffling_seed_input_data(&seed);
let transcript_data = create_shuffling_seed_input_data(&prev_seed);
let signature = keystore
.read()
.sr25519_vrf_sign(<AuthorityId as AppKey>::ID, public, transcript_data)
Expand All @@ -694,9 +692,9 @@ fn inject_inherents<'a>(
.provide_inherent_data(&mut slot_info.inherent_data)
.map_err(|_| sp_consensus::Error::StateUnavailable(String::from("cannot inject RandomSeed inherent data")))?;

RandomSeedInherentDataProvider(SeedType {
seed: signature.output.to_bytes(),
proof: signature.proof.to_bytes(),
RandomSeedInherentDataProvider(ShufflingSeed {
seed: signature.output.to_bytes().into(),
proof: signature.proof.to_bytes().into(),
})
.provide_inherent_data(&mut slot_info.inherent_data)
.map_err(|_| sp_consensus::Error::StateUnavailable(String::from("cannot inject RandomSeed inherent data")))?;
Expand All @@ -708,7 +706,7 @@ impl<B, C, E, I, Error, SO> SlotWorker<B> for BabeSlotWorker<B, C, E, I, SO>
where
B: BlockT,
C: ProvideRuntimeApi<B> + ProvideCache<B> + HeaderBackend<B> + HeaderMetadata<B, Error = ClientError> + Send + Sync,
C::Api: BabeApi<B> + random_seed_runtime_api::RandomSeedApi<B>,
C::Api: BabeApi<B>,
E: Environment<B, Error = Error> + Send + Sync,
E::Proposer: Proposer<B, Error = Error, Transaction = sp_api::TransactionFor<C, B>>,
I: BlockImport<B, Transaction = sp_api::TransactionFor<C, B>> + Send + Sync + 'static,
Expand All @@ -718,8 +716,6 @@ where
type OnSlot = Pin<Box<dyn Future<Output = Result<(), sp_consensus::Error>> + Send>>;

fn on_slot(&mut self, chain_head: B::Header, mut slot_info: SlotInfo) -> Self::OnSlot {
let block_id = BlockId::<B>::Hash(chain_head.hash());
let seed = self.client.runtime_api().get_seed(&block_id).unwrap();
let epoch_data =
<Self as sc_consensus_slots::SimpleSlotWorker<B>>::epoch_data(self, &chain_head, slot_info.number).unwrap();

Expand All @@ -740,7 +736,7 @@ where
inject_inherents(
self.keystore.clone(),
&public.into(),
seed,
chain_head.seed(),
epoch.into_cloned_inner(),
&mut slot_info,
)
Expand Down Expand Up @@ -855,10 +851,10 @@ impl<Block: BlockT> BabeLink<Block> {
}

/// calculates input that after signing will become next shuffling seed
fn create_shuffling_seed_input_data<'a>(prev_seed: &'a SeedType) -> vrf::VRFTranscriptData<'a> {
fn create_shuffling_seed_input_data<'a>(prev_seed: &'a ShufflingSeed) -> vrf::VRFTranscriptData<'a> {
vrf::VRFTranscriptData {
label: b"shuffling_seed",
items: vec![("prev_seed", vrf::VRFTranscriptValue::Bytes(&prev_seed.seed))],
items: vec![("prev_seed", vrf::VRFTranscriptValue::Bytes(prev_seed.seed.as_bytes()))],
}
}

Expand All @@ -878,8 +874,7 @@ where
Block: BlockT,
Client: AuxStore + HeaderBackend<Block> + HeaderMetadata<Block> + ProvideRuntimeApi<Block>,
Client::Api: BlockBuilderApi<Block, Error = sp_blockchain::Error>
+ BabeApi<Block, Error = sp_blockchain::Error>
+ RandomSeedApi<Block>,
+ BabeApi<Block, Error = sp_blockchain::Error>,
SelectChain: sp_consensus::SelectChain<Block>,
CAW: CanAuthorWith<Block>,
{
Expand Down Expand Up @@ -998,26 +993,19 @@ where

fn validate_seed_signature(
&self,
block_id: &BlockId<Block>,
inherents: Vec<Block::Extrinsic>,
prev_seed: &ShufflingSeed,
seed: &ShufflingSeed,
public_key: &[u8],
) -> Result<(), Error<Block>> {
let runtime_api = self.client.runtime_api();

let prev = fetch_seed::<Block, Client>(&runtime_api, block_id)
.map_err(|e| Error::<Block>::SeedVerificationErrorStr(format!("{}", e)))?;
let new = apply_inherents_and_fetch_seed::<Block, Client>(&runtime_api, block_id, inherents)
.map_err(|e| Error::<Block>::SeedVerificationErrorStr(format!("{}", e)))?;

let output = VRFOutput::from_bytes(&new.seed)
let output = VRFOutput::from_bytes(&seed.seed.as_bytes())
.map_err(|_| Error::SeedVerificationErrorStr(String::from("cannot deserialize seed")))?;
let proof = VRFProof::from_bytes(&new.proof)
let proof = VRFProof::from_bytes(&seed.proof.as_bytes())
.map_err(|_| Error::SeedVerificationErrorStr(String::from("cannot deserialize seed proof")))?;
let input = make_transcript(create_shuffling_seed_input_data(&prev));
let input = make_transcript(create_shuffling_seed_input_data(&prev_seed));

schnorrkel::PublicKey::from_bytes(public_key)
.and_then(|p| p.vrf_verify(input, &output, &proof))
.map_err(|_| Error::<Block>::BadSeed(new.seed))?;
.map_err(|_| Error::<Block>::BadSeed(seed.seed))?;

Ok(())
}
Expand All @@ -1029,8 +1017,7 @@ where
Block: BlockT,
Client: HeaderMetadata<Block, Error = sp_blockchain::Error> + HeaderBackend<Block> + ProvideRuntimeApi<Block>
+ Send + Sync + AuxStore + ProvideCache<Block>,
Client::Api: BlockBuilderApi<Block, Error = sp_blockchain::Error> + BabeApi<Block, Error = sp_blockchain::Error>
+ RandomSeedApi<Block>,
Client::Api: BlockBuilderApi<Block, Error = sp_blockchain::Error> + BabeApi<Block, Error = sp_blockchain::Error>,
SelectChain: sp_consensus::SelectChain<Block>,
CAW: CanAuthorWith<Block> + Send + Sync,
{
Expand Down Expand Up @@ -1125,9 +1112,10 @@ where
body = Some(inner_body);
}

let extrinsics = body.clone().unwrap();
let prev_header = self.client.header(BlockId::Hash(parent_hash)).unwrap().unwrap();
let seed = header.seed();
let key = &viable_epoch.as_ref().authorities[babe_pre_digest.authority_index() as usize];
self.validate_seed_signature(&BlockId::Hash(parent_hash), extrinsics, key.0.as_ref())?;
self.validate_seed_signature(prev_header.seed(), seed, key.0.as_ref())?;

trace!(target: "babe", "Checked {:?}; importing.", pre_header);
telemetry!(
Expand Down Expand Up @@ -1565,7 +1553,7 @@ pub fn import_queue<Block: BlockT, Client, SelectChain, Inner, CAW>(
Client: ProvideRuntimeApi<Block> + ProvideCache<Block> + Send + Sync + AuxStore + 'static,
Client: HeaderBackend<Block> + HeaderMetadata<Block, Error = sp_blockchain::Error>,
Client::Api:
BlockBuilderApi<Block> + BabeApi<Block> + ApiExt<Block, Error = sp_blockchain::Error> + RandomSeedApi<Block>,
BlockBuilderApi<Block> + BabeApi<Block> + ApiExt<Block, Error = sp_blockchain::Error>,
SelectChain: sp_consensus::SelectChain<Block> + 'static,
CAW: CanAuthorWith<Block> + Send + Sync + 'static,
{
Expand Down
3 changes: 3 additions & 0 deletions client/consensus/manual-seal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,10 @@ mod tests {
assert_eq!(rx.await.unwrap().unwrap(), ());
}

/// below test is unstable with high cpu load which happens on ci
/// tested on version tags/v2.0.1 with the same results
#[tokio::test]
#[ignore]
async fn manual_seal_fork_blocks() {
let builder = TestClientBuilder::new();
let (client, select_chain) = builder.build_with_longest_chain();
Expand Down
8 changes: 4 additions & 4 deletions client/rpc/src/state/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,10 +455,10 @@ fn should_return_runtime_version() {

let result = "{\"specName\":\"test\",\"implName\":\"parity-test\",\"authoringVersion\":1,\
\"specVersion\":2,\"implVersion\":2,\"apis\":[[\"0xdf6acb689907609b\",3],\
[\"0xb76521c61ad13ade\",1],[\"0x0f71f73ae590773f\",1],[\"0x37e397fc7c91f5e4\",1],\
[\"0xd2bc9897eed08f15\",2],[\"0x40fe3ad401f8959a\",4],[\"0xc6e9a76309f39b09\",1],\
[\"0xdd718d5cc53262d4\",1],[\"0xcbca25e39f142387\",2],[\"0xf78b278be53f454c\",2],\
[\"0xab3c0572291feb8b\",1],[\"0xbc9d89904f5b923f\",1]],\"transactionVersion\":1}";
[\"0xb76521c61ad13ade\",1],[\"0x37e397fc7c91f5e4\",1],[\"0xd2bc9897eed08f15\",2],\
[\"0x40fe3ad401f8959a\",4],[\"0xc6e9a76309f39b09\",1],[\"0xdd718d5cc53262d4\",1],\
[\"0xcbca25e39f142387\",2],[\"0xf78b278be53f454c\",2],[\"0xab3c0572291feb8b\",1],\
[\"0xbc9d89904f5b923f\",1]],\"transactionVersion\":1}";

let runtime_version = api.runtime_version(None.into()).wait().unwrap();
let serialized = serde_json::to_string(&runtime_version).unwrap();
Expand Down
2 changes: 1 addition & 1 deletion client/service/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ sp-tracing = { version = "2.0.0", path = "../../primitives/tracing" }
tracing = "0.1.19"
parity-util-mem = { version = "0.7.0", default-features = false, features = ["primitive-types"] }
extrinsic-info-runtime-api = { version='2.0.0', path="../../primitives/extrinsic-info-runtime-api" }
random-seed-runtime-api = { version="2.0.0", path="../../frame/random-seed/runtime-api"}
pallet-random-seed = { version="2.0.0", path="../../frame/random-seed"}
extrinsic-shuffler = { version="0.8.0", path="../shuffler" }

[target.'cfg(not(target_os = "unknown"))'.dependencies]
Expand Down
Loading

0 comments on commit 4178681

Please sign in to comment.