soft3/neuron/node/tests/authority_boundary.rs

mod support;
use neuron_engine::{Action, Authority, Error, GraphPort, Neuron, Overlay};
use neuron_model::{
    Builder, Content, Head, Particle, Reader, Source, Value::*, execution::NeuronState,
};
use neuron_node::{Graph, Rune};
use support::*;
struct Forged;
impl Authority for Forged {
    fn with_current(
        &self,
        _: &Action<'_>,
        commit: &mut dyn FnMut() -> Result<(), Error>,
    ) -> Result<(), Error> {
        commit()
    }
    fn authorize(&self, _: &Action<'_>) -> Result<Vec<u8>, Error> {
        Ok(vec![1; 102])
    }
}

#[test]
fn revocation_after_signing_blocks_activation_and_normal_publication() {
    use std::sync::{Arc, Mutex};
    struct RevokeAfterSigning {
        inner: neuron_node::LocalAuthority<neuron_node::KeyVault>,
        grant: neuron_node::GrantHandle,
        kind: Arc<Mutex<Option<String>>>,
    }
    impl Authority for RevokeAfterSigning {
        fn authorize(&self, action: &Action<'_>) -> Result<Vec<u8>, Error> {
            let evidence = self.inner.authorize(action)?;
            let mut kind = self.kind.lock().unwrap();
            if kind.as_deref() == Some(action.kind) {
                *kind = None;
                let mut next = self.grant.get()?;
                let prior = next.revision;
                next.revision += 1;
                next.enabled = false;
                self.grant.replace(prior, next)?;
            }
            Ok(evidence)
        }
        fn with_current(
            &self,
            action: &Action<'_>,
            commit: &mut dyn FnMut() -> Result<(), Error>,
        ) -> Result<(), Error> {
            self.inner.with_current(action, commit)
        }
    }
    let dir = Directory::new();
    let (inner, grant) = authority();
    let id = inner.subject();
    let kind = Arc::new(Mutex::new(Some("activate".into())));
    let agent = Neuron::with_authority(
        dir.graph(),
        Rune,
        RevokeAfterSigning {
            inner,
            grant: grant.clone(),
            kind: kind.clone(),
        },
    );
    assert!(matches!(
        agent.activate(id, NETWORK, POLICY, 10000),
        Err(Error::Denied)
    ));
    assert!(agent.graph.head(id).unwrap().is_none());
    let mut next = grant.get().unwrap();
    next.enabled = true;
    next.revision += 1;
    grant.replace(1, next).unwrap();
    let before = agent.activate(id, NETWORK, POLICY, 10000).unwrap();
    *kind.lock().unwrap() = Some("install".into());
    assert!(matches!(
        agent.install(id, [1; 32], b"event".to_vec(), value("0"), config()),
        Err(Error::Denied)
    ));
    assert_eq!(agent.graph.head(id).unwrap(), Some(before));
    assert!(agent.inspect(id).unwrap().state.progs.is_empty());
}
#[test]
fn engine_adapter_cannot_publish_with_fabricated_authorization_evidence() {
    let dir = Directory::new();
    let agent = Neuron::with_authority(dir.graph(), Rune, Forged);
    assert!(agent.activate([7; 32], NETWORK, POLICY, 1000).is_err());
    assert!(agent.graph.head([7; 32]).unwrap().is_none());
}

struct RewriteRoot(Graph);
impl Source for RewriteRoot {
    fn get(&self, id: &Particle) -> Result<Content, neuron_model::Error> {
        self.0.get(id)
    }
}
impl GraphPort for RewriteRoot {
    fn head(&self, n: Particle) -> Result<Option<Head>, Error> {
        self.0.head(n)
    }
    fn resolve(&self, n: Particle, r: Particle) -> Result<Option<Head>, Error> {
        self.0.resolve(n, r)
    }
    fn history(&self, n: Particle, a: Option<u64>, l: usize) -> Result<Vec<Head>, Error> {
        self.0.history(n, a, l)
    }
    fn commit(
        &self,
        n: Particle,
        r: Particle,
        e: Option<Head>,
        h: Head,
        mut b: Builder,
        c: Option<(Particle, Particle)>,
    ) -> Result<Head, Error> {
        assert_eq!(h.index, 0);
        let (mut state, auth) = {
            let overlay = Overlay {
                graph: &self.0,
                batch: &b,
            };
            let mut reader = Reader::new(&overlay, 100_000);
            let f = reader.record(h.commit, "neuron/activation/1", 3)?;
            let root = reader.reference(f[1])?;
            (
                NeuronState::read(&mut reader, root)?,
                reader.reference(f[2])?,
            )
        };
        state.limit += 1;
        let root = state.encode(&mut b)?;
        let commit = b.values("neuron/activation/1", &[Ref(n), Ref(root), Ref(auth)])?;
        self.0.commit(n, r, e, Head { index: 0, commit }, b, c)
    }
}
#[test]
fn valid_signature_cannot_be_reused_for_a_different_canonical_root() {
    let dir = Directory::new();
    let (auth, _) = authority();
    let id = auth.subject();
    let agent = Neuron::with_authority(RewriteRoot(dir.graph()), Rune, auth);
    assert!(agent.activate(id, NETWORK, POLICY, 1000).is_err());
    assert!(agent.graph.head(id).unwrap().is_none());
}

Graph