Skip to content

Commit

Permalink
Much work, but clearer what's required
Browse files Browse the repository at this point in the history
  • Loading branch information
expede committed Mar 14, 2024
1 parent b65ec3e commit 61ed0ca
Show file tree
Hide file tree
Showing 30 changed files with 947 additions and 256 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ web-sys = { version = "0.3", features = ["Crypto", "CryptoKey", "CryptoKeyPair",

[dev-dependencies]
libipld = "0.16"
pretty_assertions = "1.4"
rand = "0.8"
testresult = "0.3"
test-log = "0.2"
Expand Down
11 changes: 11 additions & 0 deletions src/ability/crud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,17 @@ pub enum Crud {
Destroy(Destroy),
}

impl From<Crud> for arguments::Named<Ipld> {
fn from(crud: Crud) -> Self {
match crud {
Crud::Create(create) => create.into(),
Crud::Read(read) => read.into(),
Crud::Update(update) => update.into(),
Crud::Destroy(destroy) => destroy.into(),
}
}
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum PromisedCrud {
Create(PromisedCreate),
Expand Down
17 changes: 17 additions & 0 deletions src/ability/crud/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::{
};
use libipld_core::ipld::Ipld;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::path::PathBuf;
use thiserror::Error;

Expand Down Expand Up @@ -53,6 +54,22 @@ pub struct Create {
pub args: Option<arguments::Named<Ipld>>,
}

impl From<Create> for Ipld {
fn from(create: Create) -> Self {
let mut map = BTreeMap::new();

if let Some(path) = create.path {
map.insert("path".to_string(), path.display().to_string().into());
}

if let Some(args) = create.args {
map.insert("args".to_string(), args.into());
}

Ipld::Map(map)
}
}

#[cfg_attr(doc, aquamarine::aquamarine)]
/// An invoked `crud/create` ability (but possibly awaiting another
/// [`Invocation`][crate::invocation::Invocation]).
Expand Down
13 changes: 13 additions & 0 deletions src/ability/crud/destroy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::{
};
use libipld_core::ipld::Ipld;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::path::PathBuf;
use thiserror::Error;

Expand Down Expand Up @@ -49,6 +50,18 @@ pub struct Destroy {
pub path: Option<PathBuf>,
}

impl From<Destroy> for Ipld {
fn from(destroy: Destroy) -> Self {
let mut map = BTreeMap::new();

if let Some(path) = destroy.path {
map.insert("path".to_string(), path.display().to_string().into());
}

Ipld::Map(map)
}
}

const COMMAND: &'static str = "/crud/destroy";

impl Command for Destroy {
Expand Down
17 changes: 17 additions & 0 deletions src/ability/crud/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::{
};
use libipld_core::{error::SerdeError, ipld::Ipld, serde as ipld_serde};
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::path::PathBuf;
use thiserror::Error;

Expand Down Expand Up @@ -49,6 +50,22 @@ pub struct Read {
pub args: Option<arguments::Named<Ipld>>,
}

impl From<Read> for Ipld {
fn from(ready: Read) -> Self {
let mut map = BTreeMap::new();

if let Some(path) = ready.path {
map.insert("path".to_string(), Ipld::String(path.display().to_string()));
}

if let Some(args) = ready.args {
map.insert("args".to_string(), args.into());
}

map.into()
}
}

#[cfg_attr(doc, aquamarine::aquamarine)]
/// An invoked `crud/read` ability (but possibly awaiting another
/// [`Invocation`][crate::invocation::Invocation]).
Expand Down
14 changes: 12 additions & 2 deletions src/ability/crud/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,19 @@ impl TryFrom<arguments::Named<Ipld>> for Update {
}
}

impl From<Update> for Ipld {
impl From<Update> for arguments::Named<Ipld> {
fn from(create: Update) -> Self {
create.into()
let mut named = arguments::Named::<Ipld>::new();

if let Some(path) = create.path {
named.insert("path".to_string(), Ipld::String(path.display().to_string()));
}

if let Some(args) = create.args {
named.insert("args".to_string(), args.into());
}

named
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/ability/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ pub enum Msg {
Receive(Receive),
}

impl From<Msg> for arguments::Named<Ipld> {
fn from(msg: Msg) -> Self {
match msg {
Msg::Send(send) => send.into(),
Msg::Receive(receive) => receive.into(),
}
}
}

/// A promised version of the [`Msg`] ability.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum PromisedMsg {
Expand Down
11 changes: 11 additions & 0 deletions src/ability/msg/send.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::{
};
use libipld_core::ipld::Ipld;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;

#[cfg_attr(doc, aquamarine::aquamarine)]
/// The executable/dispatchable variant of the `msg/send` ability.
Expand Down Expand Up @@ -51,6 +52,16 @@ pub struct Send {
pub message: String,
}

impl From<Send> for arguments::Named<Ipld> {
fn from(send: Send) -> Self {
arguments::Named::from_iter([
("to".to_string(), send.to.into()),
("from".to_string(), send.from.into()),
("message".to_string(), send.message.into()),
])
}
}

#[cfg_attr(doc, aquamarine::aquamarine)]
/// The invoked variant of the `msg/send` ability
///
Expand Down
11 changes: 11 additions & 0 deletions src/ability/preset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ impl ToCommand for Preset {
}
}

impl From<Preset> for arguments::Named<Ipld> {
fn from(preset: Preset) -> Self {
match preset {
Preset::Crud(crud) => crud.into(),
Preset::Msg(msg) => msg.into(),
Preset::Ucan(ucan) => ucan.into(),
Preset::Wasm(wasm) => wasm.into(),
}
}
}

#[derive(Debug, Clone, PartialEq)] //, Serialize, Deserialize)]
pub enum PromisedPreset {
Crud(PromisedCrud),
Expand Down
7 changes: 7 additions & 0 deletions src/ability/ucan/revoke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::{
};
use libipld_core::{cid::Cid, ipld::Ipld};
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::fmt::Debug;

/// The fully resolved variant: ready to execute.
Expand All @@ -19,6 +20,12 @@ pub struct Revoke {
// FIXME pub witness
}

impl From<Revoke> for arguments::Named<Ipld> {
fn from(revoke: Revoke) -> Self {
arguments::Named::from_iter([("ucan".to_string(), Ipld::Link(revoke.ucan).into())])
}
}

const COMMAND: &'static str = "/ucan/revoke";

impl Command for Revoke {
Expand Down
10 changes: 10 additions & 0 deletions src/ability/wasm/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ pub struct Run {
pub args: Vec<Ipld>,
}

impl From<Run> for arguments::Named<Ipld> {
fn from(run: Run) -> Self {
arguments::Named::from_iter([
("mod".into(), Ipld::from(run.module)),
("fun".into(), run.function.into()),
("args".into(), run.args.into()),
])
}
}

impl TryFrom<arguments::Named<Ipld>> for Run {
type Error = ();

Expand Down
42 changes: 27 additions & 15 deletions src/crypto/signature/envelope.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::ability::arguments::Named;
use crate::{capsule::Capsule, crypto::varsig, did::Did};
use libipld_core::{
cid::Cid,
Expand All @@ -6,14 +7,14 @@ use libipld_core::{
ipld::Ipld,
multihash::{Code, MultihashDigest},
};
use signature::SignatureEncoding;
use signature::Verifier;
use signature::{SignatureEncoding, Signer};
use std::collections::BTreeMap;
use thiserror::Error;

pub trait Envelope: Sized {
type DID: Did;
type Payload: Clone + Capsule + TryFrom<Ipld> + Into<Ipld>;
type Payload: Clone + Capsule + TryFrom<Named<Ipld>> + Into<Named<Ipld>>;
type VarsigHeader: varsig::Header<Self::Encoder> + Clone;
type Encoder: Codec + TryFrom<u64> + Into<u64>;

Expand All @@ -29,9 +30,11 @@ pub trait Envelope: Sized {
) -> Self;

fn to_ipld_envelope(&self) -> Ipld {
let inner_args: Named<Ipld> = self.payload().clone().into();
let inner_ipld: Ipld = inner_args.into();

let wrapped_payload: Ipld =
BTreeMap::from_iter([(Self::Payload::TAG.into(), self.payload().clone().into())])
.into();
BTreeMap::from_iter([(Self::Payload::TAG.into(), inner_ipld)]).into();

let header_bytes: Vec<u8> = (*self.varsig_header()).clone().into();
let header: Ipld = vec![header_bytes.into(), wrapped_payload].into();
Expand All @@ -42,15 +45,15 @@ pub trait Envelope: Sized {

fn try_from_ipld_envelope(
ipld: Ipld,
) -> Result<Self, FromIpldError<<Self::Payload as TryFrom<Ipld>>::Error>> {
) -> Result<Self, FromIpldError<<Self::Payload as TryFrom<Named<Ipld>>>::Error>> {
if let Ipld::List(list) = ipld {
if let [Ipld::Bytes(sig), Ipld::List(inner)] = list.as_slice() {
if let [Ipld::Bytes(varsig_header), Ipld::Map(btree)] = inner.as_slice() {
if let (1, Some(inner)) = (
if let (1, Some(Ipld::Map(inner))) = (
btree.len(),
btree.get(<Self::Payload as Capsule>::TAG.into()),
) {
let payload = Self::Payload::try_from(inner.clone())
let payload = Self::Payload::try_from(Named(inner.clone()))
.map_err(FromIpldError::CannotParsePayload)?;

let varsig_header = Self::VarsigHeader::try_from(varsig_header.as_slice())
Expand Down Expand Up @@ -100,7 +103,8 @@ pub trait Envelope: Sized {
payload: Self::Payload,
) -> Result<Self, SignError>
where
Ipld: Encode<Self::Encoder> + From<Self::Payload>, // FIXME force it to be named args not IPLD
Ipld: Encode<Self::Encoder>,
Named<Ipld>: From<Self::Payload>,
{
Self::try_sign_generic(signer, varsig_header, payload)
}
Expand All @@ -125,10 +129,14 @@ pub trait Envelope: Sized {
payload: Self::Payload,
) -> Result<Self, SignError>
where
Ipld: Encode<Self::Encoder> + From<Self::Payload>,
Ipld: Encode<Self::Encoder>,
Named<Ipld>: From<Self::Payload>,
{
let ipld: Ipld =
BTreeMap::from_iter([(Self::Payload::TAG.into(), Ipld::from(payload.clone()))]).into();
let ipld: Ipld = BTreeMap::from_iter([(
Self::Payload::TAG.into(),
Named::<Ipld>::from(payload.clone()).into(),
)])
.into();

let mut buffer = vec![];
ipld.encode(*varsig::header::Header::codec(&varsig_header), &mut buffer)
Expand All @@ -155,12 +163,16 @@ pub trait Envelope: Sized {
/// FIXME
fn validate_signature(&self) -> Result<(), ValidateError>
where
Ipld: Encode<Self::Encoder> + From<Self::Payload>,
Ipld: Encode<Self::Encoder>,
Named<Ipld>: From<Self::Payload>,
{
let mut encoded = vec![];
let ipld: Ipld =
BTreeMap::from_iter([(Self::Payload::TAG.into(), self.payload().clone().into())])
.into();
let ipld: Ipld = BTreeMap::from_iter([(
Self::Payload::TAG.to_string(),
Named::<Ipld>::from(self.payload().clone()).into(),
)])
.into();

ipld.encode(
*varsig::header::Header::codec(self.varsig_header()),
&mut encoded,
Expand Down
10 changes: 6 additions & 4 deletions src/delegation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ mod payload;
pub use agent::Agent;
pub use payload::*;

use crate::ability::arguments::Named;
use crate::{
capsule::Capsule,
crypto::{signature::Envelope, varsig, Nonce},
Expand Down Expand Up @@ -126,7 +127,8 @@ impl<DID: Did, V: varsig::Header<C>, C: Codec + Into<u64> + TryFrom<u64>> Delega
impl<DID: Did + Clone, V: varsig::Header<C> + Clone, C: Codec + TryFrom<u64> + Into<u64>> Envelope
for Delegation<DID, V, C>
where
Payload<DID>: TryFrom<Ipld>,
Payload<DID>: TryFrom<Named<Ipld>>,
Named<Ipld>: From<Payload<DID>>,
{
type DID = DID;
type Payload = Payload<DID>;
Expand Down Expand Up @@ -166,7 +168,7 @@ where
impl<DID: Did + Clone, V: varsig::Header<C> + Clone, C: Codec + TryFrom<u64> + Into<u64>> Serialize
for Delegation<DID, V, C>
where
Payload<DID>: TryFrom<Ipld>,
Payload<DID>: TryFrom<Named<Ipld>>,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
Expand All @@ -179,8 +181,8 @@ where
impl<'de, DID: Did + Clone, V: varsig::Header<C> + Clone, C: Codec + TryFrom<u64> + Into<u64>>
Deserialize<'de> for Delegation<DID, V, C>
where
Payload<DID>: TryFrom<Ipld>,
<Payload<DID> as TryFrom<Ipld>>::Error: std::fmt::Display,
Payload<DID>: TryFrom<Named<Ipld>>,
<Payload<DID> as TryFrom<Named<Ipld>>>::Error: std::fmt::Display,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
Expand Down
Loading

0 comments on commit 61ed0ca

Please sign in to comment.