Friday, November 29, 2013

|coins|

I loosely followed how bitcoin exchange rates skyrocketed during last week and a half. Which means in the evening I usually uttered "Wow, bitcoins are up $100 again! And on 2nd November one BTC was just $200! This is insane!" when reading news. Today, it seems BTC/USD rate gained about $40-$60, daily change being "only" 3.5%-5.5%. According to bitcoincharts, BTC/USD trading volume at Mt.Gox bitcoin exchange has been very respectable 1.11 million BTC & 613 million USD in last 30 days. Mt.Gox will not take trade fees during four days, celebrating "Black Friday through Cyber Monday" and attempting to keep the cryptocurrency party going. Also, they launched bitcoins.com to promote bitcoins and their advantages.

During quiet moments, it is nice to ponder whether mathematically limited virtual bitcoins have more real value than the US paper dollars created at Federal Reserve from 1 part of linen and 3 parts of cotton (mixed with thin air). Currently not, as speculation is the driving force behind the exchange rate, not real services offered for bitcoins. But services extend and even infamous Silk Road, lead by "new" Dread Pirate Roberts, is back online1. Speculation can create either "real" value or bubble, it just needs to go on long enough.

I never mined or bought bitcoins. I have little understanding about how they work and the reason that I did not even experiment with them was that using conceptually truly secure local wallets seemed overkill, with e.g. Bitcoin Armory reportedly requiring 4 GB of memory to run. I imagine that is mostly because of the trust issue that rises in bitcoin peer-to-peer transactions, one cannot know whether offered bitcoin is a fake that has been already "spent", unless one keeps the record of all transactions in the currency system2. Due to constrained computing resources, it is not currently feasible for every node in the system to be an equal party who knows about all the historical transactions. "Überpeers" offering their services to resource-bound network are needed, will thus arise and must be trusted somewhat (at least until everyone has device as powerful as rack of servers at their personal disposal).

Fact that I did not have single µBTC stashed (or even a place to stash them) became dreadfully annoying during the BTC craze, so to begin with, I decided to play around with wallets. Nice to have wallet ready in an off-chance that someone actually offers to transfer me bitcoins.

Expecting installation and usage to be simpler on my Android smartphone than on my current Linux distro, I went to search for bitcoin wallet applications at Play Store. There were several and all were free to install:

  • Bitcoin Wallet by Andreas Schildbach
    • Open-source (GPL), code at GitHub
    • Decentralized, except some BTC market price average fetches.
    • I disregarded this (v 3.27), because it required too many permissions for my taste3. Also, first comment about it mentioned unexpected program launches and background service that could not be killed.
  • Blockchain Wallet by Qkos Services Ltd
    • Open-Source (GPL) fork is available at GitHub
    • I disregarded it because it asked for "discover known accounts" permission and had coin storage on central server (You to retain full control of your bitcoins while at the same time able to access them on any device.)
  • Coinbase - Bitcoin Wallet by Coinbase, Inc
    • Open-Source (APL 2.0), code available at GitHub
    • I disregarded it because of coin storage on central server (Funds are stored securely online in case you lose your phone.)
  • Mycelium Bitcoin Wallet by Mycelium Developers
    • Source code available at GitHub, but licensing is view only (MS-RSL).
    • Promises 100% control over your private keys, they never leave your device unless you export them and did not require many permissions.

The least I wanted was predictable application behaviour with private keys remaining in my own hardware, so I chose to install mysteriously named Mycelium wallet. It started without problems, generating wallet identifier on first start and showing impressive zero balance. Perfect. Time to sleep.


1Just a month after shutdown, Silk Road 2.0 emerges (Nov 2013, Ars Technica)

2Victor Grishchenko's notes on Bitcoin (May 2011, Delft University of Technology, Netherlands)

3modify/delete USB storage contents, prevent phone from sleeping, take pictures and videos, control near-field-communications, create Bluetooth connections, full Internet access, start automatically at boot, send sticky broadcast, control vibrator

Wednesday, August 7, 2013

Conversion

ImageMagick

#!/bin/sh
for f in *.png ; do 
  convert $f $f.tga && cjpeg -grayscale -dct float -optimize -targa -scale 1/2 -outfile $f.jpg $f.tga && rm $f.tga ;
done
convert *.jpg jpg-out.pdf

Saturday, July 25, 2009

No RTFMing The Obvious

After installing PostgreSQL with Kubuntu package manager, hope was that knowing the name of the database client program, the journey could start. But:
taimo@deficiency:~$ psql
psql: FATAL: Ident authentication failed for user "taimo"

taimo@deficiency:~$ psql --help
This is psql 8.3.7, the PostgreSQL interactive terminal.

Usage:
psql [OPTIONS]... [DBNAME [USERNAME]]

General options:
-d DBNAME specify database name to connect to (default: "taimo")
-c COMMAND run only single command (SQL or internal) and exit
-f FILENAME execute commands from file, then exit
-1 ("one") execute command file as a single transaction
-l list available databases, then exit
Heh. Database might just not exist. Will see.
taimo@deficiency:~$ psql  -l
psql: FATAL: Ident authentication failed for user "taimo"
Hmm. Maybe this ident authentication thingy is all wrong?
taimo@deficiency:~$ ls /etc/postgresql/8.3/main/
environment pg_hba.conf pg_ident.conf postgresql.conf start.conf
That pg_ident.conf looked suspicious, but turned out to be empty, only noting that if ident user names coincide with PostgreSQL user names, this file is not needed. Instead special mapping 'sameuser' should be used in pg_hba.conf. And that file indeed seems to have the mapping. So what is wrong?
taimo@deficiency:~$ ls /usr/share/doc/postgresql-8.3/
changelog.Debian.gz changelog.gz copyright README README.Debian.gz
Ah. The Debian README has instructions for actually creating the database with createdb command. So the database is not even there yet!
taimo@deficiency:~$ man createdb
Normally, the database user who executes this command becomes the owner of the new database.
taimo@deficiency:~$ createdb
createdb: could not connect to database postgres: FATAL: Ident authentication failed for user "taimo"
Ah. Misread the instructions. First switch to postgres had to be done, then the PostgreSQL user with desired name and rights created, including database creation rights.
taimo@deficiency:~$ sudo -u postgres sh
[sudo] password for taimo:
$ createuser -drS taimo
$ exit
taimo@deficiency:~$ createdb

taimo@deficiency:~$ psql
Welcome to psql 8.3.7, the PostgreSQL interactive terminal.

Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit
Yay! Seamless ident auth after creating the db user.

Wednesday, July 15, 2009

Coincidental Eagerness

I had web application crashing on me with org.hibernate.LazyInitializationException on certain web application page.

org.hibernate.LazyInitializationException: could not initialize proxy - no Session

Everyone who has ever used Hibernate instantly recognizes the problem. Smart proxy that Hibernate uses to load child entities of an entity on-demand could not perform its duty as the entity instance had already escaped the data layer and session had been closed. Child objects could be loaded eagerly in the data layer to make problem go away.

I examined the code and clearly child objects whose attempted retrieval resulted in the exception were never loaded. Weirdly, no-one else received exception on that page. The web layer code where exception occurred was roughly as this:
// Q, QLabel & Language are Hibernate entities
private String getQTitleInLang(Q q, String langCode) {
for (QLabel ql: q.getLabels()) {
// QLabel's Language is uninitialized, getCode() fails
if(langCode != null && ql.getLanguage().getCode().equals(langCode)){
return ql.getDescription();
}
}
return null;
}
The data layer code that loaded the main entity was bad Hibernate usage, manually forcing the n+1 selects. Actually it was worse. It had 2 nested for loops, each calling Hibernate.initialize() on many child entities. But that is besides the point, I cleaned it up a bit for the sake of example.
private void initQ(Set<q> qs) throws HibernateException {
for (Q q: qs) {
Hibernate.initialize(q.getLanguages());
Hibernate.initialize(q.getLabels());
}
}
Correct but bad fix is to add the nasty loop that initializes QLabels:
private void initQ(Set<q> qs) throws HibernateException {
for (Q q: qs) {
Hibernate.initialize(q.getLanguages());
Hibernate.initialize(q.getLabels());
// The ugly fix. In real code that brings 3rd nested for loop.
for (QLabel ql: q.getLabels()) {
Hibernate.initialize(ql.getLanguage());
}
}
}
So why did the code work for everyone else? It was just that they happened to work with different database. In their databases all the Language entities that QLabels' owned coincided with those that Q itself had as its child Languages.

As Hibernate Session holds a mandatory first-level cache of persistent objects that are used when navigating the object graph or looking up objects by identifier, that made the "unloaded" entities accessible under certain conditions.

Session-level caching just happens to work so well that code coincidentally works sometimes :)