Skip to content
Closed
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
File renamed without changes
3 changes: 2 additions & 1 deletion src/builders.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use frame_support::sp_std::prelude::*;
use product_registry::ProductId;
use core::fmt;
use crate::types::*;

// --- ShipmentBuilder ---
Expand Down Expand Up @@ -83,7 +84,7 @@ where

impl<Moment> ShippingEventBuilder<Moment>
where
Moment: Default,
Moment: Default + fmt::Debug,
{
pub fn of_type(mut self, event_type: ShippingEventType) -> Self {
self.event_type = event_type;
Expand Down
89 changes: 43 additions & 46 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#![cfg_attr(not(feature = "std"), no_std)]

use codec::alloc::string::ToString;
use frame_support::{
decl_error, decl_event, decl_module, decl_storage, dispatch, ensure, sp_std::prelude::*,
debug, decl_error, decl_event, decl_module, decl_storage, dispatch, ensure,
sp_std::prelude::*,
};
use frame_system::{ self as system, ensure_signed, offchain::SendTransactionTypes };

Expand Down Expand Up @@ -65,6 +67,7 @@ decl_error! {
ShipmentHasTooManyProducts,
ShippingEventAlreadyExists,
ShippingEventMaxExceeded,
OffchainWorkerAlreadyBusy
}
}

Expand Down Expand Up @@ -176,25 +179,16 @@ decl_module! {
Ok(())
}

// fn offchain_worker(_block_number: T::BlockNumber) {
// if Self::ocw_tasks().len() == 0 { return; }
// let mut tasks: Vec<OcwTask<T::AccountId, T::Moment>> = <OcwTasks<T>>::get();

// while tasks.len() > 0 {
// let task = tasks.remove(0);
// debug::info!("ocw task: {:?}", task);
// let _ = Self::notify_listener(&task).map_err(|e| {
// debug::error!("Error notifying listener. Err: {:?}", e);
// });
// }

// // Submit a transaction back on-chain to clear the task queue
// let call = Call::clear_ocwtasks();

// let _ = SubmitTransaction::<T, Call<T>>::submit_unsigned_transaction(call.into()).map_err(|e| {
// debug::error!("Failed in submitting tx for clearing ocw taskqueue. Err: {:?}", e);
// });
// }
fn offchain_worker(block_number: T::BlockNumber) {
let ev_indices = Self::ocw_notifications(block_number);
for idx in ev_indices {
if let Some(ev) = Self::event_by_idx(idx) {
if let Err(err) = Self::notify_listener(&ev) {
debug::error!("notify_listener error: {}", err);
}
}
}
}
}
}

Expand All @@ -208,32 +202,7 @@ impl<T: Trait> Module<T> {
ShippingEventBuilder::<T::Moment>::default()
}

// fn notify_listener(task: &OcwTask<T::AccountId, T::Moment>) -> Result<(), &'static str> {
// let request =
// sp_runtime::offchain::http::Request::post(&LISTENER_ENDPOINT, vec![task.to_string()]);

// let timeout =
// sp_io::offchain::timestamp().add(sp_runtime::offchain::Duration::from_millis(3000));

// let pending = request
// .add_header(&"Content-Type", &"text/plain")
// .deadline(timeout) // Setting the timeout time
// .send() // Sending the request out by the host
// .map_err(|_| "http post request building error")?;

// let response = pending
// .try_wait(timeout)
// .map_err(|_| "http post request sent error")?
// .map_err(|_| "http post request sent error")?;

// if response.code != 200 {
// return Err("http response error");
// }

// Ok(())
// }

pub fn store_event(event: ShippingEvent<T::Moment>) -> Result<ShippingEventIndex, Error<T>> {
fn store_event(event: ShippingEvent<T::Moment>) -> Result<ShippingEventIndex, Error<T>> {
let event_idx = EventCount::get()
.checked_add(1)
.ok_or(Error::<T>::ShippingEventMaxExceeded)?;
Expand All @@ -245,6 +214,7 @@ impl<T: Trait> Module<T> {
Ok(event_idx)
}

// (Public) Validation methods
pub fn validate_identifier(id: &[u8]) -> Result<(), Error<T>> {
// Basic identifier validation
ensure!(!id.is_empty(), Error::<T>::InvalidOrMissingIdentifier);
Expand All @@ -271,4 +241,31 @@ impl<T: Trait> Module<T> {
);
Ok(())
}

fn notify_listener(ev: &ShippingEvent<T::Moment>) -> Result<(), &'static str> {
debug::info!("notifying listener: {:?}", ev);

let request =
sp_runtime::offchain::http::Request::post(&LISTENER_ENDPOINT, vec![ev.to_string()]);

let timeout =
sp_io::offchain::timestamp().add(sp_runtime::offchain::Duration::from_millis(3000));

let pending = request
.add_header(&"Content-Type", &"text/plain")
.deadline(timeout) // Setting the timeout time
.send() // Sending the request out by the host
.map_err(|_| "http post request building error")?;

let response = pending
.try_wait(timeout)
.map_err(|_| "http post request sent error")?
.map_err(|_| "http post request sent error")?;

if response.code != 200 {
return Err("http response error");
}

Ok(())
}
}
51 changes: 9 additions & 42 deletions src/types.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use core::fmt;
use codec::{ Decode, Encode };
use fixed::types::I16F16;
use frame_support::{ sp_runtime::RuntimeDebug, sp_std::prelude::* };
Expand Down Expand Up @@ -74,6 +75,14 @@ pub struct ShippingEvent<Moment> {
pub timestamp: Moment,
}

impl<Moment> fmt::Display for ShippingEvent<Moment> where
Moment: fmt::Debug
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self)
}
}

#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)]
pub struct ReadPoint {
pub latitude: Decimal,
Expand All @@ -97,45 +106,3 @@ pub struct Reading<Moment> {
pub timestamp: Moment,
pub value: Decimal,
}

// #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)]
// pub enum OcwTaskType {
// ShipmentRegistration,
// ShipmentPickup,
// ShipmentDelivery,
// }

// impl OcwTaskType {
// pub fn from_shipping_event_type(
// shipping_event_type: &ShippingEventType,
// ) -> Result<OcwTaskType, &'static str> {
// match shipping_event_type {
// ShippingEventType::ShipmentRegistered => Ok(OcwTaskType::ShipmentRegistration),
// ShippingEventType::ShipmentPickup => Ok(OcwTaskType::ShipmentPickup),
// ShippingEventType::ShipmentDelivery => Ok(OcwTaskType::ShipmentDelivery),
// ShippingEventType::SensorReading => Err("Unsupported shipping event type conversion"),
// }
// }
// }

// #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)]
// pub enum OcwTaskPayload<AccountId, Moment> {
// Shipment(Shipment<AccountId, Moment>),
// ShippingEvent(ShippingEvent<Moment>),
// }

// #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)]
// pub struct OcwTask<AccountId, Moment> {
// r#type: OcwTaskType,
// payload: OcwTaskPayload<AccountId, Moment>,
// }

// impl<A, M> fmt::Display for OcwTask<A, M>
// where
// A: fmt::Debug,
// M: fmt::Debug,
// {
// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// write!(f, "{:?}", self)
// }
// }
42 changes: 22 additions & 20 deletions types.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
{
"Identifier": "Vec<u8>",
"Decimal": "u32",
"ProductId": "Identifier",
"Identifier": "Vec<u8>",
"Decimal": "i32",
"ShipmentId": "Identifier",
"ShippingEventIndex": "u128",
"DeviceId": "Identifier",

"ShipmentStatus": {
"_enum": [
"Pending",
Expand All @@ -18,22 +21,32 @@
"registered": "Moment",
"delivered": "Option<Moment>"
},
"ShippingEventIndex": "u64",
"DeviceId": "Identifier",
"ShippingOperation": {
"_enum": [
"ShipmentPickup",
"ShipmentDelivery"
"Pickup",
"Scan",
"Deliver"
]
},
"ShippingEventType": {
"_enum": [
"ShipmentRegistration",
"ShipmentPickup",
"SensorReading",
"ShipmentDelivery"
"ShipmentScan",
"ShipmentDeliver"
]
},
"ShippingEvent": {
"event_type": "ShippingEventType",
"shipment_id": "ShipmentId",
"location": "Option<ReadPoint>",
"readings": "Vec<Reading<Moment>>",
"timestamp": "Moment"
},
"ReadPoint": {
"latitude": "Decimal",
"longitude": "Decimal"
},
"ReadingType": {
"_enum": [
"Humidity",
Expand All @@ -44,21 +57,10 @@
"Vibration"
]
},
"ReadPoint": {
"latitude": "Decimal",
"longitude": "Decimal"
},
"Reading": {
"device_id": "DeviceId",
"reading_type": "ReadingType",
"timestamp": "Moment",
"value": "Decimal"
},
"ShippingEvent": {
"event_type": "ShippingEventType",
"shipment_id": "ShipmentId",
"location": "Option<ReadPoint>",
"readings": "Vec<Reading<Moment>>",
"timestamp": "Moment"
}
}
}