Skip to content

Commit

Permalink
Move opa bootstrap into genesis, use substrate keystore / vault for o…
Browse files Browse the repository at this point in the history
…pa root key storage

Signed-off-by: Ryan <[email protected]>
  • Loading branch information
ryan-s-roberts committed Jul 25, 2024
1 parent 97635a7 commit 6505c83
Show file tree
Hide file tree
Showing 18 changed files with 130 additions and 114 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions crates/chronicle-arrow/src/query/activity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ pub async fn load_activities_by_type(
.on(activity::id.eq(activity_block_info::activity_id)),
)
.filter(activity::domaintype.eq(typ_value.external_id_part()))
.order(activity_block_info::block_time)
.order(activity_block_info::block_time.desc())
.select((Activity::as_select(), Namespace::as_select()))
.offset(position as i64)
.limit(max_records as i64)
Expand All @@ -313,7 +313,7 @@ pub async fn load_activities_by_type(
.on(activity::id.eq(activity_block_info::activity_id)),
)
.filter(activity::domaintype.is_null())
.order(activity_block_info::block_time)
.order(activity_block_info::block_time.desc())
.select((Activity::as_select(), Namespace::as_select()))
.offset(position as i64)
.limit(max_records as i64)
Expand Down
8 changes: 0 additions & 8 deletions crates/chronicle-persistence/src/queryable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,6 @@ pub struct Entity {
pub domaintype: Option<String>,
}

#[derive(Queryable, Selectable, SimpleObject)]
#[diesel(table_name = crate::schema::entity_block_info)]
pub struct EntityBlockInfo {
pub entity_id: i32,
pub block_time: Option<NaiveDateTime>,
pub block_hash: Option<String>,
}

#[derive(Default, Queryable)]
pub struct Namespace {
_id: i32,
Expand Down
3 changes: 0 additions & 3 deletions crates/chronicle/src/bootstrap/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@ impl CliError {
}
}

/// Ugly but we need this until ! is stable, see <https://github.com/rust-lang/rust/issues/64715>
impl From<Infallible> for CliError {
fn from(_: Infallible) -> Self {
unreachable!()
Expand Down Expand Up @@ -372,8 +371,6 @@ fn attributes_from(

impl SubCommand for AgentCliModel {
fn as_cmd(&self) -> Command {
let cmd = Command::new(&*self.external_id).about(&*self.about);

let mut define = Command::new("define")
.about(&*self.define_about)
.arg(Arg::new("external_id")
Expand Down
30 changes: 1 addition & 29 deletions crates/common/src/opa/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,6 @@ impl AsRef<[u8]> for KeyAddress {
}
}

#[derive(Debug, Clone, Eq, PartialEq, Hash)]
// This message is used to bootstrap the root key for a newly created authz tp,
// it can only be executed once
pub struct BootstrapRoot {
pub public_key: PemEncoded,
}

#[cfg_attr(
feature = "parity-encoding",
derive(
Expand All @@ -153,8 +146,7 @@ pub struct BootstrapRoot {
scale_decode::DecodeAsType,
)
)]
#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize,))]
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Eq, PartialEq, Hash)]
pub struct PemEncoded(String);

impl PemEncoded {
Expand Down Expand Up @@ -242,7 +234,6 @@ pub struct OpaSubmission {

#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub enum Payload {
BootstrapRoot(BootstrapRoot),
SignedOperation(SignedOperation),
}

Expand Down Expand Up @@ -522,7 +513,6 @@ pub mod codec {

#[derive(Encode, EncodeAsType, DecodeAsType, Decode, Debug, TypeInfo, Clone, PartialEq, Eq)]
pub enum PayloadV1 {
BootstrapRoot(BootstrapRootV1),
SignedOperation(SignedOperationV1),
}

Expand Down Expand Up @@ -582,23 +572,9 @@ pub mod codec {
}
}

impl From<codec::BootstrapRootV1> for BootstrapRoot {
fn from(item: codec::BootstrapRootV1) -> Self {
Self { public_key: item.public_key }
}
}

impl From<BootstrapRoot> for codec::BootstrapRootV1 {
fn from(item: BootstrapRoot) -> Self {
tracing::debug!(target: "codec_conversion", "Converting BootstrapRoot to BootstrapRootV1");
Self { public_key: item.public_key }
}
}

impl From<codec::PayloadV1> for Payload {
fn from(item: codec::PayloadV1) -> Self {
match item {
codec::PayloadV1::BootstrapRoot(v) => Self::BootstrapRoot(v.into()),
codec::PayloadV1::SignedOperation(v) => Self::SignedOperation(v.into()),
}
}
Expand All @@ -623,10 +599,6 @@ pub mod codec {
correlation_id: item.correlation_id,
span_id: item.span_id,
payload: match item.payload {
Payload::BootstrapRoot(v) => {
tracing::trace!(target: "codec_conversion", "Payload is BootstrapRoot");
codec::PayloadV1::BootstrapRoot(v.into())
},
Payload::SignedOperation(v) => {
tracing::trace!(target: "codec_conversion", "Payload is SignedOperation");
codec::PayloadV1::SignedOperation(v.into())
Expand Down
3 changes: 3 additions & 0 deletions crates/common/src/prov/model/proptest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,5 +605,8 @@ proptest! {
let lhs_json_2 = compact_json(&prov).clone();
prop_assert_eq!( lhs_json.clone().to_string(), lhs_json_2.to_string());
}



}
}
1 change: 0 additions & 1 deletion crates/embedded-substrate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use protocol_substrate::SubxtClientError;
use protocol_substrate_chronicle::ChronicleSubstrateClient;
use sc_cli::{print_node_infos, CliConfiguration, Signals, SubstrateCli};
use subxt::{
config::ExtrinsicParams,
ext::futures::{pin_mut, FutureExt},
};
use tempfile::TempDir;
Expand Down
9 changes: 0 additions & 9 deletions crates/opactl/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,6 @@ fn wait_args(command: Command) -> Command {
)
}

fn bootstrap() -> Command {
wait_args(
Command::new("bootstrap")
.about("Initialize the OPA transaction processor with a root key from the keystore")
.arg(batcher_key()),
)
}

fn generate() -> Command {
Command::new("generate")
.arg(Arg::new("output").short('o').long("output").num_args(0..=1).help(
Expand Down Expand Up @@ -306,7 +298,6 @@ pub fn cli() -> Command {
.env("SAWTOOTH_ADDRESS")
.default_value("tcp://localhost:4004"),
)
.subcommand(bootstrap())
.subcommand(generate())
.subcommand(rotate_root())
.subcommand(register_key())
Expand Down
11 changes: 0 additions & 11 deletions crates/opactl/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,17 +251,6 @@ async fn dispatch_args<
let _entered = span.enter();
let span_id = span.id().map(|x| x.into_u64()).unwrap_or(u64::MAX);
match matches.subcommand() {
Some(("bootstrap", command_matches)) => {
let signing = configure_signing(vec![], &matches, command_matches).await?;
let bootstrap = SubmissionBuilder::bootstrap_root(signing.opa_verifying().await?)
.build(span_id, Uuid::new_v4());
Ok(handle_wait(
command_matches,
client,
OpaTransaction::bootstrap_root(bootstrap, &signing).await?,
)
.await?)
},
Some(("generate", matches)) => {
let key = SecretKey::random(StdRng::from_entropy());
let key = key.to_pkcs8_pem(LineEnding::CRLF).map_err(|_| OpaCtlError::Pkcs8)?;
Expand Down
37 changes: 35 additions & 2 deletions crates/opactl/src/test/mockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ impl frame_system::Config for Test {

impl pallet_timestamp::Config for Test {
type MinimumPeriod = ConstU64<1>;
type Moment = u64;
type OnTimestampSet = ();
type WeightInfo = ();
type Moment = u64;
}

impl pallet_opa::Config for Test {
Expand All @@ -62,7 +62,40 @@ impl pallet_opa::Config for Test {
type WeightInfo = ();
}

use k256::SecretKey;
use rand::rngs::StdRng;
use rand_core::SeedableRng;

pub struct GenesisConfig {
pub root_key: SecretKey,
}

impl Default for GenesisConfig {
fn default() -> Self {
let root_key = SecretKey::random(StdRng::from_seed([0u8; 32]));
GenesisConfig { root_key }
}
}

impl GenesisConfig {
pub fn build_storage(&self) -> sp_io::TestExternalities {
use k256::pkcs8::EncodePublicKey;
let mut storage = frame_system::GenesisConfig::<Test>::default().build_storage().unwrap();
// Insert the root key into the storage
storage.top.insert(
b"pallet_opa::root_key".to_vec(),
self.root_key
.public_key()
.to_public_key_pem(k256::pkcs8::LineEnding::CRLF)
.unwrap()
.as_bytes()
.to_vec(),
);
storage.into()
}
}

// Build genesis storage according to the mock runtime.
pub fn new_test_ext() -> sp_io::TestExternalities {
frame_system::GenesisConfig::<Test>::default().build_storage().unwrap().into()
GenesisConfig::default().build_storage()
}
67 changes: 37 additions & 30 deletions crates/pallet-opa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ use common::{
k256::ecdsa::{Signature, VerifyingKey},
opa::{
codec::{NewPublicKeyV1, OpaSubmissionV1, PayloadV1, SignedOperationV1},
BootstrapRoot, KeyAddress, KeyRegistration, Keys, OpaSubmission, Operation, Payload,
PolicyAddress, PolicyMeta, PolicyMetaAddress, RegisterKey, RotateKey, SetPolicy,
SignedOperation, SignedOperationPayload,
KeyAddress, KeyRegistration, Keys, OpaSubmission, Operation, Payload, PolicyAddress,
PolicyMeta, PolicyMetaAddress, RegisterKey, RotateKey, SetPolicy, SignedOperation,
SignedOperationPayload,
},
};

Expand Down Expand Up @@ -71,7 +71,6 @@ fn verify_signed_operation<T: Config>(
) -> Result<(), OpaError> {
use k256::ecdsa::signature::Verifier;
match &submission.payload {
PayloadV1::BootstrapRoot(_) => Ok(()),
PayloadV1::SignedOperation(SignedOperationV1 { payload, verifying_key, signature }) => {
if root_keys.is_none() {
error!("No registered root keys for signature verification");
Expand Down Expand Up @@ -111,31 +110,7 @@ fn apply_signed_operation<T: Config>(
correlation_id: ChronicleTransactionId,
payload: Payload,
) -> Result<(), OpaError> {
use scale_info::prelude::string::ToString;
match payload {
Payload::BootstrapRoot(BootstrapRoot { public_key }) => {
let existing_key = pallet::KeyStore::<T>::try_get(key_address("root"));

if existing_key.is_ok() {
error!("OPA TP has already been bootstrapped");
return Err(OpaError::InvalidOperation);
}

let keys = Keys {
id: "root".to_string(),
current: KeyRegistration { key: public_key, version: 0 },
expired: None,
};

pallet::KeyStore::<T>::set(key_address("root"), Some(keys.clone().into()));

pallet::Pallet::<T>::deposit_event(pallet::Event::<T>::KeyUpdate(
keys.into(),
correlation_id,
));

Ok(())
},
Payload::SignedOperation(SignedOperation {
payload: SignedOperationPayload { operation },
verifying_key: _,
Expand Down Expand Up @@ -291,9 +266,23 @@ fn root_keys_from_state<T: Config>() -> Result<Option<Keys>, OpaError> {
#[frame_support::pallet]
pub mod pallet {
use super::*;
use common::opa::PemEncoded;
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;

/// Genesis configuration, whether or not we need to enforce OPA policies
#[pallet::genesis_config]
pub struct GenesisConfig<T: Config> {
pub root_account: Option<PemEncoded>,
pub _phantom: PhantomData<T>,
}

impl<T: Config> Default for GenesisConfig<T> {
fn default() -> Self {
Self { root_account: None, _phantom: PhantomData }
}
}

#[pallet::pallet]
pub struct Pallet<T>(_);

Expand Down Expand Up @@ -355,13 +344,31 @@ pub mod pallet {
}
}

#[pallet::genesis_build]
impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
fn build(&self) {
use scale_info::prelude::string::ToString;
if let Some(key) = &self.root_account {
pallet::KeyStore::<T>::set(
key_address("root"),
Some(
Keys {
id: "root".to_string(),
current: KeyRegistration { key: key.clone(), version: 0 },
expired: None,
}
.into(),
),
);
}
}
}

// Dispatchable functions allows users to interact with the pallet and invoke state changes.
// These functions materialize as "extrinsics", which are often compared to transactions.
// Dispatchable functions must be annotated with a weight and must return a DispatchResult.
#[pallet::call]
impl<T: Config> Pallet<T> {
// Apply a vector of chronicle operations, yielding an event that indicates state change or
// contradiction
#[pallet::call_index(0)]
#[pallet::weight(T::WeightInfo::apply())]
pub fn apply(origin: OriginFor<T>, submission: T::OpaSubmission) -> DispatchResult {
Expand Down
Loading

0 comments on commit 6505c83

Please sign in to comment.