"November2010" is the first formal milestone for the Snow Dots project. It corresponds to the repository tag called November2010: https://snow-dots.googlecode.com/svn/tags/November2010
Documentation contemporary with November2010 is also available.
November2010 might receive obvious bug fixes, but new API and feature changes will go in the trunk, to be included in a later milestone.
There is a companion November2010 tag for the Tower of Psych project: https://tower-of-psych.googlecode.com/svn/tags/November2010 The Snow Dots and Tower of Psych "November2010" revisions are expected to work together.
Recent changes for November2010 include the following:
Digital Output
abstract model/interface
TTL pulse, one at a time
TTL sequence with realtime spacing
strobed code/word This is done as of r381.
implementation for Measurement Computing 1208FS
length of TTL sequence vs. length of device HID report
documentation of mexHID timestamps vis. the 1208FS This is done as of r381.
mexHID features
issues 37, 38, 40, 44 about "vectorization", seizing, and meaningful descriptions
mexHID needs documentation, especially about USB frame timing returns This is done as of r391.
Online Data Access
dotsTheComputablesManager
a remote manager
server to run on e.g. Plexon machine
knows about, synchronizes topsDataLog incrementally
topsDataLog may only contain data convertible to mxGram
mxGram can send function handles
may invoke compute() on managedObjects periodically (could be inf period) This is done as of r402.
dotsComputable
result = compute() to e.g. access Plexon SDK
result = compute() to be invoked via client-side object for e.g online reverse correlation
compute() result also stored in computeResult property to access periodic results
dotsComputableFunction invokes arbitrary function with arguments This is done as of r402.
"Physiology" Task
two-alternative task
similar to some monkey electrophysiology experiments
integration test: should run to completion without subject or attendant
uses Digital Output to Plexon
serial numbers used to reconcile client and Plexon clocks
timing test: TTL sequence connected to Plexon analog input
uses Online Data Access to Plexon
each trial, analyzes and displays TTL sequence seen at Plexon's analog input
same analysis must be available offline
clock reconciliation from probed words applied to analog inputs
These are done, as of r438.
Documentation
scripted regeneration
script to rebuild with doxygen and package dots and tops together
make HTML docs servable from project sites by including in SVN repository, as in http://code.google.com/p/support/issues/detail?id=720
This is done, as of r458.
doxycomments
each class must have doxycomment overview
each class must have doxycomments for each member
no doxycomments may be out of date
but not all doxycomments need be complete/verbose
This is done, as of r490.


{% extends 'layout.html' %} {% set version = "v5" %} {% set heading = "Confirmation email link has expired" %} {% set mainClasses = "nhsuk-main-wrapper--s" %} {% block beforeMain %} {% endblock %} {% block content %}
The link has expired because:
To confirm your email address, you need to enter your email address again.


This is the main page for the golang service will eventually be something else after the APIs have been fully built out hopefully


Around a fortnight back I wrote about OpenCL accelerated Merkle Tree construction technique, while using
Rescue Prime Hash as underlying collision resistant, cryptographic hash function for obtaining immediate parent node from two children
nodes ( either leaves/ intermediates ). You can find that post here.
During last two weeks, I've made some improvements in Rescue Prime Hash implementation and also ported it to SYCL. If you happen to
be specifically interested in those changes/ improvements, I suggest you take a look at following pull requests.
Along with that I also explored a different way of Merklization, where given problem statement is same as before i.e.
when N -many leaf nodes of some Binary Merkle Tree are provided with and (N - 1) -many intermediate nodes to be computed.
In this new way of Merklization, I change which work-items are tasked to compute which intermediate nodes and how many
kernel dispatch rounds are required for computing all intermediate nodes. But, as usual, that itself comes with its benefits and drawbacks.
Today in this post, I plan to study design and performance of two Merklization techniques, that I've devised, while
using SYCL for implementation.
Same as last post, I'm not going to be explaining how I improved Rescue Prime implementation in SYCL, but I note that
a huge portion of Merklization performance boost comes from optimized implementation of Rescue Prime in SYCL.
I'll do a deep study of that in coming weeks, as promised before.
Let me begin with the simple one, which henceforth I'll call Merklization approach 1. Here merklize function is provided with N -many leaf nodes, where N = 2i ∀ i ∈ {1, 2, ...}. (N - 1) -many intermediate nodes are computed by dispatching compute kernel log2N times. Say for example, if I start with N = 32, all intermediates are computed in 5 rounds, as shown below.
You should also notice, there are 5 rounds and each of them are data dependent on previous dispatch round. But good news is that each of these rounds are easily parallelizable, due to absence of any intra-round data dependency. For some specific dispatch round if input to merklize has N intermediate/ leaf nodes, each pair of consecutive nodes are read by respective work-items ( N >> 1 in total ) which are merged into single Rescue Prime digest and stored in proper memory allocation. There is scope of global memory access coalescing, as non-strided, contiguous memory addresses are accessed by each work-item. Let us take help of a diagram to better appreciate the scope of parallelism.
In above diagram, N ( = 16 ) -many leaf nodes are used for depicting execution flow. It requires 4 kernel dispatch rounds to compute all intermediates and each of them are data dependent on previous round. Each dispatch round shows how many work-items are required to parallelly compute all computable intermediate nodes, by invoking Rescue merge function; which work-item accesses which pair of consequtive nodes ( either leaves/ intermediates; leaves applicable only during round 0 ). Note, very first memory location ( resevered for some Rescue Prime digest ) is never accessed by any of dispatched kernels, because (N - 1) -many intermediate nodes are stored in memory allocated for storing total of N -many intermediate nodes, where N is power of 2 i.e. ( N & (N - 1) == 0 ).
Implementing this in SYCL is pretty easy, using USM allocation allows me to perform pointer arithmetics, which is much more familiar compared to SYCL buffer/ sub-buffer/ accessor. If you've gone through my last post, where I walked you through equivalent implementation using OpenCL, you should notice as SYCL 2020 USM based memory allocation is being used no such issue of device memory base address alignment is encountered here. I suspect, if I had to implement SYCL variant using SYCL buffer/ sub-buffer/ accessor abstraction ( which is useful due to its automatic dependency chain inference ability ) I could have stumbled upon alignment issues while sub-buffering. Also SYCL being single source programming model, it's much easier to program compared to raw OpenCL --- less verbosity is encountered. I suggest you take a look here for exploring exact implementation details of approach 1.
Notice when N is relatively large, say = 224, total 24 kernel dispatch rounds will be required to compute all intermediate
nodes. Dispatching kernel requires host-device interaction, which is not cheap. Also OpenCL/ SYCL doesn't yet
allow recording commands into a buffer and then replaying same when required to be executed as I can do in Vulkan Compute; with that during actual kernel execution,
host-device interaction can be reduced and more work will be ready for offloading, while suffering less from host latencies due to say context switching.
Well, OpenCL has this extension
just to experiment with that idea, but today I'm working with SYCL, where I've not yet discovered anything similar. Motivated by this reason, I decided to devise a way
so that kernel dispatch round count can be reduced while Merklizing.
I'm going to refer to this new Merklization technique as approach 2. Say we've N = 224 -many leaf nodes and we're using work-group
size B = 28, then number of required kernel dispatch rounds for constructing Merkle Tree using approach 2 will be
log2(N >> (2 + log2B)) + 1, which turns out to be 15, much lesser than 24, which would be required using approach 1.
Also note, it doesn't matter what is work-group size, required #-of kernel dispatch rounds will always be log2N using approach 1.
But using approach 2, work-group size can influence total #-of required kernel dispatch rounds to compute whole Merkle Tree.
If I increase work-group size B to say 29, then following aforementioned formula, I'll be required to dispatch kernel 14 times.
But as per my experience, increasing work-group size to that large value benefits less, which we'll explore soon.
Say, finally I decide to live with work-group size B = 26, I'll be required to perform 17 rounds of kernel dispatch, which is still lesser than
24 rounds, required in approach 1.
I've come up with following formula for computing required #-of kernel dispatch rounds using approach 2.
You should notice, an appended + 1, in each of these cases, that's coming from here
--- the very first round of kernel dispatch reads all N -many leaves from input buffer and writes (N >> 1) -many intermediate nodes
( living just above leaf nodes ) in designated location of output buffer. After that remaining intermediate nodes are computed
in one/ many rounds. Note, each of these kernel dispatch rounds are data dependent on previous one, which is due to
inherent hierarchical structure of Merkle Tree.
Let me now explain approach 2, while attempting to foresee what kind of (dis-)advantage it may bring to Merklization.
Say N = 16 and work-group size I'm willing to work with is 2. Then during first round, 8 work-items will be dispatched, each computing single Rescue Prime merge and total 8 intermediate nodes will be produced, who lives just above leaf nodes. Following above formula, I need to dispatch kernel 3 times for constructing whole Merkle Tree. First round looks like below.
During next round, which is dependent on first one, 4 work-items will be dispatched. As first step, each of these 4 work-items will be
computing one Rescue Prime merge, producing 4 intermediate nodes. These four work-items are globally numbered as {group: 0 => {0, 1, 2, 3}},
but remember I decided to work with work-group size of 2, so local indexing of 4 work-items will be {group: 0 => {0, 1}, group: 1 => {0, 1}}.
After first step in round 2, all work-items present in each of work-groups are synchronized, so that it's ensured that
next step can be proceeded into safely, without getting into trouble of data race. After all work-items ( = 2, in number ) in work-group
reach sycl::group_barrier(...), only even indexed work-items are chosen for computing next level of
intermediate nodes, which ensures odd indexed work-items don't cause any data race. After all even indexed work-items
have computed upper level of intermediate nodes, all work-items in a work-group are synchronized again just to ensure that
this iteration step's data will be available ( i.e. visible to next set of active work-items ) for use in next iteration.
Now question is when to stop this iterative process ?
I use (1 << (iter - 1)) < B as iteration control condition, where iter = 1 at start and then iter++
after each iteration completes.
Going back to our example, where work-group size B = 2, iter = 1 should be only iteration, as after iter++
stopping criteria is reached ( 2 < 2 == !true ). Looking at following diagram also asserts so, only root of tree is left to
be computed, which will be done in last kernel dispatch round.
In third and last kernel dispatch round, only 1 work-item is launched for computing root of Merkle Tree and no more iterations
are required ( step two can be skipped ), because there is nothing else left for computation. Once again going back to approach 2, I'll demonstrate with N = 256 and B = 16
so that you can appreciate the need for work-group sychronization and also understand how costly it can become.
Formula says, 3 kernel dispatch rounds should be enough to compute all intermediate nodes of Binary Merkle Tree with 256 leaf nodes.
In first round, 128 work-items are dispatched for computing 128 intermediate nodes, living just above 256 leaf nodes.
In second kernel dispatch round, 64 work-items are dispatched for first computing 64 intermediate nodes from 128 intermediate nodes, computed
during last round of dispatch. Remember B = 16 is our work-group size, so 16 work-items per work-group are synchronized
before they decide to execute next step. As per loop control condition (1 << (iter - 1)) < B,
it's safe to execute loop with iter = 1. That means, 8 even indexed work-items among 16 work-items in each of 4 work-groups
will be activated to compute 8 intermediate nodes, producing total of 8 x 4 = 32 intermediate nodes from 64 intermediate nodes
which were computed during previous step by 4 work-groups. Let us expand into 8 even indexed work-items to be activated
.
It means among following 16 work-items ( per work-group; making total of 64 -many dispatched ), who all participated in first step of second round,
only even indexed 8 work-items will participate in second step i.e. iteration with iter = 1.
Following 32 work-items will be active, computing 32 intermediate nodes from 64 intermediate nodes, computed during first step of second dispatch round. This is exactly the reason behind work-group synchronization after first step ( in second kernel dispatch round ), so it's ensured that all 16 work-items in work-group have computed the intermediate node it was responsible for. And only after that 8 selected work-items ( in a work-group ) can safely use previously computed 16 intermediate nodes.
After iteration with iter = 1, all 16 work-items in work-group to be synchronized, so that necessary intermediate nodes are visible to all work-items, who will be activated during next iteration i.e. iter = 2. Before we can go and execute iteration with iter = 2, we must check loop termination condition. As assert 2 < 16, execution can proceed. This time, 4 even indexed work-items ( per work-group ) among last iteration's 8 active work-items, will be activated for computing total of 4 x 4 = 16 intermediate nodes, as shown below. Once they reach end of loop, 16 work-items ( per work-group ) are synchronized, so that path of entering next round is paved well, by ensuring memory visibility.
Iteration iter = 3 can be executed, as loop termination condition doesn't yet satisfy ( i.e. assert 4 < 16 ). In this iteration, 2 even indexed work-items among last iteration's 4 active work-items ( per work-group ) will be activated for computing total 2 x 4 = 8 intermediate nodes, shown below. After completion of this iteration, all work-items in work-group will be synchronized, as usual.
Last iteration of second round i.e. iter = 4, will activate 1 ( and only one ) even-indexed work-item among 2 active work-items from last iteration ( per work-group ) and produce total of 4 intermediate nodes, which looks like below. Note this is last iteration because after that with iter = 5 loop termination condition ( i.e. (1 << (iter - 1)) < 16 ) is triggerred.
Actual reason behind stopping iteration is that I can't synchronize across work-groups, which will be required
in next iteration, if I've to proceed. If I decide to go with iter = 5, I need to compute 2 intermediate
nodes from (total) 4 intermediate nodes computed during last iteration. But those 4 input intermediate nodes are computed
by 4 different work-items who are part of 4 different work-groups ( see above depiction ).
Question is when to start executing iteration with iter = 5 ?
Answer is when 32 work-items ( across each of two possible consecutive pair of work-groups ) agree that they've completed previous iteration & data written to global memory during that is safely available for consumption.
As it's not possible to synchronize across work-groups, I can't safely start executing next iteration i.e. iter = 5.
There's a high chance that I'll end up reading intermediate node data when it's still in undefined state.
If I had a mechanism to synchronize across work-groups, following depicts which work-items will be active during iteration iter = 5.
As that is not possible, I'll have to dispatch another ( final ) round of kernel, for computing remaining intermediate nodes. Before I get to that I'd like to check how many intermediate nodes are already computed among 255 target intermediate nodes. Following table shows I've to still compute 3 intermediate nodes, which are root of Merkle Tree and their two immediate children.
In final kernel dispatch round, I'll dispatch 2 work-items ( in single work-group ), who will compute 2 intermediate nodes in step one from previous round's 4 computed intermediate nodes. After step one, these two work-items are synchronized so that in step two previous step's global memory changes ( i.e. write ops ) are ensured to be visible in correct state. In step two, first loop initiation/ termination condition is checked i.e. assert 1 < 2 and only even indexed work-item is activated to execute loop body, which computes root of Merkle Tree. With that all intermediate nodes are computed for Binary Merkle Tree with N = 256 leaf nodes.
Few points to note here, if we increase work-group size for kernel dispatches in approach 2, it seems to be beneficial
because as per our formula lesser kernel dispatch rounds will be required. But approach 2 also requires us to perform
work-group level synchronization, that means when work-group size is doubled up, double -many work-items will be required to
synchronize so that safely next iteration can be executed, while consuming previous iteration's global memory
writes ( intermediate nodes computed during last iteration/ step ). And I also note synchronization is costly. Another point to note,
after every round of work-group synchronization half of previous round's active work-items ( in a work-group ) are deactivated that means
most of work-items are not doing any useful work, which is just waste of computation ability of highly parallel GPU architecture.
If you happen to be interested in inspecting approach 2 in detail, I suggest you take a look at
this
SYCL implementation.
Now it's time to benchmark both of these implementations to actually see what do they bring on table. I used Nvidia Tesla V100 for that purpose, while compiling single source SYCL program with SYCL/ DPC++ ( experimental CUDA backend ). I'm also placing last column which shows results obtained by benchmarking equivalent OpenCL implementation of approach 1, which I already presented at end of this post.
As speculated, approach 1 is ~2x faster compared to approach 2. Though approach 2 has lesser kernel dispatch rounds but costly work-group level synchronization, mostly ( which keeps increasing after every step/ iteration ) inactive work-items etc. are reasons behind lower performance. While in approach 1, there may be log2N -many dispatch rounds, but during each dispatch every work-item does some useful work, hence compute ability of GPU is better utilized, resulting into better performance. Equivalent OpenCL implementation of Merklization approach 1 doesn't perform as good as SYCL variant. Note, SYCL with CUDA backend uses PTX as IR, but OpenCL on Nvidia GPU uses SPIR as Intermediate Representation language. I'd like to also note, OpenCL implementation is powered by Rescue Prime merge(...) function where hash state is represented using vector with 16 lanes ( each of 64 -bit width ) i.e. ulong16. But in SYCL implementation Rescue hash state is represented using an array of 3 vectors each 4 lanes wide ( each vector lane is of 64 -bit width ) i.e. sycl::ulong4[3]. That means, in OpenCL implementation, last 4 lanes are used for padding purpose, because Rescue Prime hash state is 12 field elements ( 64 -bit each ) wide, wasting both compute and memory capability of accelerator; though it's much easier to program and more readable. I implemented Rescue Prime hash with hash state represented using both sycl::ulong16 and sycl::ulong4[3] and performance improvement I noticed in later variant is non-negligible. This improvement in Rescue merge routine indeed boosts SYCL implementation, compared to equivalent OpenCL one.
With this I'll wrap up today. You can find SYCL implementation of both merklize(...) routines here. For OpenCL variant take a peek at this repository. In coming days, I plan to talk about other topics which I'm exploring/ will explore. Have a great time !


Toggle navigation
Openfrontier CI Platform
OCIP Dashboard
This platform can be used for demos, training and to start real projects.


new imageXObject(objectNumber, generationNumber, width, height, colorSpace, bpc, filter, options)
Initialize new imageXObject object.
Parameters:
| Name | Type | Argument | Default | Description |
|---|---|---|---|---|
objectNumber |
int | Unique number to define this object. | ||
generationNumber |
int | defining the number of time the pdf has been modified (default is 0 when creating). | ||
width |
int | Width of the image to be rendered on page in pt. | ||
height |
int | Height of the image to be rendered on page in pt. | ||
colorSpace |
int |
<optional> |
DeviceRGB | Color space of the image. |
bpc |
int |
<optional> |
8 | Number of bits per color channel component. |
filter |
int |
<optional> |
Filter for decoding the image data. | |
options |
object |
<optional> |
Extra options that can be set. |
- Source:
- classes/imageXObject.js, line 16
Extends
Members
-
body :int
-
The content of this obj.
- Inherited From:
- Default Value:
- []
- Source:
- classes/obj.js, line 29
-
bpc :int
-
Bits per component
- Default Value:
- 8
- Source:
- classes/imageXObject.js, line 40
-
colorSpace :pdfJS.utils.colorSpace
-
Color space of the image.
- Source:
- classes/imageXObject.js, line 34
-
content :[string]
-
The content of this stream.
- Inherited From:
- Default Value:
- []
- Source:
- classes/stream.js, line 19
-
dictionary :object
-
Specifying the dictionary part of a PDF object (e.g dictionary['SomeKey'] = 'SomeValue').
- Inherited From:
- Default Value:
- {}
- Source:
- classes/stream.js, line 25
-
filter :pdfJS.utils.filterDecoder
-
Decoding filter for the image data.
- Source:
- classes/imageXObject.js, line 45
-
generationNumber :int
-
Non-negative integer representing the generation number of pdf internal objects.
- Inherited From:
- Default Value:
- 0
- Source:
- classes/obj.js, line 23
-
height :int
-
Height of the image to be rendered on page in pt.
- Source:
- classes/imageXObject.js, line 29
-
name :string
-
Name
- Default Value:
- Im1
- Source:
- classes/imageXObject.js, line 52
-
objectNumber :int
-
Positive integer representing the object number of pdf internal objects.
- Inherited From:
- Default Value:
- 0
- Source:
- classes/obj.js, line 17
-
options :object
-
TODO: Extra options
- Default Value:
- {}
- Source:
- classes/imageXObject.js, line 58
-
width :int
-
Width of the image to be rendered on page in pt.
- Source:
- classes/imageXObject.js, line 24
Methods
-
addImage(pageObj, x, y, w, h) → {pdfJS.imageXObject#}
-
Graphic Operation Setter. Please see graphicOperators for available operations and corresponding set of operands.
Parameters:
Name Type Description pageObj
pdfJS.pageNode Page to add image. x
int Translation in X direction (pt). y
int Translation in Y direction (pt). w
int Width of the image on page (pt). h
int Height of the image on page (pt). - Source:
- api/graphics.js, line 465
Returns:
- Type
- pdfJS.imageXObject#
-
out() → {string}
-
Output PDF data string for this obj.
- Inherited From:
- Source:
- classes/obj.js, line 37
Returns:
- Type
- string
-
push(args) → {pdfJS.stream}
-
Shortcut to pushing content to the stream (same as stream.content.push('something');
Parameters:
Name Type Description args
string stream.push(item1, item2, . . . , itemX) - Inherited From:
- Source:
- classes/stream.js, line 58
Returns:
Return this stream object.- Type
- pdfJS.stream


66
1 Yahweh also said this:
"All of heaven is like my throne,
and the whole earth is like my footstool.
So you could certainly not build a house
that would be adequate for me to live in and rest!
2 I have created everything;
all things exist because I made them.
That is true because I, Yahweh, have said it.
The people I am most pleased with are those who are humble,
who patiently endure it when they suffer,
and who tremble when they hear me rebuking them.
3 You have chosen to continually do the things that you want to do:
some of you slaughter oxen to sacrifice them to me,
but you also bring human sacrifices to your idols!

When I spoke, you did not pay attention.
You did many things that I say are evil,
and you chose to do things that I did not like.

They make fun of you, and they say,
'Yahweh should show his glorious power!
We want to see him do something to cause you to be truly happy.'
But some day those people will be very disgraced."
6 At that time, you will listen to the noise in the city.
You will hear the shouting in the temple.
It will be the sound of Yahweh paying back his enemies.
7 No one ever heard that a woman gave birth to a baby
when she was just starting to have birth pains.
8 Certainly no one ever heard about such a thing happening,
and no one has ever seen it happen.
Similarly, no one ever heard that a nation was created in one instant,
not in one day.
But Jerusalem is like a woman who gives birth to children
as soon as she starts to have birth pains.
9 Women certainly do not bring infants to the time when they are ready to be born and then do not allow them to be born.
Similarly, Yahweh will do for Jerusalem what he has promised to do:
he will cause Jerusalem to be full of people again.
That will happen because Yahweh has said it.
10 You people in Jerusalem, rejoice!
And all you people who love Jerusalem should also be happy.
You people who were sad because of what happened to Jerusalem,
you should now be glad.
11 You people in Jerusalem will have everything that you need,
like a baby that gets all it needs from its mother's breasts.
You will enjoy all the abundant and glorious things in the city.
12 Yahweh has promised,
"I will cause Jerusalem to be full of valuable things that come from other nations;
those things will pour into Jerusalem; it will be like a big flood.
I will take care of the people of Jerusalem
like women care for the babies that they nurse.
13 I will comfort you people in Jerusalem like mothers comfort their children."
14 When you see those things happen,
you will rejoice.
Your old bones will become strong again
like in the springtime, when the grass grows.
When that happens, everyone will know that Yahweh has power to help those who worship and obey him,
but that he is angry with his enemies.
15 Yahweh will come down with flames of fire,
and his chariots will come down like a whirlwind;
he will be extremely angry,
and he will punish his enemies by burning them in a fire.
16 It is as though Yahweh had a big sword,
and he will judge and execute many people.
17 Yahweh says, "Some of you will prepare yourselves to enter the garden of idols by washings and special diets and clothing, and you follow into that place, those who eat the meat of pigs and mice, and other things that I have forbidden you to eat.
18 I know all the evil things that they all think and do. It is now time for me to gather together the people who live in all nations and who speak all languages, and to show them that I am very great.
19 I will do something among them to show everyone who they are, and those whom I have spared will go to various distant countries: To Tarshish, Put, Lud (home of archers), Meshech, Tubal, Javan, and to distant islands. I will send them to proclaim to nations that have never heard about me that I am very great and glorious.
20 Then they will bring back here your relatives who have been exiled, like the offerings that my Israelite people used to bring in the correct manner to the temple. They will travel to Jerusalem, where my holy mountain is; they will come on horses and in chariots, in wagons, on mules and on camels.
21 I solemnly promise that I will appoint some of them to be priests, and others to do other work in my temple. That will surely happen because I, Yahweh, have said it.
22 I also promise that just like the new heaven and the new earth will last forever, you will always have descendants, and you will always be honored.
23 At every festival to celebrate the Sabbath each week and the new moon each month, everyone will come and worship me. That will surely happen because I, Yahweh, have said it.
24 Then they will go out of Jerusalem and look at the corpses of those who rebelled against me. The maggots in those corpses will never die, the fire will never stop burning them, and everyone who sees their corpses will detest them."


Garissa DCIO Among Ten People Injured In Ukasi Accident Along Nairobi-Garissa Road
by Mercy AumaGarissa DCIO among ten people injured in Ukasi accident that occurred along Mwingi-Garissa road early today.
The accident involved City Link Bus at Ukasi stretch along Mwingi – Garissa road with unconfirmed number of people said to be caught up in the accident.
In a separate incident yesterday, several people were reported injured after a truck rammed into 8 vehicles along Mai Mahiu-Limuru escarpment.
Read:Several Injured After Truck Rams Into 8 Vehicles At Mai Mahiu Escarpment
In a report by the Standard, the truck was said to have developed mechanical problems and rammed onto oncoming vehicles before finally crashing near the Italian Catholic Church.
The accident caused massive gridlock, with police officers calling upon motorists to use alternative routes.
In another separate incident on Wednesday, two lives were lost in Nyamira County after a matatu collided with a truck along Sotik-Keroka Road.
It was reported that the truck rammed into the 14-seater matatu head on while trying to avoid the cess collection point.
This story has been updated to recant reports of fatalities earlier reported.


Показалось
by zapovednik_slonovᴀɴᴅʀᴇᴀ ᴄᴏᴛᴛᴏɴᴇ on : “⤖ Island feels 𓇼 at @mahagiriresortnusalembongan”
2,925 Likes, 168 Comments — ᴀɴᴅʀᴇᴀ ᴄᴏᴛᴛᴏɴᴇ (@andrea_cottone) on Instagram: “⤖ Island feels 𓇼 at @mahagiriresortnusalembongan”www.instagram.com
Nusa Lembongan, Indonesia
Photo: andrea_cottone


Junkyard Wars
Several units modified for reclaim-oriented games.
Modified units can build mex, and sometimes something else.
Bug: Reclaim rate is limited by build rate - if build speed is being attenuated by lack of metal, reclaim rates will also be reduced, exacerbating the problem. You must stop some spending to let reclaim rates recover.
Basic Combat Fab is the Junkyard Dog - a cheap scavenger which is also buildable by naval factories.
Advanced combat fabricator provides long-range auto-repair, manual-reclaim, and defense emplacements. It also has radar equal to it's fab range, hold CTRL to see the range. Buildable by naval factories.
Inferno has a powerful short-range lathe for mopping up an enemy base and quickly mining metal spots. However, it's flamethrower is less effective than vanilla. Nonetheless, you may need to hold fire if you want all the metal from a live target.
Vanguard has a heavy reclaim tool; you won't like the power bill, but it usually doesn't need to operate for long. It can also build walls to further protect units units behind it.
Firefly has a very weak lathe for picking up small rocks and trees, and can build radar for remote reconnaissance (albeit very, very slowly)
Gunship has a moderate lathe for reclaim raiding, and can build teleporters to call in reinforcements.


27 Dividend Boosts Announced November 18
by Fredrik ArnoldSummary
- Barron's Weekly posts a list of stocks announcing "dividend payment boosts" on the very last page of its financial data section. Here is your dog catcher 11/18/19 update.
- Last week, Barron's listed 27 stocks boosting dividends. The increases ranged $0.0018 per Q to $0.75 annually, and ranged 0.6% to 66.7% for this batch.
- Industrials with seven hikes and Financial Services with four showed the most increases last week.
- Ten top dividend-boosting stocks ranged from 10% to 64% in net gains calculated from broker targets plus dividends less broker fees.
- $5k invested in this week's lowest-priced five top-yield dividend-boosted dogs showed 2.49% less net-gain than that from $5k invested in all ten. Bigger, higher-priced dividend-boosted dogs ruled this post mid-November pack.
Foreword
Any collection of stocks is more clearly understood when subjected to yield-based (dog catcher) analysis, these dividend-boosted batches are perfect for the Arnold dog catcher process. Here is your November 18 data from Barron's for 58 dividend paying stocks supplemented by dog catcher analysis powered by YCharts.
Actionable Conclusions (1-10): Analysts Estimated 9.89% To 64.4% Net Gains For Ten Top Dividend-Boosted Stocks To November 18, 2020
Four of ten top dividend-boosted stocks by yield were among the top ten gainers for the coming year based on analyst 1-year target prices. (They are tinted gray in the chart below). Thus, this yield-based forecast for these booster dogs was graded by Wall St. Wizards as 40% accurate.
Source: YCharts.com
Projections were based on estimated dividends from $1000 invested in each of the highest yielding stocks and their aggregate one-year analyst median target prices, as reported by YCharts. Note: one-year target prices by lone analysts were not applied. Ten probable profit-generating trades projected to November 18, 2020, were:
Matthews International Corp. (MATW) was projected to net $643.97, based on the median of estimates from four analysts, plus dividends. The Beta number showed this estimate subject to risks 20% more than the market as a whole.
Helmerich & Payne (HP) was projected to net $273.19, based on the median of target estimates from twenty-five analysts, plus dividends, less broker fees. The Beta number showed this estimate subject to risks 59% more than the market as a whole.
Air Lease Corp. (AL) was projected to net $196.43, based on the median of target price estimates from thirteen analysts, plus annual dividend, less broker fees. The Beta number showed this estimate subject to risks 87% more than the market as a whole.
Griffon Corp. (GFF) was projected to net $172.712, based on dividends alone, plus a median of three target price estimates from three analysts, less broker fees. The Beta number showed this estimate subject to risks 113% above the market as a whole.
Grifols, S.A. (GRFS) was projected to net $167.75, based on dividends, plus the median of target prices estimated by three analysts, less broker fees. The Beta number showed this estimate subject to risk 7% over the market as a whole.
Motorola Solutions, Inc. (MSI) was projected to net $131.74, based on dividends, plus the median of target price estimates from fourteen analysts, less broker fees. The Beta number showed this estimate subject to risk 42% less than the market as a whole.
Four Corners Property Trust (FCPT) was projected to net $128.90, based on a median of target price estimates from seven analysts, plus dividends, less broker fees. The Beta number showed this estimate subject to risks 93% under the market as a whole.
HollyFrontier Corp. (HFC) was projected to net $117.84, based on a median of target price estimates from eighteen analysts plus annual dividends, less broker fees. The Beta number showed this estimate subject to risk 45% more than the market as a whole.
Suncor Energy Inc. (SU) was projected to net $113.78, based on dividends, plus the median of target price estimates from fifteen analysts, less broker fees. The Beta number showed this estimate subject to risks 5% over the market as a whole.
FirstEnergy Corp. (FE) was projected to net $98.88, based on dividends, plus the median of target price estimates from eighteen analysts, less broker fees. The Beta number showed this estimate subject to risks 82% under the market as a whole.
The average net gain in dividend and price was estimated at 20.45% on $10k invested as $1k in each of these ten stocks. These gain estimates were subject to average risks 24% more than the market as a whole.
Source: atlantatrails.com
The Dividend Dogs Rule
Stocks earned the "dog" moniker by exhibiting three traits: (1) paying reliable, repeating dividends, (2) their prices fell to where (3) yield (dividend/price) grew higher than their peers. Thus, the highest yielding stocks in any collection became known as "dogs." More precisely, these are, in fact, best called, "underdogs."
27 Dividend Boosted Stocks By Target Gains
Source: YCharts.com
27 Dividend Boosted Stocks By Yield
Source: YCharts.com
Actionable Conclusions (11-20): 10 Top Dividend Boosted Stocks By Yield
Top ten dividend boosted stocks reported in Barron's 11/18/19 by yield represented six of eleven Morningstar sectors plus one closed-end fund. The top of two energy dogs placed first, Helmrich & Payne Inc. [1]. The second energy dog placed seventh, Suncor Energy Inc. [7].
Then a single fund took second, Eagle Capital Growth (GRF) [2]. Two utilities placed third and eighth, Atlantica Yield PLC (AY) [3], and First Energy Corp. [8].
Two real estate representatives placed fourth, and fifth, Retail Value Inc. (RVI) [4], and Four Corners Property Trust Inc. [5]. A single industrials stock placed sixth, Grupo Aeroportuario del Pacifico S.A.B. de C.V. (PAC) [6]. Then a single financial services sector representative placed ninth, National Bankshares, Inc. (NKSH) [9].

Actionable Conclusions: (21-30) Top Ten November 18 Dividend-Boosted Dogs Showed 8.27-141.94% Upsides While (31) Five Down-Siders Plunged -0.17% to -18.64%
Source: YCharts.com
To quantify top dog rankings, analyst mean price target estimates provide a "market sentiment" gauge of upside potential. Added to the simple high-yield metrics, analyst mean price target estimates became another tool to dig out bargains.
Analysts Forecast A 2.49% Disadvantage For 5 Highest Yield, Lowest-Priced Dividend Boosted Stocks To 11/18/2020
Ten top dividend-boosted dogs were culled by yield for this update. Yield (dividend/price) results provided by YCharts did the ranking.
Source: YCharts.com
As noted above, top ten dividend boosted dogs screened 11/18/19 showing the highest dividend yields represented six of eleven Morningstar sectors and a fund.
Actionable Conclusions: Analysts Predicted 5 Lowest-Priced Of The Top Ten Highest-Yield Dividend Booster Dogs (32) Delivering 8.76% Vs. (33) 8.98% Net Gains by All Ten Come November 18, 2020
Source: YCharts.com
$5000 invested as $1k in each of the five lowest-priced stocks in the top ten dividend dividend booster kennel by yield were predicted by analyst 1-year targets to deliver 2.49% less gain than $5,000 invested as $.5k in all ten. The seventh lowest priced selection, Helmerich & Payne Inc. was projected by broker targets to deliver the best net gains of 27.32%.
Source: YCharts.com
The five lowest-priced top-yield dividend boosted dogs as of November 18 were: Eagle Capital Growth Fund, Atlantica Yield PLC; Four Corners Property Trust; MDU Resources Group Inc.; Suncor Energy Inc., with prices ranging from $8.21 to $31.83.
Five higher-priced dividend boosted dogs as of November 18 were: Retail Value Inc.; Helmerich & Payne; National Bankshares Inc.; First Energy Corp.; Grupo Aeroportuario del Pacifico SAB de CV, whose prices ranged from $38.36 to $107.65.
The distinction between five low-priced dividend dogs and the general field of ten reflected Michael B. O'Higgins' "basic method" for beating the Dow. The scale of projected gains based on analyst targets added a unique element of "market sentiment" gauging upside potential. It provided a here-and-now equivalent of waiting a year to find out what might happen in the market. Caution is advised, since analysts are historically only 20% to 80% accurate on the direction of change and just 0% to 20% accurate on the degree of change.
The net gain/loss estimates above did not factor in any foreign or domestic tax problems resulting from distributions. Consult your tax advisor regarding the source and consequences of "dividends" from any investment.
Stocks listed above were suggested only as possible reference points for your Dividend Boosted stock purchase or sale research process. These were not recommendations.
Source: Barron's Weekly & YCharts.com
Graphs and charts were compiled by Rydlun & Co., LLC from data derived from www.indexarb; YCharts; finance.yahoo; analyst mean target price by YCharts. Dog photo: atlantatrails.com
Get The Entire Weekly Dividend Boosted 'Safer' Dividend Dog Story
Click here to subscribe to The Dividend Dogcatcher. Get more information, the follow-up to this article, and a free two-week trial.
Catch A Dog On Facebook At 8:45 AM every NYSE trade day on Facebook/Dividend Dog Catcher, A Fredrik Arnold live video highlights a portfolio candidate in the Underdog Daily Dividend Show!
Root for the Underdog. Comment below on any stock ticker to make it eligible for my next FA follower report.
Disclosure: I/we have no positions in any stocks mentioned, and no plans to initiate any positions within the next 72 hours. I wrote this article myself, and it expresses my own opinions. I am not receiving compensation for it (other than from Seeking Alpha). I have no business relationship with any company whose stock is mentioned in this article.
Additional disclosure: This article is for informational and educational purposes only and should not be construed to constitute investment advice. Nothing contained herein shall constitute a solicitation, recommendation or endorsement to buy or sell any security. Prices and returns on equities in this article except as noted are listed without consideration of fees, commissions, taxes, penalties, or interest payable due to purchasing, holding, or selling same.


Overall 1.5 - 2 hours
None
Data modeling refers to how you organize the data within your database. Data modeling is the first step to creating a database. Having incorrect data models can cause your application to have inconsistent or inaccurate data, so it’s important to come up with data models that will represent your data well.
Understand how to analyze a scenario and identify entities, attributes, and data types to model that data in a database.
Read through the lesson slides for an intro to data modeling: Introduction to Data Models
Databases are made up of one or more tables. Each table has one or more columns. Database design is similar to something you’ve seen before: Object Oriented Programming. In OOP you need to choose which objects to create and which attributes each object should have. Similarly, for database modeling you need to decide which tables and columns your database will need.
Tables are sometimes also called “entities” and columns can be called “attributes” of an entity. In this lesson we’ll use the words interchangeably. The description of which tables and columns your database will have is called the “database schema”.
To model data, you’ll need to think through the pieces of data your application needs and how those pieces of data relate to each other.
When you’re modeling data, you’ll need to determine:
For today, we’ll focus on modeling one entity at a time. Let’s go through an example of modeling an entity and its attributes.
Say I’m making an app to help myself keep track of all the books I’ve read. Some features I want in my app are:
First we need to decide which entities we’ll need in our system. For this case, the entity we care about is Book.
Next, what attributes do we need? You could come up with tons of attributes an entity might have (e.g. a Book has the book text, number of chapters, color of the cover, who it’s dedicated to, year published, size of font, etc…) but in your database, you’ll want to stick with attributes that are needed for your app to function. So, for the features I want in my app, I’ll need:
Book
Each attribute needs to have a certain data type. (This is similar to JavaScript where variables have data types such as string or boolean). Different databases have their own sets of possible data types. Some common ones are:
Note: You’ll learn more about the difference between text and varchar later. For now we’ll consider them mostly interchangeable.
Let’s go back to our example and add data types:
Book
There are often multiple valid ways to model our data. Let’s return to our example from above. One way we could change the data model is instead of having a Book have an attribute “author”, we could have attributes for:
We might choose to make this change if we wanted to make sure to collect the author data in a structured form rather than just a free-form string. An example could be if we want to sort the data by author’s last name.
Each entity should have a “primary key”. This is a unique identifier for a given row in the database.
To understand rows, let’s look at an example. For each table in our database, we’ll have multple “rows” representing individual instances of the entity. For example, I might have 2 books:
Book:
Book:
How can I uniquely identify a book in my collection? A first thought might be to use the book’s title. But sometimes multiple books can exist with the same title. Or sometimes a title could change (e.g. if I typed it in wrong and later corrected it).
For books, an option could be to add an attribute for ISBN (International Standard Book Number), which is a unique identifier that happens to exist for books. Then the “isbn” column could be my primary key.
But what if I also wanted to add magazines into the table, which don’t have an ISBN?
A common solution to this is to create a new attribute called “id” (or something similar, like “bookId”). This attribute’s data type will be integer, and we’ll assign a unique value to every row.
Now our data model will look like:
Book
And our rows will look like:
Book:
Book:
Now we have a way to refer to each row that’s always unique, never null, and never changes.
Read https://www.vertabelo.com/blog/technical-articles/how-to-create-a-database-model-from-scratch for a more in-depth explanation and example of how to model your data. It describes basic data modeling as well as relationship between tables, which we’ll cover in an upcoming lesson.
Imagine you are creating a website to organize your personal recipe collection. You want to be able to:
Make a data model for this app, and answer the following questions:
In your own words, define the following terms:


Ocean [am80], ocean, in The Outer Sea
Last updated Turn #119
Ocean [am80], ocean, in The Outer Sea
------------------------------------------------------------------------
1: Pleasure Sloop [v5n], ship, 30 hulls, 1 rowing port, 90 sails, arrived
1: from Ocean [am79], owner:
1: Dorothy [v1b], Pen, with 39 peasants, 30 soldiers, 94 sailors,
1: accompanied by:
1: Cindy [z1c], Pen, with one worker, 45 soldiers, 11 skirmishers
1: Banian [e7n], Imperial Empire, knight, the High Priest of the
1: Church of Eres [151], with 16 soldiers, ten angels
1: Drummond [x8q], Imperial Empire, with 30 soldiers
1: Roland [o6t], Imperial Empire, Bishop of the Church of
1: Anteus [152], with 34 soldiers, five angels
1: Fortuis [h1m], Imperial Empire, with 20 soldiers
2: Pleasure Sloop [v5n], ship, 30 hulls, 1 rowing port, 90 sails,
2: departed for Endless Plains [an80].
Routes leaving Ocean:
North, to Ocean [al80], 6 days
East, to Ocean [am81], 6 days
South, plain, to Endless Plains [an80], Imperia, 2 days
West, to Ocean [am79], 6 days


The following example uses standard JSF converters to convert input data to the appropriate data type. In addition to standard converters a custom converter is also implemented on the phone number field. For the phone number, enter a full Canadian/USA number, starting with a 1 followed by ten digits, using spaces, dashes or round brackets as optional delimiters.
First Name:


You have claimed an existing organization as the new Signing Authority. If you are approved, you will be able to update site information and add new sites for your organization. It may take several business days for approval. You will be notified via the email address you provided.


RTACCT
Section: Maintenance Commands (8)Updated: 27 June, 2007
Index Return to Main Contents
NAME
nstat, rtacct - network statistics tools.SYNOPSIS
Usage: nstat [ -h?vVzrnasd:t: ] [ PATTERN [ PATTERN ] ]Usage: rtacct [ -h?vVzrnasd:t: ] [ ListOfRealms ]
DESCRIPTION
nstat and rtacct are simple tools to monitor kernel snmp counters and network interface statistics.OPTIONS
- -h -?
- Print help
- -v -V
- Print version
- -z
- Dump zero counters too. By default they are not shown.
- -r
- Reset history.
- -n
- Do not display anything, only update history.
- -a
- Dump absolute values of counters. The default is to calculate increments since the previous use.
- -s
- Do not update history, so that the next time you will see counters including values accumulated to the moment of this measurement too.
- -d <INTERVAL>
- Run in daemon mode collecting statistics. <INTERVAL> is interval between measurements in seconds.
- -t <INTERVAL>
-
Time interval to average rates. Default value is 60 seconds.
SEE ALSO
lnstat(8)
Index
This document was created by man2html, using the manual pages.
Time: 05:34:29 GMT, December 24, 2015


The reason why Christian Bale turned down fourth film offer
- Advertisement -
Christopher Nolan’s The Dark Knight Trilogy are undoubtedly some of the best comic book movies ever made.
Nolan’s critically acclaimed Batman movies starring Christian Bale are dark, grounded and gritty and Bale’s acting contributes towards the renewed perspective of comic book cinema.
Delivering a solid opening, earthmoving the second film and the poetic finale, the trilogy is perfect.
The box office success of The Dark Knight and The Dark Knight Rises, both of which grossed slightly over $US 1 billion led Warner Bros to decide that they wanted a fourth Batman film with Christian Bale but the actor declined.
- Advertisement -
Speaking to Toronto Sun in an interview, Bale talked about Nolan’s trilogy and why he declined the offer.
He said that he and Nolan had to reinvent it. Bale said there were people laughing at him when they were doing a new kind of Batman.
He said the reason it worked was because of Nolan’s take on it but the two of them were never arrogant to assume that there was an opportunity for one film at a time.
Nolan would say that they are making one film and that’s all they got.
So when people approached them and asked if they were going to make another, Nolan and Bale will still say that this was it and there will not be another opportunity.
Then when they said they will do the third one, Nolan said that if they were fortunate to make three, they will stop and walk away after that.
In many interviews, Nolan said that when he started writing Batman Begins with David Goyer in 2003, he always thought of doing three films.
Bale then added that when people went to Nolan and Bale to ask for a number four, he would say no, to stick to Nolan’s dream which was to do a trilogy. They didn’t want to stretch too far and become overindulgent.
That was why after Nolan stepped away and Bale was informed his services were no longer required.
Matt Reeves’ Batman movie will star Robert Pattinson the expected released date is 2021.
- Advertisement -


add
{{card.count}}, {{card.foil_count}}
({{card.set}}, {{card.card}})
{{cardHistory.directionTodayDaysAgoCache(card, 2) | currency}}
{{0 | currency}}
0" style="color:#4ab252;font-size:13px;">+{{cardHistory.directionTodayDaysAgoCache(card, 2) | currency}}
remove


Understanding Reticulum¶
This chapter will briefly describe the overall purpose and operating principles of Reticulum, a networking stack designed for reliable and secure communication over high-latency, low-bandwidth links. It should give you an overview of how the stack works, and an understanding of how to develop networked applications using Reticulum.
This document is not an exhaustive source of information on Reticulum, at least not yet. Currently, the best place to go for such information is the Python reference implementation of Reticulum, along with the code examples and API reference. It is however an essential resource to understanding the general principles of Reticulum, how to apply them when creating your own networks or software.
After reading this document, you should be well-equipped to understand how a Reticulum network operates, what it can achieve, and how you can use it yourself. If you want to help out with the development, this is also the place to start, since it will provide a pretty clear overview of the sentiments and the philosophy behind Reticulum.
Motivation¶
The primary motivation for designing and implementing Reticulum has been the current lack of reliable, functional and secure minimal-infrastructure modes of digital communication. It is my belief that it is highly desirable to create a cheap and reliable way to set up a wide-range digital communication network that can securely allow exchange of information between people and machines, with no central point of authority, control, censorship or barrier to entry.
Almost all of the various networking systems in use today share a common limitation, namely that they require large amounts of coordination and trust to work, and to join the networks you need approval of gatekeepers in control. This need for coordination and trust inevitably leads to an environment of central control, where it’s very easy for infrastructure operators or governments to control or alter traffic, and censor or persecute unwanted actors.
Reticulum aims to require as little coordination and trust as possible. In fact, the only “coordination” required is to know the characteristics of physical medium carrying Reticulum traffic.
Since Reticulum is completely medium agnostic, this could be whatever is best suited to the situation. In some cases, this might be 1200 baud packet radio links over VHF frequencies, in other cases it might be a microwave network using off-the-shelf radios. At the time of release of this document, the recommended setup for development and testing is using LoRa radio modules with an open source firmware (see the section Reference System Setup), connected to a small computer like a Raspberry Pi. As an example, the default reference setup provides a channel capacity of 5.4 Kbps, and a usable direct node-to-node range of around 15 kilometers (indefinitely extendable by using multiple hops).
Goals¶
To be as widely usable and easy to implement as possible, the following goals have been used to guide the design of Reticulum:
- Fully useable as open source software stack
Reticulum must be implemented with, and be able to run using only open source software. This is critical to ensuring the availability, security and transparency of the system.
- Hardware layer agnosticism
Reticulum shall be fully hardware agnostic, and shall be useable over a wide range physical networking layers, such as data radios, serial lines, modems, handheld transceivers, wired ethernet, wifi, or anything else that can carry a digital data stream. Hardware made for dedicated Reticulum use shall be as cheap as possible and use off-the-shelf components, so it can be easily replicated.
- Very low bandwidth requirements
Reticulum should be able to function reliably over links with a transmission capacity as low as 1,000 bps.
- Encryption by default
Reticulum must use encryption by default where possible and applicable.
- Unlicensed use
Reticulum shall be functional over physical communication mediums that do not require any form of license to use. Reticulum must be designed in a way, so it is usable over ISM radio frequency bands, and can provide functional long distance links in such conditions, for example by connecting a modem to a PMR or CB radio, or by using LoRa or WiFi modules.
- Supplied software
Apart from the core networking stack and API, that allows a developer to build applications with Reticulum, a basic communication suite using Reticulum must be implemented and released at the same time as Reticulum itself. This shall serve both as a functional communication suite, and as an example and learning resource to others wishing to build applications with Reticulum.
- Ease of use
The reference implementation of Reticulum is written in Python, to make it easy to use and understand. A programmer with only basic experience should be able to use Reticulum in their own applications.
- Low cost
It shall be as cheap as possible to deploy a communication system based on Reticulum. This should be achieved by using cheap off-the-shelf hardware that potential users might already own. The cost of setting up a functioning node should be less than $100 even if all parts needs to be purchased.
Introduction & Basic Functionality¶
Reticulum is a networking stack suited for high-latency, low-bandwidth links. Reticulum is at it’s core a message oriented system. It is suited for both local point-to-point or point-to-multipoint scenarios where alle nodes are within range of each other, as well as scenarios where packets need to be transported over multiple hops to reach the recipient.
Reticulum does away with the idea of addresses and ports known from IP, TCP and UDP. Instead Reticulum uses the singular concept of destinations. Any application using Reticulum as it’s networking stack will need to create one or more destinations to receive data, and know the destinations it needs to send data to.
All destinations in Reticulum are represented internally as 10 bytes, derived from truncating a full
SHA-256 hash of identifying characteristics of the destination. To users, the destination addresses
will be displayed as 10 bytes in hexadecimal representation, as in the following example: <80e29bf7cccaf31431b3>
.
By default Reticulum encrypts all data using public-key cryptography. Any message sent to a destination is encrypted with that destinations public key. Reticulum can also set up an encrypted channel to a destination with Perfect Forward Secrecy and Initiator Anonymity using a elliptic curve cryptography and ephemeral keys derived from a Diffie Hellman exchange on Curve25519. In Reticulum terminology, this is called a Link.
Reticulum also offers symmetric key encryption for group-oriented communications, as well as unencrypted packets for broadcast purposes, or situations where you need the communication to be in plain text. The multi-hop transport, coordination, verification and reliability layers are fully autonomous and based on public key cryptography.
Reticulum can connect to a variety of interfaces such as radio modems, data radios and serial ports, and offers the possibility to easily tunnel Reticulum traffic over IP links such as the Internet or private IP networks.
Destinations¶
To receive and send data with the Reticulum stack, an application needs to create one or more destinations. Reticulum uses three different basic destination types, and one special:
- Single
The single destination type defines a public-key encrypted destination. Any data sent to this destination will be encrypted with the destination’s public key, and will only be readable by the creator of the destination.
- Group
The group destination type defines a symmetrically encrypted destination. Data sent to this destination will be encrypted with a symmetric key, and will be readable by anyone in possession of the key. The group destination can be used just as well by only two peers, as it can by many.
- Plain
A plain destination type is unencrypted, and suited for traffic that should be broadcast to a number of users, or should be readable by anyone. Traffic to a plain destination is not encrypted.
- Link
A link is a special destination type, that serves as an abstract channel to a single destination, directly connected or over multiple hops. The link also offers reliability and more efficient encryption, forward secrecy, initiator anonymity, and as such can be useful even when a node is directly reachable.
Destination Naming¶
Destinations are created and named in an easy to understand dotted notation of aspects, and represented on the network as a hash of this value. The hash is a SHA-256 truncated to 80 bits. The top level aspect should always be a unique identifier for the application using the destination. The next levels of aspects can be defined in any way by the creator of the application.
Aspects can be as long and as plentiful as required, and a resulting long destination name will not impact efficiency, as names are always represented as truncated SHA-256 hashes on the network.
As an example, a destination for a environmental monitoring application could be made up of the application name, a device type and measurement type, like this:
app name : environmentlogger
aspects : remotesensor, temperature
full name : environmentlogger.remotesensor.temperature
hash : fa7ddfab5213f916dea
For the single destination, Reticulum will automatically append the associated public key as a destination aspect before hashing. This is done to ensure only the correct destination is reached, since anyone can listen to any destination name. Appending the public key ensures that a given packet is only directed at the destination that holds the corresponding private key to decrypt the packet.
Take note! There is a very important concept to understand here:
Anyone can use the destination name
environmentlogger.remotesensor.temperature
Each destination that does so will still have a unique destination hash, and thus be uniquely addressable, because their public keys will differ.
In actual use of single destination naming, it is advisable not to use any uniquely identifying features in aspect naming. Aspect names should be general terms describing what kind of destination is represented. The uniquely identifying aspect is always acheived by the appending the public key, which expands the destination into a uniquely identifyable one.
Any destination on a Reticulum network can be addressed and reached simply by knowning its destination hash (and public key, but if the public key is not known, it can be requested from the network simply by knowing the destination hash). The use of app names and aspects makes it easy to structure Reticulum programs and makes it possible to filter what information and data your program receives.
To recap, the different destination types should be used in the following situations:
- Single
When private communication between two endpoints is needed. Supports multiple hops.
- Group
When private communication between two or more endpoints is needed. Supports multiple hops indirectly, but must first be established through a single destination.
- Plain
When plain-text communication is desirable, for example when broadcasting information.
To communicate with a single destination, you need to know it’s public key. Any method for obtaining the public key is valid, but Reticulum includes a simple mechanism for making other nodes aware of your destinations public key, called the announce. It is also possible to request an unknown public key from the network, as all participating nodes serve as a distributed ledger of public keys.
Note that public key information can be shared and verified in many other ways than using the built-in announce functionality, and that it is therefore not required to use the announce/request functionality to obtain public keys. It is by far the easiest though, and should definitely be used if there is not a good reason for doing it differently.
Public Key Announcements¶
An announce will send a special packet over any configured interfaces, containing all needed information about the destination hash and public key, and can also contain some additional, application specific data. The entire packet is signed by the sender to ensure authenticity. It is not required to use the announce functionality, but in many cases it will be the simplest way to share public keys on the network. As an example, an announce in a simple messenger application might contain the following information:
The announcers destination hash
The announcers public key
Application specific data, in this case the users nickname and availability status
A random blob, making each new announce unique
An Ed25519 signature of the above information, verifying authenticity
With this information, any Reticulum node that receives it will be able to reconstruct an outgoing destination to securely communicate with that destination. You might have noticed that there is one piece of information lacking to reconstruct full knowledge of the announced destination, and that is the aspect names of the destination. These are intentionally left out to save bandwidth, since they will be implicit in almost all cases. If a destination name is not entirely implicit, information can be included in the application specific data part that will allow the receiver to infer the naming.
It is important to note that announces will be forwarded throughout the network according to a certain pattern. This will be detailed in the section The Announce Mechanism in Detail.
Seeing how single destinations are always tied to a private/public key pair leads us to the next topic.
Identities¶
In Reticulum, an identity does not necessarily represent a personal identity, but is an abstraction that can represent any kind of verified entity. This could very well be a person, but it could also be the control interface of a machine, a program, robot, computer, sensor or something else entirely. In general, any kind of agent that can act, or be acted upon, or store or manipulate information, can be represented as an identity.
As we have seen, a single destination will always have an identity tied to it, but not plain or group destinations. Destinations and identities share a multilateral connection. You can create a destination, and if it is not connected to an identity upon creation, it will just create a new one to use automatically. This may be desirable in some situations, but often you will probably want to create the identity first, and then link it to created destinations.
Building upon the simple messenger example, we could use an identity to represent the user of the application. Destinations created will then be linked to this identity to allow communication to reach the user. In all cases it is of great importance to store the private keys associated with any Reticulum Identity securely and privately.
Getting Further¶
The above functions and principles form the core of Reticulum, and would suffice to create functional networked applications in local clusters, for example over radio links where all interested nodes can directly hear each other. But to be truly useful, we need a way to direct traffic over multiple hops in the network.
In the following sections, two concepts that allow this will be introduced, paths and links.
Reticulum Transport¶
The term routing has been purposefully avoided until now. The current methods of routing used in IP-based networks are fundamentally incompatible with the physical link types that Reticulum was designed to handle. These routing methodologies assume trust at the physical layer, and often needs a lot more bandwidth than Reticulum can assume is available.
Since Reticulum is designed to run over open radio spectrum, no such trust exists, and bandwidth is often very limited. Existing routing protocols like BGP or OSPF carry too much overhead to be practically useable over bandwidth-limited, high-latency links.
To overcome such challenges, Reticulum’s Transport system uses public-key cryptography to implement the concept of paths that allow discovery of how to get information to a certain destination. It is important to note that no single node in a Reticulum network knows the complete path to a destination. Every Transport node participating in a Reticulum network will only know what the most direct way to get a packet one hop closer to it’s destination is.
The Announce Mechanism in Detail¶
When an announce is transmitted by a node, it will be forwarded by any node receiving it, but according to some specific rules:
- If this exact announce has already been received before, ignore it.
- If not, record into a table which node the announce was received from, and how many times in total it has been retransmitted to get here.
- If the announce has been retransmitted m+1 times, it will not be forwarded. By default, m is set to 18.
- The announce will be assigned a delay d = ch seconds, where c is a decay constant, and h is the amount of times this packet has already been forwarded.
- The packet will be given a priority p = 1/d.
- If at least d seconds has passed since the announce was received, and no other packets with a priority higher than p are waiting in the queue (see Packet Prioritisation), and the channel is not utilized by other traffic, the announce will be forwarded.
- If no other nodes are heard retransmitting the announce with a greater hop count than when it left this node, transmitting it will be retried r times. By default, r is set to 1. Retries follow same rules as above, with the exception that it must wait for at least d = ch+1 + t + rand(0, rw) seconds. This amount of time is equal to the amount of time it would take the next node to retransmit the packet, plus a random window. By default, t is set to 10 seconds, and the random window rw is set to 10 seconds.
- If a newer announce from the same destination arrives, while an identical one is already in the queue, the newest announce is discarded. If the newest announce contains different application specific data, it will replace the old announce, but will use d and p of the old announce.
Once an announce has reached a node in the network, any other node in direct contact with that node will be able to reach the destination the announce originated from, simply by sending a packet addressed to that destination. Any node with knowledge of the announce will be able to direct the packet towards the destination by looking up the next node with the shortest amount of hops to the destination.
According to these rules and default constants, an announce will propagate throughout the network in a predictable way. In an example network utilising the default constants, and with an average link distance of Lavg = 15 kilometers, an announce will be able to propagate outwards to a radius of 180 kilometers in 34 minutes, and a maximum announce radius of 270 kilometers in approximately 3 days.
Reaching the Destination¶
In networks with changing topology and trustless connectivity, nodes need a way to establish verified connectivity with each other. Since the network is assumed to be trustless, Reticulum must provide a way to guarantee that the peer you are communicating with is actually who you expect. Reticulum offers two ways to do this.
For exchanges of small amounts of information, Reticulum offers the Packet API, which works exactly like you would expect - on a per packet level. The following process is employed when sending a packet:
- A packet is always created with an associated destination and some payload data. When the packet is sent to a single destination type, Reticulum will automatically create an ephemeral encryption key, perform an ECDH key exchange with the destinations public key, and encrypt the information.
- It is important to note that this key exchange does not require any network traffic. The sender already knows the public key of the destination from an earlier received announce, and can thus perform the ECDH key exchange locally, before sending the packet.
- The public part of the newly generated ephemeral key-pair is included with the encrypted token, and sent along with the encrypted payload data in the packet.
- When the destination receives the packet, it can itself perform an ECDH key exchange and decrypt the packet.
- A new ephemeral key is used for every packet sent in this way, and forward secrecy is guaranteed on a per packet level.
- Once the packet has been received and decrypted by the addressed destination, that destination can opt to prove its receipt of the packet. It does this by calculating the SHA-256 hash of the received packet, and signing this hash with it’s Ed25519 signing key. Transport nodes in the network can then direct this proof back to the packets origin, where the signature can be verified against the destinations known public signing key.
- In case the packet is addressed to a group destination type, the packet will be encrypted with the pre-shared AES-128 key associated with the destination. In case the packet is addressed to a plain destination type, the payload data will not be encrypted. Neither of these two destination types offer forward secrecy. In general, it is recommended to always use the single destination type, unless it is strictly necessary to use one of the others.
For exchanges of larger amounts of data, or when longer sessions of bidirectional communication is desired, Reticulum offers the Link API. To establish a link, the following process is employed:
- First, the node that wishes to establish a link will send out a special packet, that traverses the network and locates the desired destination. Along the way, the nodes that forward the packet will take note of this link request.
- Second, if the destination accepts the link request , it will send back a packet that proves the authenticity of it’s identity (and the receipt of the link request) to the initiating node. All nodes that initially forwarded the packet will also be able to verify this proof, and thus accept the validity of the link throughout the network.
- When the validity of the link has been accepted by forwarding nodes, these nodes will remember the link , and it can subsequently be used by referring to a hash representing it.
- As a part of the link request , a Diffie-Hellman key exchange takes place, that sets up an efficiently encrypted tunnel between the two nodes, using elliptic curve cryptography. As such, this mode of communication is preferred, even for situations when nodes can directly communicate, when the amount of data to be exchanged numbers in the tens of packets.
- When a link has been set up, it automatically provides message receipt functionality, through the same proof mechanism discussed before, so the sending node can obtain verified confirmation that the information reached the intended recipient.
In a moment, we will discuss the details of how this methodology is implemented, but let’s first recap what purposes this methodology serves. We first ensure that the node answering our request is actually the one we want to communicate with, and not a malicious actor pretending to be so. At the same time we establish an efficient encrypted channel. The setup of this is relatively cheap in terms of bandwidth, so it can be used just for a short exchange, and then recreated as needed, which will also rotate encryption keys. The link can also be kept alive for longer periods of time, if this is more suitable to the application. The procedure also inserts the link id , a hash calculated from the link request packet, into the memory of forwarding nodes, which means that the communicating nodes can thereafter reach each other simply by referring to this link id.
The combined bandwidth cost of setting up a link is 3 packets totalling 240 bytes (more info in the Binary Packet Format section). The amount of bandwidth used on keeping a link open is practically negligible, at 0.62 bits per second. Even on a slow 1200 bits per second packet radio channel, 100 concurrent links will still leave 95% channel capacity for actual data.
Link Establishment in Detail¶
After exploring the basics of the announce mechanism, finding a path through the network, and an overview of the link establishment procedure, this section will go into greater detail about the Reticulum link establishment process.
The link in Reticulum terminology should not be viewed as a direct node-to-node link on the physical layer, but as an abstract channel, that can be open for any amount of time, and can span an arbitrary number of hops, where information will be exchanged between two nodes.
- When a node in the network wants to establish verified connectivity with another node, it will randomly generate a new X25519 private/public key pair. It then creates a link request packet, and broadcast it.It should be noted that the X25519 public/private keypair mentioned above is two separate keypairs: An encryption key pair, used for derivation of a shared symmetric key, and a signing key pair, used for signing and verifying messages on the link. They are sent together over the wire, and can be considered as single public key for simplicity in this explanation.
- The link request is addressed to the destination hash of the desired destination, and contains the following data: The newly generated X25519 public key LKi.
- The broadcasted packet will be directed through the network according to the rules laid out previously.
- Any node that forwards the link request will store a link id in it’s link table , along with the amount of hops the packet had taken when received. The link id is a hash of the entire link request packet. If the link request packet is not proven by the addressed destination within some set amount of time, the entry will be dropped from the link table again.
- When the destination receives the link request packet, it will decide whether to accept the request. If it is accepted, the destination will also generate a new X25519 private/public key pair, and perform a Diffie Hellman Key Exchange, deriving a new symmetric key that will be used to encrypt the channel, once it has been established.
- A link proof packet is now constructed and transmitted over the network. This packet is addressed to the link id of the link. It contains the following data: The newly generated X25519 public key LKr and an Ed25519 signature of the link id and LKr made by the signing key of the addressed destination.
- By verifying this link proof packet, all nodes that originally transported the link request packet to the destination from the originator can now verify that the intended destination received the request and accepted it, and that the path they chose for forwarding the request was valid. In sucessfully carrying out this verification, the transporting nodes marks the link as active. An abstract bi-directional communication channel has now been established along a path in the network.
- When the source receives the proof , it will know unequivocally that a verified path has been established to the destination. It can now also use the X25519 public key contained in the link proof to perform it’s own Diffie Hellman Key Exchange and derive the symmetric key that is used to encrypt the channel. Information can now be exchanged reliably and securely.
It’s important to note that this methodology ensures that the source of the request does not need to reveal any identifying information about itself. The link initiator remains completely anonymous.
When using links, Reticulum will automatically verify all data sent over the link, and can also automate retransmissions if Resources are used.
Resources¶
For exchanging small amounts of data over a Reticulum network, the Packet interface is sufficient, but for exchanging data that would require many packets, an efficient way to coordinate the transfer is needed.
This is the purpose of the Reticulum Resource. A Resource can automatically handle the reliable transfer of an arbitrary amount of data over an established Link. Resources can auto-compress data, will handle breaking the data into individual packets, sequencing the transfer and reassembling the data on the other end.
Resources are programmatically very simple to use, and only requires a few lines of codes to reliably transfer any amount of data. They can be used to transfer data stored in memory, or stream data directly from files.
Reference System Setup¶
This section will detail the recommended Reference System Setup for Reticulum. It is important to note that Reticulum is designed to be usable over more or less any medium that allows you to send and receive data in a digital form, and satisfies some very low minimum requirements. The communication channel must support at least half-duplex operation, and provide an average throughput of around 1000 bits per second, and supports a physical layer MTU of 500 bytes. The Reticulum software should be able to run on more or less any hardware that can provide a Python 3.x runtime environment.
That being said, the reference setup has been outlined to provide a common platform for anyone who wants to help in the development of Reticulum, and for everyone who wants to know a recommended setup to get started. A reference system consists of three parts:
- A channel access device
Or CAD , in short, provides access to the physical medium whereupon the communication takes place, for example a radio with an integrated modem. A setup with a separate modem connected to a radio would also be termed a “channel access device”.
- A host device
Some sort of computing device that can run the necessary software, communicates with the channel access device, and provides user interaction.
- A software stack
The software implementing the Reticulum protocol and applications using it.
The reference setup can be considered a relatively stable platform to develop on, and also to start building networks on. While details of the implementation might change at the current stage of development, it is the goal to maintain hardware compatibility for as long as entirely possible, and the current reference setup has been determined to provide a functional platform for many years into the future. The current Reference System Setup is as follows:
- Channel Access Device
A data radio consisting of a LoRa radio module, and a microcontroller with open source firmware, that can connect to host devices via USB. It operates in either the 430, 868 or 900 MHz frequency bands. More details can be found on the RNode Page.
- Host device
Any computer device running Linux and Python. A Raspberry Pi with a Debian based OS is recommended.
- Software stack
The current Reference Implementation Release of Reticulum, running on a Debian based operating system.
It is very important to note, that the reference channel access device does not use the LoRaWAN standard, but uses a custom MAC layer on top of the plain LoRa modulation! As such, you will need a plain LoRa radio module connected to an MCU with the correct firmware. Full details on how to get or make such a device is available on the RNode Page.
With the current reference setup, it should be possible to get on a Reticulum network for around 100$ even if you have none of the hardware already, and need to purchase everything.
Protocol Specifics¶
This chapter will detail protocol specific information that is essential to the implementation of Reticulum, but non critical in understanding how the protocol works on a general level. It should be treated more as a reference than as essential reading.
Node Types¶
Currently Reticulum defines two node types, the Station and the Peer. A node is a station if it fixed in one place, and if it is intended to be kept online most of the time. Otherwise the node is a peer. This distinction is made by the user configuring the node, and is used to determine what nodes on the network will help forward traffic, and what nodes rely on other nodes for connectivity.
If a node is a Peer it should be given the configuration directive enable_transport = No
.
If it is a Station, it should be given the configuration directive enable_transport = Yes
.
Packet Prioritisation¶
Currently, Reticulum is completely priority-agnostic regarding general traffic. All traffic is handled on a first-come, first-serve basis. Announce re-transmission are handled according to the re-transmission times and priorities described earlier in this chapter.
It is possible that a prioritisation engine could be added to Reticulum in the future, but in the light of Reticulums goal of equal access, doing so would need to be the subject of careful investigation of the consequences first.
Binary Packet Format¶
== Reticulum Wire Format ======
A Reticulum packet is composed of the following fields:
[HEADER 2 bytes] [ADDRESSES 10/20 bytes] [CONTEXT 1 byte] [DATA 0-477 bytes]
* The HEADER field is 2 bytes long.
* Byte 1: [Header Type], [Propagation Type], [Destination Type] and [Packet Type]
* Byte 2: Number of hops
* The ADDRESSES field contains either 1 or 2 addresses.
* Each address is 10 bytes long.
* The Header Type flag in the HEADER field determines
whether the ADDRESSES field contains 1 or 2 addresses.
* Addresses are Reticulum hashes truncated to 10 bytes.
* The CONTEXT field is 1 byte.
* It is used by Reticulum to determine packet context.
* The DATA field is between 0 and 477 bytes.
* It contains the packets data payload.
Header Types
-----------------
type 1 00 Two byte header, one 10 byte address field
type 2 01 Two byte header, two 10 byte address fields
type 3 10 Reserved
type 4 11 Reserved
Propagation Types
-----------------
broadcast 00
transport 01
reserved 10
reserved 11
Destination Types
-----------------
single 00
group 01
plain 10
link 11
Packet Types
-----------------
data 00
announce 01
link request 10
proof 11
+- Packet Example -+
HEADER FIELD ADDRESSES FIELD CONTEXT FIELD DATA FIELD
_______|_______ ________________|________________ ________|______ __|_
| | | | | | | |
01010000 00000100 [ADDR1, 10 bytes] [ADDR2, 10 bytes] [CONTEXT, 1 byte] [DATA]
| | | | |
| | | | +-- Hops = 4
| | | +------- Packet Type = DATA
| | +--------- Destination Type = SINGLE
| +----------- Propagation Type = TRANSPORT
+------------- Header Type = HEADER_2 (two byte header, two address fields)
+- Packet Example -+
HEADER FIELD ADDRESSES FIELD CONTEXT FIELD DATA FIELD
_______|_______ _______|_______ ________|______ __|_
| | | | | | | |
00000000 00000111 [ADDR1, 10 bytes] [CONTEXT, 1 byte] [DATA]
| | | | |
| | | | +-- Hops = 7
| | | +------- Packet Type = DATA
| | +--------- Destination Type = SINGLE
| +----------- Propagation Type = BROADCAST
+------------- Header Type = HEADER_1 (two byte header, one address field)
Size examples of different packet types
---------------------------------------
The following table lists example sizes of various
packet types. The size listed are the complete on-
wire size including all fields.
- Path Request : 33 bytes
- Announce : 151 bytes
- Link Request : 77 bytes
- Link Proof : 77 bytes
- Link RTT packet : 86 bytes
- Link keepalive : 14 bytes


Lack of Consistency at Clinics
Description: Participants commented on the lack of consistency between and within clinics. Participants viewed quality based on the location or on the doctor.
Comments: - 'His evaluation of the experience varies depending on where he received the treatment.'
- 'Experience and evaluation of health care delivery locations vary depending on the location.'
- 'She summed it up by saying that the service depends on the doctor.'
Full Data link


\(Logic\longleftrightarrow Learner\)
Grammar:
Propositional
Boolean Algebra
Disjunctive Normal Form
Input method:
Blocks
Text
Add Question
Submit
Prompt
Grammar
Input
Delete