Crux Pluto Assignment: put transactions

Crux Pluto Assignment: put transactions

July 22, 2019
Johanna Antonelli

earth pluto mercury neptune saturn jupiter comet planet a


This is the second part of the Crux tutorial. The Earth installment looked at setting up a simple Crux standalone node and a very simple put transaction.

We shall assume you have a Crux standalone node. If not, you can find all you need to know on Earth. Click on a destination above to take you there.

If you are following on your own machine, it is best you follow along in sequence as this tutorial depends on the Earth installment.

To go to different destination, click the location above.

Arrival on Pluto

As you enter the Plutonian atmosphere, a message pops up on your communication panel:

Welcome to the dwarf planet Pluto. You are entering privately governed space. If you do not have the correct papers, entry will be denied. We hope you enjoy your stay.

Have a nice day.

— Anarchic Directorate of Pluto

The government of Pluto is asking to see your flight manifest.

Choose your path:

You have your manifest You do not have your manifest

You have permission to land

You do not have permission to land. You must return to Earth and fill in your manifest.



Pluto Space Port

As you circle the dwarf planet to land, you have a quick read of your Crux manual. You know you will be using the put operation a lot for this assignment and although you used the operation to add your manifest before you left, you think it is a good idea to brush up on your knowledge.

Currently there are only four transaction operations in Crux: put, delete, match and evict.

Transaction Description


Writes a version of a document


Deletes a version of a document


Stops a transaction if the precondition is not met.


Removes a document entirely


The put operation is used to write versions of a document (doc).

Each document must be in Extensible Data Notation (edn) and must contain a unique :crux.db/id value. However, beyond those two requirements you have the flexibility to add whatever you like to your documents because Crux is schemaless.

Along with the document (doc), put has two optional additional arguments:

start valid-time

The time at which the entry will be valid from.

end valid-time

The time at which the entry will be valid until.

This means that you can query back through Crux, you can use valid-time arguments to see the state of Crux at a different time.

If no valid-time is provided, start valid-time defaults to the transaction time and the document is valid either eternally or until the document is updated by a future transaction with the same eid.

Time in Crux is denoted #inst "yyyy-MM-ddThh:mm:ss". For example, 9:30 pm on January 2nd 1999 would be written:

#inst "1999-01-02T21:30:00".

A complete put transaction has the form:

[:crux.tx/put doc valid-time-start valid-time-end]

— Crux manual
Read More


You land on the surface of the dwarf planet. As you do, the job ticket for this assignment is unlocked.


Commodity Logging


Tombaugh Resources Ltd.


R. Glogofloon



Additional information

We need help setting up a new recording system for our mine. I have enclosed a list of the commodities we deal with. Please send someone soon because we already have a week’s worth of unrecorded stocktakes.



You make your way over to the mines on the next shuttle. On your way you decide to get a head start and put the commodities into Crux.

(crux/submit-tx node
                  {:crux.db/id :commodity/Pu
                   :common-name "Plutonium"
                   :type :element/metal
                   :density 19.816
                   :radioactive true}]

                  {:crux.db/id :commodity/N
                   :common-name "Nitrogen"
                   :type :element/gas
                   :density 1.2506
                   :radioactive false}]

                  {:crux.db/id :commodity/CH4
                   :common-name "Methane"
                   :type :molecule/gas
                   :density 0.717
                   :radioactive false}]])
;;=> #:crux.tx{:tx-id 0, :tx-time #inst "2020-06-18T14:11:51.087-00:00"}

Since it takes six hours for each transaction to reach your Crux node on Earth from here, it is a good idea to batch up all the commodities in a single transaction.

Stock take

You arrive at the mine and are met by the CEO, Reginald Glogofloon, a 150 year old Plutonian.

Hello, I’m glad you’re here.

I would like you to fill in our last week’s worth of data on our commodities. We need to be able to look back at a given day and see what our stocks were for auditing purposes.

The stock for each day must be submitted at 6pm Earth time (UTC) for your banks records.

Are you able to do that for me?

— R. Glogofloon

Choose your path

"Yes I’ll give it a go." "I’m not sure how to even begin."
pluto surface

You remember that with Crux you have the option of adding a valid-time. This comes in useful now as you enter the weeks worth of stock takes for Plutonium.

(crux/submit-tx node
                  {:crux.db/id :stock/Pu
                   :commod :commodity/Pu
                   :weight-ton 21 }
                  #inst "2115-02-13T18"] ;; valid-time

                  {:crux.db/id :stock/Pu
                   :commod :commodity/Pu
                   :weight-ton 23 }
                  #inst "2115-02-14T18"]

                  {:crux.db/id :stock/Pu
                   :commod :commodity/Pu
                   :weight-ton 22.2 }
                  #inst "2115-02-15T18"]

                  {:crux.db/id :stock/Pu
                   :commod :commodity/Pu
                   :weight-ton 24 }
                  #inst "2115-02-18T18"]

                  {:crux.db/id :stock/Pu
                   :commod :commodity/Pu
                   :weight-ton 24.9 }
                  #inst "2115-02-19T18"]])
;;=> #:crux.tx{:tx-id 1, :tx-time #inst "2020-06-18T14:14:08.347-00:00"}

You notice that the amount of Nitrogen and Methane has not changed in the last week which saves you some time:

(crux/submit-tx node
                  {:crux.db/id :stock/N
                   :commod :commodity/N
                   :weight-ton 3 }
                  #inst "2115-02-13T18"  ;; start valid-time
                  #inst "2115-02-19T18"] ;; end valid-time

                  {:crux.db/id :stock/CH4
                   :commod :commodity/CH4
                   :weight-ton 92 }
                  #inst "2115-02-15T18"
                  #inst "2115-02-19T18"]])
;;=> #:crux.tx{:tx-id 2, :tx-time #inst "2020-06-18T14:15:19.716-00:00"}

The CEO is impressed with your speed, but a little skeptical that you have done it properly.

You gain their confidence by showing them the entries for Plutonium on two different days:

(crux/entity (crux/db node #inst "2115-02-14") :stock/Pu)
;;=> {:crux.db/id :stock/Pu, :commod :commodity/Pu, :weight-ton 21}

(crux/entity (crux/db node #inst "2115-02-18") :stock/Pu)
;;=> {:crux.db/id :stock/Pu, :commod :commodity/Pu, :weight-ton 22.2}

Easy ingest

As a parting gift to them you create an easy ingest function so that if they needed to add more commodities to their stock list they could do it fast.

(defn easy-ingest
  "Uses Crux put transaction to add a vector of documents to a specified
  [node docs]
  (crux/submit-tx node (mapv (fn [doc] [:crux.tx/put doc]) docs)))

Tombaugh Resources Ltd. are happy that this will be simple enough to use. They thank you for the extra help and you head back to your ship.

Space Port

You are back at your ship and check your communications panel. There is a new assignment waiting for you:

Congratulations on completing your first assignment.

We would like you to go to Mercury, the hub of the trade world. Their main trade center has a new IT department and want you to show them how to query Crux.

— Helios Banking Inc.

It’s a long flight so you refuel, and update your manifest. You have been awarded a new badge. Since this is the only thing to update in your manifest, you use the Clojure function assoc to save time.

   (assoc manifest :badges ["SETUP" "PUT"])]])
;;=> #:crux.tx{:tx-id 3, :tx-time #inst "2020-06-18T14:20:31.602-00:00"}

You check this has worked because it’s your first time doing it this way.

(crux/entity (crux/db node) :manifest)
;;=> {:crux.db/id :manifest,
;;    :pilot-name "Johanna",
;;    :id/rocket "SB002-sol",
;;    :id/employee "22910x2",
;;    :badges ["SETUP" "PUT"],
;;    :cargo ["stereo" "gold fish" "slippers" "secret note"]}

You enter countdown for lift off to Mercury. See you soon.

Click on Mercury to take you to your next assignment.