diff --git a/go.mod b/go.mod
index ac900fc8dcdc0bfdaae33acf7e26636d169ad672..78c48e9fa97fb0e6d79f206d95d1b04140426cd0 100644
--- a/go.mod
+++ b/go.mod
@@ -4,6 +4,7 @@ go 1.13
 
 require (
 	github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect
+	github.com/apsdehal/go-logger v0.0.0-20190506062552-f85330a4b532 // indirect
 	github.com/dgraph-io/badger v1.6.0
 	github.com/dgrijalva/jwt-go v3.2.0+incompatible
 	github.com/emicklei/dot v0.10.1
@@ -11,22 +12,24 @@ require (
 	github.com/gdamore/tcell v1.2.0
 	github.com/go-zeromq/zmq4 v0.5.0
 	github.com/golang/protobuf v1.3.2 // indirect
-	github.com/google/open-location-code/go v0.0.0-20190723034300-2c7115db77a3
+	github.com/google/open-location-code/go v0.0.0-20190903173953-119bc96a3a51
 	github.com/gorilla/websocket v1.4.1
-	github.com/iotaledger/hive.go v0.0.0-20191112142249-92832505dd6d
-	github.com/iotaledger/iota.go v1.0.0-beta.7
-	github.com/kr/pretty v0.1.0 // indirect
+	github.com/iotaledger/hive.go v0.0.0-20191125112048-8b1784dd1bce
+	github.com/iotaledger/iota.go v1.0.0-beta.9
 	github.com/kr/text v0.1.0
 	github.com/labstack/echo v3.3.10+incompatible
 	github.com/labstack/gommon v0.3.0 // indirect
 	github.com/magiconair/properties v1.8.1
+	github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
 	github.com/pkg/errors v0.8.1
 	github.com/rivo/tview v0.0.0-20190829161255-f8bc69b90341
 	github.com/rivo/uniseg v0.1.0 // indirect
+	github.com/sasha-s/go-deadlock v0.2.0 // indirect
+	github.com/spf13/pflag v1.0.5
 	github.com/stretchr/objx v0.2.0 // indirect
 	golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf
 	golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297
 	golang.org/x/sys v0.0.0-20190904154756-749cb33beabd // indirect
 	golang.org/x/text v0.3.2 // indirect
-	gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
+	gopkg.in/zeromq/goczmq.v4 v4.1.0 // indirect
 )
diff --git a/go.sum b/go.sum
index cb9678226d7197e486795d18450879765a8976dc..d5e8a2f9be775a982ae90f8211b5b1f26792addc 100644
--- a/go.sum
+++ b/go.sum
@@ -1,17 +1,27 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
 github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M=
 github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
+github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=
 github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/apsdehal/go-logger v0.0.0-20190506062552-f85330a4b532/go.mod h1:U3/8D6R9+bVpX0ORZjV+3mU9pQ86m7h1lESgJbXNvXA=
 github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
 github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
 github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
 github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
 github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
 github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -24,6 +34,7 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
 github.com/dgryski/go-farm v0.0.0-20190323231341-8198c7b169ec/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
 github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=
 github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
+github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
 github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
 github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
 github.com/emicklei/dot v0.10.1 h1:bkzvwgIhhw/cuxxnJy5/5+ZL3GnhFxFfv0eolHtWE2w=
@@ -38,28 +49,57 @@ github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo
 github.com/gdamore/tcell v1.1.2/go.mod h1:h3kq4HO9l2On+V9ed8w8ewqQEmGCSSHOgQ+2h8uzurE=
 github.com/gdamore/tcell v1.2.0 h1:ikixzsxc8K8o3V2/CEmyoEW8mJZaNYQQ3NP3VIQdUe4=
 github.com/gdamore/tcell v1.2.0/go.mod h1:Hjvr+Ofd+gLglo7RYKxxnzCBmev3BzsS67MebKS4zMM=
+github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
+github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/go-zeromq/zmq4 v0.5.0 h1:DijriKlrr2b48mymvAsZApiPzrbxQodYKG1aDH1rz8c=
 github.com/go-zeromq/zmq4 v0.5.0/go.mod h1:6p7pjNlkfrQQVipmEuZDk7fakLZCqPPVK+Iq3jfbDg8=
+github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
 github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/open-location-code/go v0.0.0-20190723034300-2c7115db77a3 h1:qI8YeX4bVZ2HrE+kEOn12L2io7Tw/2IffULguAh3M4Q=
 github.com/google/open-location-code/go v0.0.0-20190723034300-2c7115db77a3/go.mod h1:eJfRN6aj+kR/rnua/rw9jAgYhqoMHldQkdTi+sePRKk=
+github.com/google/open-location-code/go v0.0.0-20190903173953-119bc96a3a51 h1:OdVal38kmXn0U3M3CYmPF4cpMLLvD4ioshwrooNfmxs=
+github.com/google/open-location-code/go v0.0.0-20190903173953-119bc96a3a51/go.mod h1:eJfRN6aj+kR/rnua/rw9jAgYhqoMHldQkdTi+sePRKk=
 github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
 github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
 github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
 github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
+github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
 github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 github.com/iotaledger/hive.go v0.0.0-20191112142249-92832505dd6d h1:6n1M4lkXVlclr1z3+Ee9iSjIdWz2L9Kx87WBurof/JU=
 github.com/iotaledger/hive.go v0.0.0-20191112142249-92832505dd6d/go.mod h1:3u9aMALGTDHvpdmpODAkl6HAJ3GmDTfKIJIVSboXKLg=
+github.com/iotaledger/hive.go v0.0.0-20191118130432-89eebe8fe8eb h1:nuS/LETRJ8obUyBIZeyxeei0ZPlyOMj8YPziOgSM4Og=
+github.com/iotaledger/hive.go v0.0.0-20191118130432-89eebe8fe8eb/go.mod h1:1Thhlil4lHzuy53EVvmEbEvWBFY0Tasp4kCBfxBCPIk=
+github.com/iotaledger/hive.go v0.0.0-20191125112048-8b1784dd1bce h1:QchbydsqgH7bXWXk8zLa1PvZ0fcWRddfIXCoXuWgzt4=
+github.com/iotaledger/hive.go v0.0.0-20191125112048-8b1784dd1bce/go.mod h1:1Thhlil4lHzuy53EVvmEbEvWBFY0Tasp4kCBfxBCPIk=
 github.com/iotaledger/iota.go v1.0.0-beta.7 h1:OaUNahPvOdQz2nKcgeAfcUdxlEDlEV3xwLIkwzZ1B/U=
 github.com/iotaledger/iota.go v1.0.0-beta.7/go.mod h1:dMps6iMVU1pf5NDYNKIw4tRsPeC8W3ZWjOvYHOO1PMg=
+github.com/iotaledger/iota.go v1.0.0-beta.9 h1:c654s9pkdhMBkABUvWg+6k91MEBbdtmZXP1xDfQpajg=
+github.com/iotaledger/iota.go v1.0.0-beta.9/go.mod h1:F6WBmYd98mVjAmmPVYhnxg8NNIWCjjH8VWT9qvv3Rc8=
+github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
 github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@@ -82,39 +122,75 @@ github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg
 github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
 github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
 github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
+github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
 github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
 github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
 github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
 github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ=
+github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
+github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
 github.com/rivo/tview v0.0.0-20190721135419-23dc8a0944e4/go.mod h1:+rKjP5+h9HMwWRpAfhIkkQ9KE3m3Nz5rwn7YtUpwgqk=
 github.com/rivo/tview v0.0.0-20190829161255-f8bc69b90341 h1:d2Z5U4d3fenPRFFweaMCogbXiRywM5kgYtu20/hol3M=
 github.com/rivo/tview v0.0.0-20190829161255-f8bc69b90341/go.mod h1:+rKjP5+h9HMwWRpAfhIkkQ9KE3m3Nz5rwn7YtUpwgqk=
 github.com/rivo/uniseg v0.0.0-20190513083848-b9f5b9457d44/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
 github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
 github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
 github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
+github.com/sasha-s/go-deadlock v0.2.0 h1:lMqc+fUb7RrFS3gQLtoQsJ7/6TV/pAIFvBsqX73DK8Y=
+github.com/sasha-s/go-deadlock v0.2.0/go.mod h1:StQn567HiB1fF2yJ44N9au7wOhrPS3iZqiDbRupzT10=
+github.com/simia-tech/env v0.1.0/go.mod h1:eVRQ7W5NXXHifpPAcTJ3r5EmoGgMn++dXfSVbZv3Opo=
+github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
 github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
+github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
 github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
+github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
 github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
+github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
 github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
 github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
+github.com/spf13/viper v1.5.0 h1:GpsTwfsQ27oS/Aha/6d1oD7tpKIqWnOA6tgOX9HHkt4=
+github.com/spf13/viper v1.5.0/go.mod h1:AkYRkVJF8TkSG/xet6PzXX+l39KhhXa2pdqVSxnTcn4=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
+github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
+github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
 github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
@@ -122,8 +198,14 @@ github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8W
 github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
 github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
 github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
+github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
 github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
+go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
 go.mongodb.org/mongo-driver v1.0.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
+go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
@@ -132,17 +214,31 @@ golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 h1:Gv7RPwsi3eZ2Fgewe3CBsu
 golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf h1:fnPsqIDRbCSgumaMCRpoIoF2s4qxv0xSSS0BVZUE/ss=
 golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
 golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -158,17 +254,31 @@ golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
 gopkg.in/h2non/gock.v1 v1.0.14/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE=
+gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/zeromq/goczmq.v4 v4.1.0 h1:CE+FE81mGVs2aSlnbfLuS1oAwdcVywyMM2AC1g33imI=
 gopkg.in/zeromq/goczmq.v4 v4.1.0/go.mod h1:h4IlfePEYMpFdywGr5gAwKhBBj+hiBl/nF4VoSE4k+0=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/packages/graphviz/render_png.go b/packages/graphviz/render_png.go
new file mode 100644
index 0000000000000000000000000000000000000000..ae1c1bc344edc1ed34f7217050293a40e344f6cb
--- /dev/null
+++ b/packages/graphviz/render_png.go
@@ -0,0 +1,25 @@
+package graphviz
+
+import (
+	"io/ioutil"
+	"os"
+	"os/exec"
+
+	"github.com/emicklei/dot"
+)
+
+func RenderPNG(graph *dot.Graph, fileName string) (err error) {
+	if err = ioutil.WriteFile("_tmp.dot", []byte(graph.String()), os.ModePerm); err != nil {
+		return
+	}
+
+	if _, err = exec.Command("dot", "-Tpng", "_tmp.dot", "-o", fileName).Output(); err != nil {
+		return
+	}
+
+	if err = os.Remove("_tmp.dot"); err != nil {
+		return
+	}
+
+	return
+}
diff --git a/packages/ledgerstate/_tmp.dot b/packages/ledgerstate/_tmp.dot
deleted file mode 100644
index 9868bd436ed622835c5f1d32e5508555a3f77920..0000000000000000000000000000000000000000
--- a/packages/ledgerstate/_tmp.dot
+++ /dev/null
@@ -1,29 +0,0 @@
-digraph  {
-	ranksep="1.0 equally";
-	n9[color="#B85450",fillcolor="#F8CECC",label="",shape="Mdiamond",style="filled"];
-	n10[color="#B85450",fillcolor="#F8CECC",label="",shape="Mdiamond",style="filled"];
-	n11[color="#B85450",fillcolor="#F8CECC",label="",shape="Mdiamond",style="filled"];
-	n6[color="#9673A6",fillcolor="#DAE8FC",label="AGGREGATED REALITY\n\n0x59a7cb38c58588aba986f855051495abc475b804c8cb246fd6757407f6293668 (1)",penwidth="2.0",shape="rect",style="filled"];
-	n1[color="#6C8EBF",fillcolor="#DAE8FC",label="REALITY\n\nGSufYxGepaLWsiLwDLAURWfgkmTTydqP (1)",shape="rect",style="filled"];
-	n3[color="#6C8EBF",fillcolor="#DAE8FC",label="REALITY\n\nHYVbVsWtXuokjqsezXDxIwFLsojfAqHH (1)",shape="rect",style="filled"];
-	n2[color="#6C8EBF",fillcolor="#DAE8FC",label="REALITY\n\nMAIN_REALITY (2)",shape="rect",style="filled"];
-	n4[color="#6C8EBF",fillcolor="#DAE8FC",label="REALITY\n\nNWscRATSxEOMUCWFMtsGiMvveCzTDggi (1)",shape="rect",style="filled"];
-	n5[color="#6C8EBF",fillcolor="#DAE8FC",label="REALITY\n\nOujbHEvHbaogJoYgDMPPqapnhEFmNweo (1)",shape="rect",style="filled"];
-	n7[color="#6C8EBF",fillcolor="#DAE8FC",label="REALITY\n\nuoIdkaUxrjBlNIwuAWAfNenOPudzhlUx (1)",shape="rect",style="filled"];
-	n8[color="#6C8EBF",fillcolor="#DAE8FC",label="REALITY\n\nxEjDqModkSvUmyKFxgAaaghSSdbtEOJk (1)",shape="rect",style="filled"];
-	n9->n5[arrowhead="none",arrowtail="none",color="#B85450"];
-	n9->n3[arrowhead="none",arrowtail="none",color="#B85450"];
-	n10->n7[arrowhead="none",arrowtail="none",color="#B85450"];
-	n10->n8[arrowhead="none",arrowtail="none",color="#B85450"];
-	n11->n1[arrowhead="none",arrowtail="none",color="#B85450"];
-	n11->n4[arrowhead="none",arrowtail="none",color="#B85450"];
-	n6->n7[arrowhead="none",arrowtail="none"];
-	n6->n5[arrowhead="none",arrowtail="none"];
-	n1->n2[arrowhead="none",arrowtail="none"];
-	n3->n4[arrowhead="none",arrowtail="none"];
-	n4->n2[arrowhead="none",arrowtail="none"];
-	n5->n4[arrowhead="none",arrowtail="none"];
-	n7->n2[arrowhead="none",arrowtail="none"];
-	n8->n2[arrowhead="none",arrowtail="none"];
-	
-}
\ No newline at end of file
diff --git a/packages/ledgerstate/conflict_set.go b/packages/ledgerstate/conflict.go
similarity index 50%
rename from packages/ledgerstate/conflict_set.go
rename to packages/ledgerstate/conflict.go
index c9d429c5183fa020375af6e736951b98c4f7f6a3..a65dcf570a4f437680a63a591e2626250ac15d46 100644
--- a/packages/ledgerstate/conflict_set.go
+++ b/packages/ledgerstate/conflict.go
@@ -10,8 +10,8 @@ import (
 	"github.com/iotaledger/hive.go/objectstorage"
 )
 
-type ConflictSet struct {
-	id      ConflictSetId
+type Conflict struct {
+	id      ConflictId
 	members map[RealityId]empty
 
 	storageKey  []byte
@@ -20,8 +20,8 @@ type ConflictSet struct {
 	membersMutex sync.RWMutex
 }
 
-func newConflictSet(id ConflictSetId) *ConflictSet {
-	result := &ConflictSet{
+func newConflictSet(id ConflictId) *Conflict {
+	result := &Conflict{
 		id:      id,
 		members: make(map[RealityId]empty),
 
@@ -32,73 +32,73 @@ func newConflictSet(id ConflictSetId) *ConflictSet {
 	return result
 }
 
-func (conflictSet *ConflictSet) GetId() ConflictSetId {
-	return conflictSet.id
+func (conflict *Conflict) GetId() ConflictId {
+	return conflict.id
 }
 
-func (conflictSet *ConflictSet) AddReality(realityId RealityId) {
-	conflictSet.membersMutex.Lock()
+func (conflict *Conflict) AddReality(realityId RealityId) {
+	conflict.membersMutex.Lock()
 
-	conflictSet.members[realityId] = void
+	conflict.members[realityId] = void
 
-	conflictSet.membersMutex.Unlock()
+	conflict.membersMutex.Unlock()
 }
 
-func (conflictSet *ConflictSet) String() string {
-	conflictSet.membersMutex.RLock()
-	defer conflictSet.membersMutex.RUnlock()
+func (conflict *Conflict) String() string {
+	conflict.membersMutex.RLock()
+	defer conflict.membersMutex.RUnlock()
 
-	return stringify.Struct("ConflictSet",
-		stringify.StructField("id", conflictSet.id.String()),
-		stringify.StructField("members", conflictSet.members),
+	return stringify.Struct("Conflict",
+		stringify.StructField("id", conflict.id.String()),
+		stringify.StructField("members", conflict.members),
 	)
 }
 
 // region support object storage ///////////////////////////////////////////////////////////////////////////////////////
 
-func (conflictSet *ConflictSet) GetStorageKey() []byte {
-	return conflictSet.storageKey
+func (conflict *Conflict) GetStorageKey() []byte {
+	return conflict.storageKey
 }
 
-func (conflictSet *ConflictSet) Update(other objectstorage.StorableObject) {
+func (conflict *Conflict) Update(other objectstorage.StorableObject) {
 	fmt.Println("UPDATE")
 }
 
-func (conflictSet *ConflictSet) MarshalBinary() ([]byte, error) {
-	conflictSet.membersMutex.RLock()
+func (conflict *Conflict) MarshalBinary() ([]byte, error) {
+	conflict.membersMutex.RLock()
 
 	offset := 0
-	membersCount := len(conflictSet.members)
+	membersCount := len(conflict.members)
 	result := make([]byte, 4+membersCount*realityIdLength)
 
 	binary.LittleEndian.PutUint32(result[offset:], uint32(membersCount))
 	offset += 4
 
-	for realityId := range conflictSet.members {
+	for realityId := range conflict.members {
 		copy(result[offset:], realityId[:realityIdLength])
 		offset += realityIdLength
 	}
 
-	conflictSet.membersMutex.RUnlock()
+	conflict.membersMutex.RUnlock()
 
 	return result, nil
 }
 
-func (conflictSet *ConflictSet) UnmarshalBinary(serializedObject []byte) error {
-	if err := conflictSet.id.UnmarshalBinary(conflictSet.storageKey); err != nil {
+func (conflict *Conflict) UnmarshalBinary(serializedObject []byte) error {
+	if err := conflict.id.UnmarshalBinary(conflict.storageKey); err != nil {
 		return err
 	}
 
-	if members, err := conflictSet.unmarshalMembers(serializedObject); err != nil {
+	if members, err := conflict.unmarshalMembers(serializedObject); err != nil {
 		return err
 	} else {
-		conflictSet.members = members
+		conflict.members = members
 	}
 
 	return nil
 }
 
-func (conflictSet *ConflictSet) unmarshalMembers(serializedConsumers []byte) (map[RealityId]empty, error) {
+func (conflict *Conflict) unmarshalMembers(serializedConsumers []byte) (map[RealityId]empty, error) {
 	offset := 0
 
 	membersCount := int(binary.LittleEndian.Uint32(serializedConsumers[offset:]))
diff --git a/packages/ledgerstate/conflict_set_id.go b/packages/ledgerstate/conflict_id.go
similarity index 57%
rename from packages/ledgerstate/conflict_set_id.go
rename to packages/ledgerstate/conflict_id.go
index 2f6862794f35ada2a48dd79a503b21cc6dc86249..0d084ca047931540bac891e7c29ce09b774864a4 100644
--- a/packages/ledgerstate/conflict_set_id.go
+++ b/packages/ledgerstate/conflict_id.go
@@ -7,17 +7,17 @@ import (
 	"golang.org/x/crypto/blake2b"
 )
 
-type ConflictSetId [conflictSetIdLength]byte
+type ConflictId [conflictSetIdLength]byte
 
-func NewConflictSetId(conflictSetBytes ...interface{}) (result ConflictSetId) {
-	switch len(conflictSetBytes) {
+func NewConflictSetId(conflictBytes ...interface{}) (result ConflictId) {
+	switch len(conflictBytes) {
 	case 2:
-		transferHash, ok := conflictSetBytes[0].(TransferHash)
+		transferHash, ok := conflictBytes[0].(TransferHash)
 		if !ok {
 			panic("expected first parameter of NewConflictSetId to be a TransferHash")
 		}
 
-		addressHash, ok := conflictSetBytes[0].(TransferHash)
+		addressHash, ok := conflictBytes[0].(TransferHash)
 		if !ok {
 			panic("expected second parameter of NewConflictSetId to be a AddressHash")
 		}
@@ -35,17 +35,17 @@ func NewConflictSetId(conflictSetBytes ...interface{}) (result ConflictSetId) {
 	return
 }
 
-func (conflictSetId *ConflictSetId) UnmarshalBinary(data []byte) error {
-	copy(conflictSetId[:], data[:conflictSetIdLength])
+func (conflictId *ConflictId) UnmarshalBinary(data []byte) error {
+	copy(conflictId[:], data[:conflictSetIdLength])
 
 	return nil
 }
 
-func (conflictSetId ConflictSetId) String() string {
-	if utf8.Valid(conflictSetId[:]) {
-		return string(conflictSetId[:])
+func (conflictId ConflictId) String() string {
+	if utf8.Valid(conflictId[:]) {
+		return string(conflictId[:])
 	} else {
-		return stringify.SliceOfBytes(conflictSetId[:])
+		return stringify.SliceOfBytes(conflictId[:])
 	}
 }
 
diff --git a/packages/ledgerstate/conflict_id_list.go b/packages/ledgerstate/conflict_id_list.go
new file mode 100644
index 0000000000000000000000000000000000000000..afd0a940ba574362390119b17bfe565898214dfc
--- /dev/null
+++ b/packages/ledgerstate/conflict_id_list.go
@@ -0,0 +1,23 @@
+package ledgerstate
+
+type ConflictIdList []ConflictId
+
+func (conflictIdList ConflictIdList) Clone() (clone ConflictIdList) {
+	clone = make(ConflictIdList, len(conflictIdList))
+
+	for key, value := range conflictIdList {
+		clone[key] = value
+	}
+
+	return
+}
+
+func (conflictIdList ConflictIdList) ToSet() (set ConflictIdSet) {
+	set = make(ConflictIdSet)
+
+	for _, value := range conflictIdList {
+		set[value] = void
+	}
+
+	return
+}
diff --git a/packages/ledgerstate/conflict_id_set.go b/packages/ledgerstate/conflict_id_set.go
new file mode 100644
index 0000000000000000000000000000000000000000..ccc431cae1e6a082de9e803dd6ee059b956e091a
--- /dev/null
+++ b/packages/ledgerstate/conflict_id_set.go
@@ -0,0 +1,36 @@
+package ledgerstate
+
+type ConflictIdSet map[ConflictId]empty
+
+func NewConflictIdSet(conflictIds ...ConflictId) (conflictIdSet ConflictIdSet) {
+	conflictIdSet = make(ConflictIdSet)
+
+	for _, realityId := range conflictIds {
+		conflictIdSet[realityId] = void
+	}
+
+	return
+}
+
+func (conflictIdSet ConflictIdSet) Clone() (clone ConflictIdSet) {
+	clone = make(ConflictIdSet, len(conflictIdSet))
+
+	for key := range conflictIdSet {
+		clone[key] = void
+	}
+
+	return
+}
+
+func (conflictIdSet ConflictIdSet) ToList() (list ConflictIdList) {
+	list = make(ConflictIdList, len(conflictIdSet))
+
+	i := 0
+	for key := range conflictIdSet {
+		list[i] = key
+
+		i++
+	}
+
+	return
+}
diff --git a/packages/ledgerstate/ledgerstate.go b/packages/ledgerstate/ledgerstate.go
index 04759124465313085777feb1e65c8711d09d1e79..caf22788e6857bbf8dd24f3f317a8343e3b7de1a 100644
--- a/packages/ledgerstate/ledgerstate.go
+++ b/packages/ledgerstate/ledgerstate.go
@@ -10,6 +10,8 @@ import (
 	"strings"
 	"time"
 
+	"github.com/iotaledger/goshimmer/packages/graphviz"
+
 	"golang.org/x/crypto/blake2b"
 
 	"github.com/emicklei/dot"
@@ -68,7 +70,7 @@ func (ledgerState *LedgerState) GetTransferOutput(transferOutputReference *Trans
 
 func (ledgerState *LedgerState) ForEachConflictSet(callback func(object *objectstorage.CachedObject) bool) {
 	if err := ledgerState.conflictSets.ForEach(func(key []byte, cachedObject *objectstorage.CachedObject) bool {
-		cachedObject.Get().(*ConflictSet).ledgerState = ledgerState
+		cachedObject.Get().(*Conflict).ledgerState = ledgerState
 
 		return callback(cachedObject)
 	}); err != nil {
@@ -161,13 +163,13 @@ func (ledgerState *LedgerState) BookTransfer(transfer *Transfer) error {
 }
 
 func (ledgerState *LedgerState) GenerateRealityVisualization(pngFilename string) error {
-	di := dot.NewGraph(dot.Directed)
-	di.Attr("ranksep", "1.0 equally")
+	graph := dot.NewGraph(dot.Directed)
+	graph.Attr("ranksep", "1.0 equally")
 
 	realityNodes := make(map[RealityId]dot.Node)
 
-	drawConflictSet := func(conflictSet *ConflictSet) {
-		conflictSetNode := di.Node(strings.Trim(conflictSet.id.String(), "\x00"))
+	drawConflictSet := func(conflictSet *Conflict) {
+		conflictSetNode := graph.Node(strings.Trim(conflictSet.id.String(), "\x00"))
 		conflictSetNode.Attr("label", "")
 		conflictSetNode.Attr("shape", "Mdiamond")
 		conflictSetNode.Attr("style", "filled")
@@ -181,24 +183,24 @@ func (ledgerState *LedgerState) GenerateRealityVisualization(pngFilename string)
 
 	var drawReality func(reality *Reality) dot.Node
 	drawReality = func(reality *Reality) dot.Node {
-		realityNode, exists := realityNodes[reality.GetId()]
+		realityNode, exists := realityNodes[reality.id]
 		if !exists {
-			if len(reality.parentRealities) > 1 {
-				realityNode = di.Node("AGGREGATED REALITY\n\n" + strings.Trim(reality.GetId().String(), "\x00") + " (" + strconv.Itoa(reality.GetTransferOutputCount()) + ")")
+			if reality.IsAggregated() {
+				realityNode = graph.Node("AGGREGATED REALITY\n\n" + strings.Trim(reality.id.String(), "\x00") + " (" + strconv.Itoa(int(reality.GetTransferOutputCount())) + ")")
 				realityNode.Attr("style", "filled")
 				realityNode.Attr("shape", "rect")
 				realityNode.Attr("color", "#9673A6")
 				realityNode.Attr("fillcolor", "#DAE8FC")
 				realityNode.Attr("penwidth", "2.0")
 			} else {
-				realityNode = di.Node("REALITY\n\n" + strings.Trim(reality.GetId().String(), "\x00") + " (" + strconv.Itoa(reality.GetTransferOutputCount()) + ")")
+				realityNode = graph.Node("REALITY\n\n" + strings.Trim(reality.id.String(), "\x00") + " (" + strconv.Itoa(int(reality.GetTransferOutputCount())) + ")")
 				realityNode.Attr("style", "filled")
 				realityNode.Attr("shape", "rect")
 				realityNode.Attr("color", "#6C8EBF")
 				realityNode.Attr("fillcolor", "#DAE8FC")
 			}
 
-			realityNodes[reality.GetId()] = realityNode
+			realityNodes[reality.id] = realityNode
 		}
 
 		if !exists {
@@ -221,30 +223,15 @@ func (ledgerState *LedgerState) GenerateRealityVisualization(pngFilename string)
 
 		return true
 	})
-
 	ledgerState.ForEachConflictSet(func(object *objectstorage.CachedObject) bool {
 		object.Consume(func(object objectstorage.StorableObject) {
-			drawConflictSet(object.(*ConflictSet))
+			drawConflictSet(object.(*Conflict))
 		})
 
 		return true
 	})
 
-	d1 := []byte(di.String())
-	if err := ioutil.WriteFile("_tmp.dot", d1, 0755); err != nil {
-		return err
-	}
-
-	_, err := exec.Command("dot", "-Tpng", "_tmp.dot", "-o", pngFilename).Output()
-	if err != nil {
-		return err
-	}
-
-	//if err := os.Remove("_tmp.dot"); err != nil {
-	//	return err
-	//}
-
-	return nil
+	return graphviz.RenderPNG(graph, pngFilename)
 }
 
 func (ledgerState *LedgerState) GenerateVisualization() error {
@@ -309,7 +296,7 @@ func (ledgerState *LedgerState) GenerateVisualization() error {
 	return nil
 }
 
-func (ledgerState *LedgerState) MergeRealities(realityIds ...RealityId) *objectstorage.CachedObject {
+func (ledgerState *LedgerState) AggregateRealities(realityIds ...RealityId) *objectstorage.CachedObject {
 	switch len(realityIds) {
 	case 0:
 		if loadedReality, loadedRealityErr := ledgerState.realities.Load(MAIN_REALITY_ID[:]); loadedRealityErr != nil {
@@ -352,16 +339,16 @@ func (ledgerState *LedgerState) MergeRealities(realityIds ...RealityId) *objects
 			for aggregatedRealityId, aggregatedReality := range aggregatedRealities {
 				// if an already aggregated reality "descends" from the current reality, then we have found the more
 				// "specialized" reality already and keep it
-				if aggregatedReality.Get().(*Reality).DescendsFromReality(realityId) {
+				if aggregatedReality.Get().(*Reality).DescendsFrom(realityId) {
 					continue AGGREGATE_REALITIES
 				}
 
 				// if the current reality
-				if reality.DescendsFromReality(aggregatedRealityId) {
+				if reality.DescendsFrom(aggregatedRealityId) {
 					delete(aggregatedRealities, aggregatedRealityId)
 					aggregatedReality.Release()
 
-					aggregatedRealities[reality.GetId()] = cachedReality
+					aggregatedRealities[reality.id] = cachedReality
 
 					continue AGGREGATE_REALITIES
 				}
@@ -540,7 +527,7 @@ func (ledgerState *LedgerState) getTargetReality(inputs []*objectstorage.CachedO
 		realityIds[i] = input.Get().(*TransferOutput).GetRealityId()
 	}
 
-	return ledgerState.MergeRealities(realityIds...)
+	return ledgerState.AggregateRealities(realityIds...)
 }
 
 func (ledgerState *LedgerState) getTransferInputs(transfer *Transfer) []*objectstorage.CachedObject {
@@ -582,7 +569,7 @@ func realityFactory(key []byte) objectstorage.StorableObject {
 }
 
 func conflictSetFactory(key []byte) objectstorage.StorableObject {
-	result := &ConflictSet{
+	result := &Conflict{
 		storageKey: make([]byte, len(key)),
 	}
 	copy(result.storageKey, key)
diff --git a/packages/ledgerstate/ledgerstate_test.go b/packages/ledgerstate/ledgerstate_test.go
index c41f90d7e5877b4c1b641f39ce130c7c55f3aea5..3ede10579c54fcf560b224a631e50a65c469b4f1 100644
--- a/packages/ledgerstate/ledgerstate_test.go
+++ b/packages/ledgerstate/ledgerstate_test.go
@@ -6,6 +6,8 @@ import (
 	"testing"
 	"time"
 
+	"github.com/iotaledger/hive.go/parameter"
+
 	"github.com/iotaledger/goshimmer/packages/utils"
 
 	"github.com/iotaledger/hive.go/objectstorage"
@@ -29,6 +31,12 @@ var (
 	pendingReality = NewRealityId("PENDING")
 )
 
+func init() {
+	if err := parameter.FetchConfig(false); err != nil {
+		panic(err)
+	}
+}
+
 func Benchmark(b *testing.B) {
 	ledgerState := NewLedgerState("testLedger").Prune().AddTransferOutput(
 		transferHash1, addressHash1, NewColoredBalance(eth, 1337),
diff --git a/packages/ledgerstate/realities.png b/packages/ledgerstate/realities.png
index 06e0c5c9713e6efcfeb4b2c57075af9492f3ff62..ee04a70dc73d14b3b2f6fb0e66d329a0c21c9f19 100644
Binary files a/packages/ledgerstate/realities.png and b/packages/ledgerstate/realities.png differ
diff --git a/packages/ledgerstate/reality.go b/packages/ledgerstate/reality.go
index 4ed825f5b8e5c90ff2381faaca51649e6b05af94..3645f10697a9699a661c835e263234772b8e6516 100644
--- a/packages/ledgerstate/reality.go
+++ b/packages/ledgerstate/reality.go
@@ -1,63 +1,90 @@
 package ledgerstate
 
 import (
-	"fmt"
 	"sync"
+	"sync/atomic"
 
 	"github.com/iotaledger/goshimmer/packages/errors"
-
 	"github.com/iotaledger/goshimmer/packages/stringify"
 
 	"github.com/iotaledger/hive.go/objectstorage"
 )
 
 type Reality struct {
-	id                  RealityId
-	transferOutputCount int
-	parentRealities     map[RealityId]empty
-	conflictSets        map[ConflictSetId]empty
+	id                    RealityId
+	parentRealityIds      RealityIdSet
+	parentRealityIdsMutex sync.RWMutex
+	conflictIds           ConflictIdSet
+	conflictIdsMutex      sync.RWMutex
+	transferOutputCount   uint32
 
 	storageKey  []byte
 	ledgerState *LedgerState
-
-	bookingMutex             sync.RWMutex
-	transferOutputCountMutex sync.RWMutex
-	parentRealitiesMutex     sync.RWMutex
-	conflictSetsMutex        sync.RWMutex
 }
 
+// region DONE REVIEWING ///////////////////////////////////////////////////////////////////////////////////////////////
+
+// Creates a new Reality with the given id and parents. It is only used internally and therefore "private".
 func newReality(id RealityId, parentRealities ...RealityId) *Reality {
 	result := &Reality{
-		id:              id,
-		parentRealities: make(map[RealityId]empty),
-		conflictSets:    make(map[ConflictSetId]empty),
+		id:               id,
+		parentRealityIds: NewRealityIdSet(parentRealities...),
+		conflictIds:      NewConflictIdSet(),
 
 		storageKey: make([]byte, len(id)),
 	}
 	copy(result.storageKey, id[:])
 
-	for _, parentRealityId := range parentRealities {
-		result.parentRealities[parentRealityId] = void
-	}
-
 	return result
 }
 
+// Returns the id of this Reality. Since the id never changes, we do not need a mutex to protect this property.
 func (reality *Reality) GetId() RealityId {
 	return reality.id
 }
 
-func (reality *Reality) GetTransferOutputCount() (transferOutputCount int) {
-	reality.transferOutputCountMutex.RLock()
-	transferOutputCount = reality.transferOutputCount
-	reality.transferOutputCountMutex.RUnlock()
+// Returns the set of RealityIds that are the parents of this Reality (it creates a clone).
+func (reality *Reality) GetParentRealityIds() (realityIdSet RealityIdSet) {
+	reality.parentRealityIdsMutex.RLock()
+	realityIdSet = reality.parentRealityIds.Clone()
+	reality.parentRealityIdsMutex.RUnlock()
 
 	return
 }
 
-// [DONE] Checks if the Reality "descends" from the given RealityId. It returns true, if the RealityId addresses the
-// Reality itself, or one of its ancestors.
-func (reality *Reality) DescendsFromReality(realityId RealityId) bool {
+// Sets the set of RealityIds that are the parents of this Reality.
+func (reality *Reality) SetParentRealityIds(parentRealityIds RealityIdSet) {
+	reality.parentRealityIdsMutex.Lock()
+	reality.parentRealityIds = parentRealityIds
+	reality.parentRealityIdsMutex.Unlock()
+}
+
+// Returns the amount of TransferOutputs in this Reality.
+func (reality *Reality) GetTransferOutputCount() uint32 {
+	return atomic.LoadUint32(&(reality.transferOutputCount))
+}
+
+// Increases (and returns) the amount of TransferOutputs in this Reality.
+func (reality *Reality) IncreaseTransferOutputCount() uint32 {
+	return atomic.AddUint32(&(reality.transferOutputCount), 1)
+}
+
+// Decreases (and returns) the amount of TransferOutputs in this Reality.
+func (reality *Reality) DecreaseTransferOutputCount() uint32 {
+	return atomic.AddUint32(&(reality.transferOutputCount), ^uint32(0))
+}
+
+// Returns true, if this reality is an "aggregated reality" that combines multiple other realities.
+func (reality *Reality) IsAggregated() (isAggregated bool) {
+	reality.parentRealityIdsMutex.RLock()
+	isAggregated = len(reality.parentRealityIds) > 1
+	reality.parentRealityIdsMutex.RUnlock()
+
+	return
+}
+
+// Returns true if the given RealityId addresses the Reality itself or one of its ancestors.
+func (reality *Reality) DescendsFrom(realityId RealityId) bool {
 	if reality.id == realityId {
 		return true
 	} else {
@@ -75,25 +102,27 @@ func (reality *Reality) DescendsFromReality(realityId RealityId) bool {
 	}
 }
 
+// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
 // [DONE] Returns a map of all parent realities (one level). They have to manually be "released" when they are not
 // needed anymore.
 func (reality *Reality) GetParentRealities() map[RealityId]*objectstorage.CachedObject {
 	parentRealities := make(map[RealityId]*objectstorage.CachedObject)
 
-	reality.parentRealitiesMutex.RLock()
+	reality.parentRealityIdsMutex.RLock()
 
-	for parentRealityId := range reality.parentRealities {
+	for parentRealityId := range reality.parentRealityIds {
 		loadedParentReality := reality.ledgerState.GetReality(parentRealityId)
 		if !loadedParentReality.Exists() {
-			reality.parentRealitiesMutex.RUnlock()
+			reality.parentRealityIdsMutex.RUnlock()
 
 			panic("could not load parent reality with id \"" + string(parentRealityId[:]) + "\"")
 		}
 
-		parentRealities[loadedParentReality.Get().(*Reality).GetId()] = loadedParentReality
+		parentRealities[loadedParentReality.Get().(*Reality).id] = loadedParentReality
 	}
 
-	reality.parentRealitiesMutex.RUnlock()
+	reality.parentRealityIdsMutex.RUnlock()
 
 	return parentRealities
 }
@@ -115,10 +144,10 @@ func (reality *Reality) GetAncestorRealities() (result map[RealityId]*objectstor
 }
 
 // [DONE] Registers the conflict set in the Reality.
-func (reality *Reality) AddConflictSet(conflictSetId ConflictSetId) {
-	reality.conflictSetsMutex.Lock()
-	reality.conflictSets[conflictSetId] = void
-	reality.conflictSetsMutex.Unlock()
+func (reality *Reality) AddConflictSet(conflictSetId ConflictId) {
+	reality.conflictIdsMutex.Lock()
+	reality.conflictIds[conflictSetId] = void
+	reality.conflictIdsMutex.Unlock()
 }
 
 // [DONE] Creates a new sub Reality and "stores" it. It has to manually be "released" when it is not needed anymore.
@@ -130,12 +159,8 @@ func (reality *Reality) CreateReality(id RealityId) *objectstorage.CachedObject
 }
 
 func (reality *Reality) BookTransfer(transfer *Transfer) (err error) {
-	reality.bookingMutex.RLock()
-
 	err = reality.bookTransfer(transfer.GetHash(), reality.ledgerState.getTransferInputs(transfer), transfer.GetOutputs())
 
-	reality.bookingMutex.RUnlock()
-
 	return
 }
 
@@ -153,15 +178,24 @@ func (reality *Reality) bookTransfer(transferHash TransferHash, inputs objectsto
 		var targetRealityId RealityId
 		copy(targetRealityId[:], transferHash[:])
 
-		for _, conflictSet := range conflictSets {
-			conflictSet.Get().(*ConflictSet).AddReality(targetRealityId)
-		}
-
 		reality.CreateReality(targetRealityId).Consume(func(object objectstorage.StorableObject) {
-			object.(*Reality).persistTransfer(transferHash, outputs)
+			targetReality := object.(*Reality)
+
+			for _, cachedConflictSet := range conflictSets {
+				conflictSet := cachedConflictSet.Get().(*Conflict)
+
+				conflictSet.AddReality(targetRealityId)
+				targetReality.AddConflictSet(conflictSet.GetId())
+			}
+
+			for addressHash, coloredBalances := range outputs {
+				targetReality.bookTransferOutput(NewTransferOutput(reality.ledgerState, emptyRealityId, transferHash, addressHash, coloredBalances...))
+			}
 		})
 	} else {
-		reality.persistTransfer(transferHash, outputs)
+		for addressHash, coloredBalances := range outputs {
+			reality.bookTransferOutput(NewTransferOutput(reality.ledgerState, emptyRealityId, transferHash, addressHash, coloredBalances...))
+		}
 	}
 
 	conflictSets.Release()
@@ -180,7 +214,7 @@ func (reality *Reality) verifyTransfer(inputs []*objectstorage.CachedObject, out
 		}
 
 		transferOutput := cachedInput.Get().(*TransferOutput)
-		if !reality.DescendsFromReality(transferOutput.GetRealityId()) {
+		if !reality.DescendsFrom(transferOutput.GetRealityId()) {
 			return errors.New("the referenced funds do not exist in this reality")
 		}
 
@@ -245,7 +279,7 @@ func (reality *Reality) retrieveConflictSetForConflictingInput(input *TransferOu
 
 		conflictSet = reality.ledgerState.conflictSets.Store(newConflictSet)
 
-		err = reality.elevateTransferOutputs(consumersToElevate, conflictSet.Get().(*ConflictSet))
+		err = reality.createRealityForConflictingConsumers(consumersToElevate, conflictSet.Get().(*Conflict))
 		if err != nil {
 			return
 		}
@@ -254,14 +288,14 @@ func (reality *Reality) retrieveConflictSetForConflictingInput(input *TransferOu
 		if err != nil {
 			return
 		}
-		conflictSet.Get().(*ConflictSet).ledgerState = reality.ledgerState
+		conflictSet.Get().(*Conflict).ledgerState = reality.ledgerState
 	}
 
 	return
 }
 
-func (reality *Reality) elevateTransferOutputs(transferOutputs map[TransferHash][]AddressHash, conflictSet *ConflictSet) (err error) {
-	for transferHash, addressHashes := range transferOutputs {
+func (reality *Reality) createRealityForConflictingConsumers(conflictingConsumers map[TransferHash][]AddressHash, conflictSet *Conflict) (err error) {
+	for transferHash, addressHashes := range conflictingConsumers {
 		// determine RealityId
 		elevatedRealityId := transferHash.ToRealityId()
 
@@ -269,11 +303,11 @@ func (reality *Reality) elevateTransferOutputs(transferOutputs map[TransferHash]
 		reality.CreateReality(elevatedRealityId).Consume(func(object objectstorage.StorableObject) {
 			elevatedReality := object.(*Reality)
 
-			// register Reality <-> ConflictSet
+			// register Reality <-> Conflict
 			conflictSet.AddReality(elevatedRealityId)
 			elevatedReality.AddConflictSet(conflictSet.GetId())
 
-			// elevate TransferOutputs
+			// elevate TransferOutputs to the new Reality
 			for _, addressHash := range addressHashes {
 				if err = reality.elevateTransferOutput(NewTransferOutputReference(transferHash, addressHash), elevatedReality); err != nil {
 					return
@@ -286,68 +320,65 @@ func (reality *Reality) elevateTransferOutputs(transferOutputs map[TransferHash]
 }
 
 func (reality *Reality) elevateTransferOutput(transferOutputReference *TransferOutputReference, newReality *Reality) (err error) {
-	if cachedTransferOutputToElevate := reality.ledgerState.GetTransferOutput(transferOutputReference); !cachedTransferOutputToElevate.Exists() {
+	cachedTransferOutputToElevate := reality.ledgerState.GetTransferOutput(transferOutputReference)
+	if !cachedTransferOutputToElevate.Exists() {
 		return errors.New("could not find TransferOutput to elevate")
-	} else {
-		cachedTransferOutputToElevate.Consume(func(object objectstorage.StorableObject) {
-			transferOutputToElevate := object.(*TransferOutput)
+	}
 
-			if transferOutputToElevate.GetRealityId() == reality.id {
-				if moveErr := newReality.bookTransferOutput(transferOutputToElevate); moveErr != nil {
-					err = moveErr
+	cachedTransferOutputToElevate.Consume(func(object objectstorage.StorableObject) {
+		transferOutputToElevate := object.(*TransferOutput)
 
-					return
-				}
+		if transferOutputToElevate.GetRealityId() == reality.id {
+			err = reality.elevateTransferOutputOfCurrentReality(transferOutputToElevate, newReality)
+		} else {
+			reality.ledgerState.GetReality(transferOutputToElevate.GetRealityId()).Consume(func(nestedReality objectstorage.StorableObject) {
+				err = nestedReality.(*Reality).elevateTransferOutputOfNestedReality(transferOutputToElevate, reality.id, newReality.id)
+			})
+		}
+	})
 
-				for transferHash, addresses := range transferOutputToElevate.GetConsumers() {
-					for _, addressHash := range addresses {
-						if elevateErr := reality.elevateTransferOutput(NewTransferOutputReference(transferHash, addressHash), newReality); elevateErr != nil {
-							err = elevateErr
+	return
+}
 
-							return
-						}
-					}
-				}
-			} else {
-				reality.ledgerState.GetReality(transferOutputToElevate.GetRealityId()).Consume(func(nestedReality objectstorage.StorableObject) {
-					nestedReality.(*Reality).elevateReality(reality.id, newReality.GetId())
-				})
+func (reality *Reality) elevateTransferOutputOfCurrentReality(transferOutput *TransferOutput, newReality *Reality) (err error) {
+	if err = newReality.bookTransferOutput(transferOutput); err != nil {
+		return
+	}
+
+	for transferHash, addresses := range transferOutput.GetConsumers() {
+		for _, addressHash := range addresses {
+			if elevateErr := reality.elevateTransferOutput(NewTransferOutputReference(transferHash, addressHash), newReality); elevateErr != nil {
+				err = elevateErr
+
+				return
 			}
-		})
+		}
 	}
 
 	return
 }
 
-func (reality *Reality) elevateReality(oldParentRealityId RealityId, newParentRealityId RealityId) {
-	reality.bookingMutex.Lock()
-	reality.parentRealitiesMutex.Lock()
+func (reality *Reality) elevateTransferOutputOfNestedReality(transferOutput *TransferOutput, oldParentRealityId RealityId, newParentRealityId RealityId) (err error) {
+	if !reality.IsAggregated() {
+		reality.parentRealityIdsMutex.Lock()
+		reality.parentRealityIds.Remove(oldParentRealityId).Add(newParentRealityId)
+		reality.parentRealityIdsMutex.Unlock()
 
-	fmt.Println(reality.id)
-
-	if len(reality.parentRealities) > 1 {
-		// aggregated reality
-		fmt.Println("AGGREGATED REALITY")
-		delete(reality.parentRealities, oldParentRealityId)
-		reality.parentRealities[newParentRealityId] = void
-	} else {
-		delete(reality.parentRealities, oldParentRealityId)
-		reality.parentRealities[newParentRealityId] = void
+		return
 	}
 
-	reality.parentRealitiesMutex.Unlock()
-	reality.bookingMutex.Unlock()
-}
+	newParentRealities := reality.GetParentRealityIds().Remove(oldParentRealityId).Add(newParentRealityId).ToList()
 
-func (reality *Reality) persistTransfer(transferHash TransferHash, transferOutputs map[AddressHash][]*ColoredBalance) {
-	for addressHash, coloredBalances := range transferOutputs {
-		reality.bookTransferOutput(NewTransferOutput(reality.ledgerState, emptyRealityId, transferHash, addressHash, coloredBalances...))
-	}
+	reality.ledgerState.AggregateRealities(newParentRealities...).Store().Consume(func(object objectstorage.StorableObject) {
+		err = reality.elevateTransferOutputOfCurrentReality(transferOutput, object.(*Reality))
+	})
+
+	return
 }
 
 func (reality *Reality) bookTransferOutput(transferOutput *TransferOutput) (err error) {
 	// retrieve required variables
-	realityId := reality.GetId()
+	realityId := reality.id
 	transferOutputRealityId := transferOutput.GetRealityId()
 	transferOutputAddressHash := transferOutput.GetAddressHash()
 	transferOutputSpent := len(transferOutput.consumers) >= 1
@@ -368,11 +399,10 @@ func (reality *Reality) bookTransferOutput(transferOutput *TransferOutput) (err
 			transferOutput.SetRealityId(realityId)
 
 			reality.ledgerState.GetReality(transferOutputRealityId).Consume(func(object objectstorage.StorableObject) {
-				oldReality := object.(*Reality)
-
-				oldReality.transferOutputCountMutex.Lock()
-				oldReality.transferOutputCount--
-				oldReality.transferOutputCountMutex.Unlock()
+				// decrease transferOutputCount and remove reality if it is empty
+				if object.(*Reality).DecreaseTransferOutputCount() == 0 {
+					reality.ledgerState.realities.Delete(transferOutputRealityId[:])
+				}
 			})
 
 			oldTransferOutputBooking.Delete().Release()
@@ -383,21 +413,18 @@ func (reality *Reality) bookTransferOutput(transferOutput *TransferOutput) (err
 	if transferOutputRealityId != realityId {
 		reality.ledgerState.storeTransferOutputBooking(newTransferOutputBooking(realityId, transferOutputAddressHash, transferOutputSpent, transferOutputTransferHash)).Release()
 
-		reality.transferOutputCountMutex.Lock()
-		reality.transferOutputCount++
-		reality.transferOutputCountMutex.Unlock()
+		reality.IncreaseTransferOutputCount()
 	}
 
 	return
 }
 
 func (reality *Reality) String() (result string) {
-	reality.parentRealitiesMutex.RLock()
-
-	parentRealities := make([]string, len(reality.parentRealities))
+	reality.parentRealityIdsMutex.RLock()
 
+	parentRealities := make([]string, len(reality.parentRealityIds))
 	i := 0
-	for parentRealityId := range reality.parentRealities {
+	for parentRealityId := range reality.parentRealityIds {
 		parentRealities[i] = parentRealityId.String()
 
 		i++
@@ -408,7 +435,7 @@ func (reality *Reality) String() (result string) {
 		stringify.StructField("parentRealities", parentRealities),
 	)
 
-	reality.parentRealitiesMutex.RUnlock()
+	reality.parentRealityIdsMutex.RUnlock()
 
 	return
 }
diff --git a/packages/ledgerstate/reality.objectstorage.go b/packages/ledgerstate/reality.objectstorage.go
index 8dabf05632a444fcbb1fffa13d7583265f0fa423..7ccdc5edbcd6d2e52dca8c8ed05b5b597782d08f 100644
--- a/packages/ledgerstate/reality.objectstorage.go
+++ b/packages/ledgerstate/reality.objectstorage.go
@@ -11,37 +11,33 @@ func (reality *Reality) GetStorageKey() []byte {
 }
 
 func (reality *Reality) Update(other objectstorage.StorableObject) {
-	reality.bookingMutex.Lock()
-
 	if otherReality, ok := other.(*Reality); !ok {
-		reality.bookingMutex.Unlock()
-
 		panic("Update method expects a *TransferOutputBooking")
 	} else {
-		reality.parentRealities = otherReality.parentRealities
+		reality.parentRealityIdsMutex.Lock()
+		reality.parentRealityIds = otherReality.parentRealityIds
+		reality.parentRealityIdsMutex.Unlock()
 	}
-
-	reality.bookingMutex.Unlock()
 }
 
 func (reality *Reality) MarshalBinary() ([]byte, error) {
-	reality.parentRealitiesMutex.RLock()
+	reality.parentRealityIdsMutex.RLock()
 
-	parentRealityCount := len(reality.parentRealities)
+	parentRealityCount := len(reality.parentRealityIds)
 
 	marshaledReality := make([]byte, 4+4+parentRealityCount*realityIdLength)
 
-	binary.LittleEndian.PutUint32(marshaledReality, uint32(reality.transferOutputCount))
+	binary.LittleEndian.PutUint32(marshaledReality, uint32(reality.GetTransferOutputCount()))
 
 	binary.LittleEndian.PutUint32(marshaledReality[4:], uint32(parentRealityCount))
 	i := 0
-	for parentRealityId := range reality.parentRealities {
+	for parentRealityId := range reality.parentRealityIds {
 		copy(marshaledReality[4+4+i*realityIdLength:], parentRealityId[:])
 
 		i++
 	}
 
-	reality.parentRealitiesMutex.RUnlock()
+	reality.parentRealityIdsMutex.RUnlock()
 
 	return marshaledReality, nil
 }
@@ -51,9 +47,9 @@ func (reality *Reality) UnmarshalBinary(serializedObject []byte) error {
 		return err
 	}
 
-	reality.parentRealities = make(map[RealityId]empty)
+	reality.parentRealityIds = NewRealityIdSet()
 
-	reality.transferOutputCount = int(binary.LittleEndian.Uint32(serializedObject))
+	reality.transferOutputCount = binary.LittleEndian.Uint32(serializedObject)
 
 	parentRealityCount := int(binary.LittleEndian.Uint32(serializedObject[4:]))
 	for i := 0; i < parentRealityCount; i++ {
@@ -62,7 +58,7 @@ func (reality *Reality) UnmarshalBinary(serializedObject []byte) error {
 			return err
 		}
 
-		reality.parentRealities[restoredRealityId] = void
+		reality.parentRealityIds[restoredRealityId] = void
 	}
 
 	return nil
diff --git a/packages/ledgerstate/reality_id_list.go b/packages/ledgerstate/reality_id_list.go
new file mode 100644
index 0000000000000000000000000000000000000000..1d6189cdf9aab39a2a9c121ef39ec5487db2fca0
--- /dev/null
+++ b/packages/ledgerstate/reality_id_list.go
@@ -0,0 +1,23 @@
+package ledgerstate
+
+type RealityIdList []RealityId
+
+func (realityIdList RealityIdList) Clone() (clone RealityIdList) {
+	clone = make(RealityIdList, len(realityIdList))
+
+	for key, value := range realityIdList {
+		clone[key] = value
+	}
+
+	return
+}
+
+func (realityIdList RealityIdList) ToSet() (set RealityIdSet) {
+	set = make(RealityIdSet)
+
+	for _, value := range realityIdList {
+		set[value] = void
+	}
+
+	return
+}
diff --git a/packages/ledgerstate/reality_id_set.go b/packages/ledgerstate/reality_id_set.go
new file mode 100644
index 0000000000000000000000000000000000000000..e202a3064895de39e666cb399e49b1209f96153d
--- /dev/null
+++ b/packages/ledgerstate/reality_id_set.go
@@ -0,0 +1,48 @@
+package ledgerstate
+
+type RealityIdSet map[RealityId]empty
+
+func NewRealityIdSet(realityIds ...RealityId) (realityIdSet RealityIdSet) {
+	realityIdSet = make(RealityIdSet)
+
+	for _, realityId := range realityIds {
+		realityIdSet[realityId] = void
+	}
+
+	return
+}
+
+func (realityIdSet RealityIdSet) Add(realityId RealityId) RealityIdSet {
+	realityIdSet[realityId] = void
+
+	return realityIdSet
+}
+
+func (realityIdSet RealityIdSet) Remove(realityId RealityId) RealityIdSet {
+	delete(realityIdSet, realityId)
+
+	return realityIdSet
+}
+
+func (realityIdSet RealityIdSet) Clone() (clone RealityIdSet) {
+	clone = make(RealityIdSet, len(realityIdSet))
+
+	for key := range realityIdSet {
+		clone[key] = void
+	}
+
+	return
+}
+
+func (realityIdSet RealityIdSet) ToList() (list RealityIdList) {
+	list = make(RealityIdList, len(realityIdSet))
+
+	i := 0
+	for key := range realityIdSet {
+		list[i] = key
+
+		i++
+	}
+
+	return
+}
diff --git a/packages/ledgerstate_old/address.go b/packages/ledgerstate_old/address.go
deleted file mode 100644
index 95d2750af1f26814fccb6fbf5bd6f21ec2174bc0..0000000000000000000000000000000000000000
--- a/packages/ledgerstate_old/address.go
+++ /dev/null
@@ -1,62 +0,0 @@
-package ledgerstate
-
-type AddressHash [addressHashLength]byte
-
-type Address struct {
-	ledgerState *LedgerState
-	realityId   RealityId
-	hash        AddressHash
-}
-
-func NewAddress(ledgerState *LedgerState, realityId RealityId, hash AddressHash) *Address {
-	return &Address{
-		ledgerState: ledgerState,
-		realityId:   realityId,
-		hash:        hash,
-	}
-}
-
-func (address *Address) GetHash() AddressHash {
-	return address.hash
-}
-
-func (address *Address) GetRealityId() RealityId {
-	return address.realityId
-}
-
-func (address *Address) GetReality() *Reality {
-	return address.ledgerState.GetReality(address.realityId)
-}
-
-func (address *Address) GetUnspentTransferOutputs() (unspentTransferOutputs []*TransferOutput) {
-	unspentTransferOutputs = make([]*TransferOutput, 0)
-
-	address.collectUnspentTransferOutputs(address.realityId, &unspentTransferOutputs)
-	for ancestorRealityId := range address.GetReality().GetAncestorRealities() {
-		address.collectUnspentTransferOutputs(ancestorRealityId, &unspentTransferOutputs)
-	}
-
-	return unspentTransferOutputs
-}
-
-func (address *Address) collectUnspentTransferOutputs(realityId RealityId, unspentTransferOutputs *[]*TransferOutput) {
-	address.ledgerState.ForEachTransferOutput(func(transferOutput *TransferOutput) {
-		*unspentTransferOutputs = append(*unspentTransferOutputs, transferOutput)
-	}, FilterRealities(realityId), FilterAddresses(address.hash), FilterUnspent())
-}
-
-func (address *Address) GetTransferOutputs() map[TransferHash]*TransferOutput {
-	return nil
-}
-
-func (address *Address) GetBalances() map[Color]uint64 {
-	balances := make(map[Color]uint64)
-
-	for _, unspentTransferOutput := range address.GetUnspentTransferOutputs() {
-		for colorHash, balance := range unspentTransferOutput.GetColoredBalances() {
-			balances[colorHash] += balance.GetValue()
-		}
-	}
-
-	return balances
-}
diff --git a/packages/ledgerstate_old/colored_balance.go b/packages/ledgerstate_old/colored_balance.go
deleted file mode 100644
index 71b690fade2f72afd1840268e872b43912f5797e..0000000000000000000000000000000000000000
--- a/packages/ledgerstate_old/colored_balance.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package ledgerstate
-
-import (
-	"strconv"
-)
-
-type Color string
-
-type ColoredBalance struct {
-	color   Color
-	balance uint64
-}
-
-func NewColoredBalance(color Color, balance uint64) *ColoredBalance {
-	return &ColoredBalance{
-		color:   color,
-		balance: balance,
-	}
-}
-
-func (balance *ColoredBalance) GetColor() Color {
-	return balance.color
-}
-
-func (balance *ColoredBalance) GetValue() uint64 {
-	return balance.balance
-}
-
-func (coloredBalance *ColoredBalance) String() string {
-	return "ColoredBalance(\"" + string(coloredBalance.color) + "\", " + strconv.FormatUint(coloredBalance.balance, 10) + ")"
-}
diff --git a/packages/ledgerstate_old/constants.go b/packages/ledgerstate_old/constants.go
deleted file mode 100644
index e2449f56654ddc7ef17dd2017612be4222a2c1ab..0000000000000000000000000000000000000000
--- a/packages/ledgerstate_old/constants.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package ledgerstate
-
-var (
-	MAIN_REALITY_ID = [realityIdLength]byte{}
-)
-
-const (
-	UNSPENT_SEPARATOR_BYTE = byte(0)
-	SPENT_SEPARATOR_BYTE   = byte(1)
-
-	transferHashLength = 32
-	addressHashLength  = 32
-	realityIdLength    = 32
-
-	marshalTransferOutputBookingRealityIdStart    = 0
-	marshalTransferOutputBookingRealityIdEnd      = marshalTransferOutputBookingRealityIdStart + realityIdLength
-	marshalTransferOutputBookingAddressHashStart  = marshalTransferOutputBookingRealityIdEnd
-	marshalTransferOutputBookingAddressHashEnd    = marshalTransferOutputBookingAddressHashStart + addressHashLength
-	marshalTransferOutputBookingSpentStart        = marshalTransferOutputBookingAddressHashEnd
-	marshalTransferOutputBookingSpentEnd          = marshalTransferOutputBookingSpentStart + 1
-	marshalTransferOutputBookingTransferHashStart = marshalTransferOutputBookingSpentEnd
-	marshalTransferOutputBookingTransferHashEnd   = marshalTransferOutputBookingTransferHashStart + transferHashLength
-	marshalTransferOutputBookingTotalLength       = marshalTransferOutputBookingTransferHashEnd
-)
diff --git a/packages/ledgerstate_old/errors.go b/packages/ledgerstate_old/errors.go
deleted file mode 100644
index c531dcb8f19ca8e49f99aa4577795ef4d520a261..0000000000000000000000000000000000000000
--- a/packages/ledgerstate_old/errors.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package ledgerstate
-
-import "github.com/iotaledger/goshimmer/packages/errors"
-
-var (
-	ErrInvalidTransfer = errors.New("invalid transfer")
-	ErrUnmarshalFailed = errors.New("unmarshal failed")
-)
diff --git a/packages/ledgerstate_old/ledgerstate.go b/packages/ledgerstate_old/ledgerstate.go
deleted file mode 100644
index 3c45d7346db6f7cef3f2f34ae25c7980c4cfc722..0000000000000000000000000000000000000000
--- a/packages/ledgerstate_old/ledgerstate.go
+++ /dev/null
@@ -1,242 +0,0 @@
-package ledgerstate
-
-import (
-	"github.com/iotaledger/goshimmer/packages/errors"
-	"github.com/iotaledger/goshimmer/packages/objectstorage"
-)
-
-// region LedgerState //////////////////////////////////////////////////////////////////////////////////////////////////
-
-type LedgerState struct {
-	storageId       []byte
-	transferOutputs TransferOutputStorage
-	realities       RealityStorage
-	options         *LedgerStateOptions
-}
-
-func NewLedgerState(storageId []byte, options ...LedgerStateOption) (result *LedgerState) {
-	ledgerStateOptions := DEFAULT_LEDGER_STATE_OPTIONS.Override(options...)
-
-	realityStorage := ledgerStateOptions.RealityStorageFactory(storageId)
-
-	result = &LedgerState{
-		storageId:       storageId,
-		options:         ledgerStateOptions,
-		transferOutputs: ledgerStateOptions.TransferOutputStorageFactory(storageId),
-		realities:       realityStorage,
-	}
-
-	newReality := newReality(result, MAIN_REALITY_ID)
-	if storeErr := realityStorage.StoreReality(newReality); storeErr != nil {
-		panic(storeErr)
-	}
-
-	return
-}
-
-func (ledgerState *LedgerState) AddTransferOutput(transferHash TransferHash, addressHash AddressHash, balances ...*ColoredBalance) *LedgerState {
-	if err := ledgerState.transferOutputs.StoreTransferOutput(NewTransferOutput(ledgerState, MAIN_REALITY_ID, addressHash, transferHash, balances...)); err != nil {
-		panic(err)
-	}
-
-	return ledgerState
-}
-
-func (ledgerState *LedgerState) AddTransferOutputOld(transferOutput *TransferOutput) *LedgerState {
-	if err := ledgerState.transferOutputs.StoreTransferOutput(transferOutput); err != nil {
-		panic(err)
-	}
-
-	return ledgerState
-}
-
-func (ledgerState *LedgerState) GetTransferOutput(transferOutputReference *TransferOutputReference) *objectstorage.CachedObject {
-	if transferOutput, err := ledgerState.transferOutputs.LoadTransferOutput(transferOutputReference.GetId()); err != nil {
-		panic(err)
-	} else {
-		return transferOutput
-	}
-}
-
-func (ledgerState *LedgerState) ForEachTransferOutput(callback func(transferOutput *TransferOutput), filter ...TransferOutputStorageFilter) {
-	ledgerState.transferOutputs.ForEach(callback, filter...)
-}
-
-func (ledgerState *LedgerState) BookTransfer(transfer *Transfer) errors.IdentifiableError {
-	if !transfer.IsValid(ledgerState) {
-		return ErrInvalidTransfer.Derive("balance of transfer is invalid")
-	}
-
-	realities := make([]RealityId, 0)
-	for _, input := range transfer.GetInputs() {
-		transferOutput := ledgerState.GetTransferOutput(input)
-		if transferOutput == nil {
-			return ErrInvalidTransfer.Derive("referenced transfer output doesn't exist")
-		}
-
-		realities = append(realities, transferOutput.GetRealityId())
-	}
-
-	aggregatedReality := ledgerState.MergeRealities(realities...)
-	if err := ledgerState.realities.StoreReality(aggregatedReality); err != nil {
-		return err
-	}
-
-	aggregatedReality.BookTransfer(transfer)
-	// determine the transferoutputs
-	// aggregate their realities
-	// persist reality
-	// book funds in this reality
-
-	return nil
-}
-
-func (ledgerState *LedgerState) CreateReality(realityId RealityId) *Reality {
-	if loadedReality, err := ledgerState.realities.LoadReality(realityId); err != nil {
-		panic(err)
-	} else if loadedReality != nil {
-		return loadedReality
-	} else {
-		newReality := newReality(ledgerState, realityId, MAIN_REALITY_ID)
-
-		if storeErr := ledgerState.realities.StoreReality(newReality); storeErr != nil {
-			panic(storeErr)
-		}
-
-		return newReality
-	}
-}
-
-func (ledgerState *LedgerState) GetReality(realityId RealityId) *Reality {
-	if loadedReality, loadedRealityErr := ledgerState.realities.LoadReality(realityId); loadedRealityErr != nil {
-		panic(loadedRealityErr)
-	} else {
-		return loadedReality
-	}
-}
-
-func (ledgerState *LedgerState) MergeRealities(realityIds ...RealityId) *Reality {
-	switch len(realityIds) {
-	case 0:
-		if loadedReality, loadedRealityErr := ledgerState.realities.LoadReality(MAIN_REALITY_ID); loadedRealityErr != nil {
-			panic(loadedRealityErr)
-		} else {
-			return loadedReality
-		}
-	case 1:
-		if loadedReality, loadedRealityErr := ledgerState.realities.LoadReality(realityIds[0]); loadedRealityErr != nil {
-			panic(loadedRealityErr)
-		} else {
-			return loadedReality
-		}
-	default:
-		aggregatedRealities := make(map[RealityId]*Reality)
-
-		for _, realityId := range realityIds {
-			if _, exists := aggregatedRealities[realityId]; exists {
-				continue
-			}
-
-			switchedRealities := make(map[RealityId]*Reality)
-			realityIncluded := false
-			for independentRealityId, independentReality := range aggregatedRealities {
-				if independentReality.DescendsFromReality(realityId) {
-					realityIncluded = true
-
-					break
-				} else {
-					if loadedReality, loadedRealityErr := ledgerState.realities.LoadReality(realityId); loadedRealityErr != nil {
-						panic(loadedRealityErr)
-					} else if loadedReality == nil {
-						return nil
-					} else if loadedReality.DescendsFromReality(independentRealityId) {
-						switchedRealities[independentRealityId] = loadedReality
-
-						realityIncluded = true
-
-						break
-					}
-				}
-			}
-			for oldId, newReality := range switchedRealities {
-				delete(aggregatedRealities, oldId)
-				aggregatedRealities[newReality.GetId()] = newReality
-			}
-			if realityIncluded {
-				continue
-			}
-
-			if loadedReality, loadedRealityErr := ledgerState.realities.LoadReality(realityId); loadedRealityErr != nil {
-				panic(loadedRealityErr)
-			} else {
-				aggregatedRealities[realityId] = loadedReality
-			}
-		}
-
-		if len(aggregatedRealities) == 1 {
-			for _, independentReality := range aggregatedRealities {
-				return independentReality
-			}
-		} else {
-			sortedRealityIds := make([]RealityId, len(aggregatedRealities))
-			counter := 0
-			for realityId := range aggregatedRealities {
-				sortedRealityIds[counter] = realityId
-
-				counter++
-			}
-			// TODO: CALCULATE REALITY ID INSTEAD OF MAIN_REALITY_ID
-			newReality := newReality(ledgerState, MAIN_REALITY_ID, sortedRealityIds...)
-
-			if storeErr := ledgerState.realities.StoreReality(newReality); storeErr != nil {
-				panic(storeErr)
-			}
-
-			return newReality
-		}
-
-		return nil
-	}
-}
-
-func (ledgerState *LedgerState) ForEachReality(callback func(reality *Reality), filter ...*TransferOutputStorageFilter) {
-}
-
-// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-// region LedgerStateOptions ///////////////////////////////////////////////////////////////////////////////////////////
-
-var DEFAULT_LEDGER_STATE_OPTIONS = &LedgerStateOptions{
-	TransferOutputStorageFactory: newTransferOutputStorageMemory,
-	RealityStorageFactory:        newRealityStorageMemory,
-}
-
-func OptionTransferOutputStorageFactory(factory TransferOutputStorageFactory) LedgerStateOption {
-	return func(args *LedgerStateOptions) {
-		args.TransferOutputStorageFactory = factory
-	}
-}
-
-func OptionStorageFactory(factory RealityStorageFactory) LedgerStateOption {
-	return func(args *LedgerStateOptions) {
-		args.RealityStorageFactory = factory
-	}
-}
-
-type LedgerStateOptions struct {
-	TransferOutputStorageFactory TransferOutputStorageFactory
-	RealityStorageFactory        RealityStorageFactory
-}
-
-func (options LedgerStateOptions) Override(optionalOptions ...LedgerStateOption) *LedgerStateOptions {
-	result := &options
-	for _, option := range optionalOptions {
-		option(result)
-	}
-
-	return result
-}
-
-type LedgerStateOption func(*LedgerStateOptions)
-
-// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/packages/ledgerstate_old/ledgerstate_test.go b/packages/ledgerstate_old/ledgerstate_test.go
deleted file mode 100644
index 94f2da1ec7fe38e686555aaf257230633e685a0f..0000000000000000000000000000000000000000
--- a/packages/ledgerstate_old/ledgerstate_test.go
+++ /dev/null
@@ -1,103 +0,0 @@
-package ledgerstate
-
-import (
-	"testing"
-)
-
-func Benchmark(b *testing.B) {
-	address1 := NewAddressHash("ADDRESS1")
-	address2 := NewAddressHash("ADDRESS2")
-	address3 := NewAddressHash("ADDRESS3")
-	transfer1 := NewTransferHash("TRANSFER1")
-	transfer2 := NewTransferHash("TRANSFER2")
-
-	ledgerState := NewLedgerState([]byte("TESTLEDGER"))
-
-	ledgerState.AddTransferOutputOld(
-		NewTransferOutput(ledgerState, MAIN_REALITY_ID, address1, transfer1, NewColoredBalance("RED", 1337), NewColoredBalance("IOTA", 1338)),
-	)
-
-	b.ResetTimer()
-
-	for i := 0; i < b.N; i++ {
-		transfer := NewTransfer(transfer2).AddInput(
-			NewTransferOutputReferenceOld(MAIN_REALITY_ID, address1, transfer1),
-		).AddOutput(
-			address2, NewColoredBalance("IOTA", 338),
-		).AddOutput(
-			address2, NewColoredBalance("RED", 337),
-		).AddOutput(
-			address3, NewColoredBalance("IOTA", 1000),
-		).AddOutput(
-			address3, NewColoredBalance("RED", 1000),
-		)
-
-		if err := ledgerState.BookTransfer(transfer); err != nil {
-			panic(err)
-		}
-	}
-}
-
-func NewAddressHash(input string) (result AddressHash) {
-	copy(result[:], input)
-	return
-}
-
-func NewRealityId(input string) (result RealityId) {
-	copy(result[:], input)
-	return
-}
-
-func NewTransferHash(input string) (result TransferHash) {
-	copy(result[:], input)
-	return
-}
-
-func Test(t *testing.T) {
-	//pendingReality := NewRealityId("PENDING")
-	address1 := NewAddressHash("ADDRESS1")
-	//address2 := NewAddressHash("ADDRESS2")
-	//address3 := NewAddressHash("ADDRESS3")
-	//address4 := NewAddressHash("ADDRESS4")
-	transfer1 := NewTransferHash("TRANSFER1")
-	//transfer2 := NewTransferHash("TRANSFER2")
-	//transfer3 := NewTransferHash("TRANSFER3")
-
-	ledgerState := NewLedgerState([]byte("TESTLEDGER"))
-
-	ledgerState.AddTransferOutput(transfer1, address1, NewColoredBalance("RED", 1337), NewColoredBalance("IOTA", 1338))
-	ledgerState.GetTransferOutput(NewTransferOutputReference(transfer1, address1))
-
-	/*
-		ledgerState.CreateReality(pendingReality)
-
-		ledgerState.AddTransferOutputOld(
-			NewTransferOutput(ledgerState, MAIN_REALITY_ID, address1, transfer1, NewColoredBalance("RED", 1337), NewColoredBalance("IOTA", 1338)),
-		).AddTransferOutputOld(
-			NewTransferOutput(ledgerState, pendingReality, address1, transfer1, NewColoredBalance("RED", 7331), NewColoredBalance("IOTA", 8331)),
-		).AddTransferOutputOld(
-			NewTransferOutput(ledgerState, pendingReality, address2, transfer2, NewColoredBalance("RED", 7331), NewColoredBalance("IOTA", 8331)),
-		)
-
-		fmt.Println(ledgerState.GetReality(pendingReality).GetAddress(address1).GetUnspentTransferOutputs())
-
-		transfer := NewTransfer(transfer3).AddInput(
-			NewTransferOutputReferenceOld(MAIN_REALITY_ID, address1, transfer1),
-		).AddOutput(
-			address3, NewColoredBalance("IOTA", 338),
-		).AddOutput(
-			address3, NewColoredBalance("RED", 337),
-		).AddOutput(
-			address4, NewColoredBalance("IOTA", 1000),
-		).AddOutput(
-			address4, NewColoredBalance("RED", 1000),
-		)
-
-		if err := ledgerState.BookTransfer(transfer); err != nil {
-			t.Error(err)
-		}
-
-		fmt.Println(ledgerState.GetReality(MAIN_REALITY_ID).GetAddress(address3).GetBalances())
-		fmt.Println(ledgerState.GetReality(MAIN_REALITY_ID).GetAddress(address4).GetBalances())
-	*/
-}
diff --git a/packages/ledgerstate_old/reality.go b/packages/ledgerstate_old/reality.go
deleted file mode 100644
index 12b756cb730f5c5b431ec3feed29715ed1d5fef8..0000000000000000000000000000000000000000
--- a/packages/ledgerstate_old/reality.go
+++ /dev/null
@@ -1,94 +0,0 @@
-package ledgerstate
-
-import (
-	"github.com/iotaledger/goshimmer/packages/errors"
-)
-
-type RealityId [realityIdLength]byte
-
-type Reality struct {
-	ledgerState      *LedgerState
-	id               RealityId
-	parentRealityIds []RealityId
-	parentRealities  map[RealityId]*Reality
-}
-
-func newReality(ledgerState *LedgerState, id RealityId, parentRealityIds ...RealityId) *Reality {
-	return &Reality{
-		ledgerState:      ledgerState,
-		id:               id,
-		parentRealityIds: parentRealityIds,
-	}
-}
-
-func (reality *Reality) SetLedgerState(ledgerState *LedgerState) {
-	reality.ledgerState = ledgerState
-}
-
-func (reality *Reality) GetId() RealityId {
-	return reality.id
-}
-
-func (reality *Reality) GetParentRealityIds() []RealityId {
-	return reality.parentRealityIds
-}
-
-func (reality *Reality) GetAddress(addressHash AddressHash) *Address {
-	return NewAddress(reality.ledgerState, reality.id, addressHash)
-}
-
-func (reality *Reality) GetParentRealities() map[RealityId]*Reality {
-	if reality.parentRealities == nil {
-		parentRealities := make(map[RealityId]*Reality)
-		for _, parentRealityId := range reality.parentRealityIds {
-			if loadedParentReality := reality.ledgerState.GetReality(parentRealityId); loadedParentReality == nil {
-				panic("could not load parent reality " + string(parentRealityId[:]))
-			} else {
-				parentRealities[loadedParentReality.GetId()] = loadedParentReality
-			}
-		}
-		reality.parentRealities = parentRealities
-	}
-
-	return reality.parentRealities
-}
-
-func (reality *Reality) GetAncestorRealities() (result map[RealityId]*Reality) {
-	result = make(map[RealityId]*Reality, 1)
-
-	for _, parentReality := range reality.GetParentRealities() {
-		result[parentReality.GetId()] = reality
-
-		for _, ancestor := range parentReality.GetAncestorRealities() {
-			result[ancestor.GetId()] = ancestor
-		}
-	}
-
-	return
-}
-
-func (reality *Reality) DescendsFromReality(realityId RealityId) bool {
-	if reality.id == realityId {
-		return true
-	} else {
-		_, exists := reality.GetAncestorRealities()[realityId]
-
-		return exists
-	}
-}
-
-func (reality *Reality) BookTransfer(transfer *Transfer) errors.IdentifiableError {
-	// process outputs
-	for addressHash, transferOutput := range transfer.GetOutputs() {
-		for _, coloredBalance := range transferOutput {
-			createdTransferOutput := NewTransferOutput(reality.ledgerState, reality.id, addressHash, transfer.GetHash(), coloredBalance)
-			reality.ledgerState.AddTransferOutputOld(createdTransferOutput)
-		}
-	}
-
-	return nil
-}
-
-func (reality *Reality) Exists() bool {
-	return reality != nil
-}
diff --git a/packages/ledgerstate_old/reality_storage.go b/packages/ledgerstate_old/reality_storage.go
deleted file mode 100644
index b32429e16e3de5a1b60fe7799b03ef7166a7a909..0000000000000000000000000000000000000000
--- a/packages/ledgerstate_old/reality_storage.go
+++ /dev/null
@@ -1,49 +0,0 @@
-package ledgerstate
-
-import (
-	"sync"
-
-	"github.com/iotaledger/goshimmer/packages/errors"
-)
-
-type RealityStorage interface {
-	LoadReality(realityId RealityId) (result *Reality, err errors.IdentifiableError)
-	StoreReality(reality *Reality) (err errors.IdentifiableError)
-}
-
-type RealityStorageFactory func(id []byte) RealityStorage
-
-type RealityStorageMemory struct {
-	id        []byte
-	realities map[RealityId]*Reality
-	mutex     sync.RWMutex
-}
-
-var _ RealityStorage = &RealityStorageMemory{}
-
-func newRealityStorageMemory(id []byte) RealityStorage {
-	return &RealityStorageMemory{
-		id:        id,
-		realities: make(map[RealityId]*Reality),
-	}
-}
-
-func (storage *RealityStorageMemory) StoreReality(reality *Reality) (err errors.IdentifiableError) {
-	storage.mutex.Lock()
-
-	storage.realities[reality.GetId()] = reality
-
-	storage.mutex.Unlock()
-
-	return
-}
-
-func (storage *RealityStorageMemory) LoadReality(realityId RealityId) (result *Reality, err errors.IdentifiableError) {
-	storage.mutex.RLock()
-
-	result = storage.realities[realityId]
-
-	storage.mutex.RUnlock()
-
-	return
-}
diff --git a/packages/ledgerstate_old/transfer.go b/packages/ledgerstate_old/transfer.go
deleted file mode 100644
index f38d3a6e10ba71e9270c3d8772f8bdbdee697564..0000000000000000000000000000000000000000
--- a/packages/ledgerstate_old/transfer.go
+++ /dev/null
@@ -1,77 +0,0 @@
-package ledgerstate
-
-type TransferHash [transferHashLength]byte
-
-type Transfer struct {
-	hash    TransferHash
-	inputs  []*TransferOutputReferenceOld
-	outputs map[AddressHash]map[Color]*ColoredBalance
-}
-
-func NewTransfer(transferHash TransferHash) *Transfer {
-	return &Transfer{
-		hash:    transferHash,
-		inputs:  make([]*TransferOutputReferenceOld, 0),
-		outputs: make(map[AddressHash]map[Color]*ColoredBalance),
-	}
-}
-
-func (transfer *Transfer) GetHash() TransferHash {
-	return transfer.hash
-}
-
-func (transfer *Transfer) IsValid(ledgerState *LedgerState) bool {
-	totalColoredBalances := make(map[Color]uint64)
-
-	// process inputs
-	for _, transferOutputReference := range transfer.inputs {
-		if transferOutput := ledgerState.GetTransferOutput(transferOutputReference); transferOutput == nil {
-			return false
-		} else {
-			for colorHash, coloredBalance := range transferOutput.GetColoredBalances() {
-				totalColoredBalances[colorHash] += coloredBalance.GetValue()
-			}
-		}
-	}
-
-	// process outputs
-	for _, transferOutput := range transfer.outputs {
-		for colorHash, coloredBalance := range transferOutput {
-			totalColoredBalances[colorHash] -= coloredBalance.GetValue()
-
-			if totalColoredBalances[colorHash] == 0 {
-				delete(totalColoredBalances, colorHash)
-			}
-		}
-	}
-
-	// transfer is valid if sum of funds is 0
-	return len(totalColoredBalances) == 0
-}
-
-func (transfer *Transfer) AddInput(input *TransferOutputReferenceOld) *Transfer {
-	transfer.inputs = append(transfer.inputs, input)
-
-	return transfer
-}
-
-func (transfer *Transfer) GetInputs() []*TransferOutputReferenceOld {
-	return transfer.inputs
-}
-
-func (transfer *Transfer) AddOutput(address AddressHash, balance *ColoredBalance) *Transfer {
-	addressEntry, addressExists := transfer.outputs[address]
-	if !addressExists {
-		addressEntry = make(map[Color]*ColoredBalance)
-
-		transfer.outputs[address] = addressEntry
-	}
-
-	addressEntry[balance.GetColor()] = balance
-
-	return transfer
-}
-
-func (transfer *Transfer) GetOutputs() map[AddressHash]map[Color]*ColoredBalance {
-	return transfer.outputs
-}
diff --git a/packages/ledgerstate_old/transfer_output.go b/packages/ledgerstate_old/transfer_output.go
deleted file mode 100644
index b59af031d13f68524ba4c6e2f1176cc66e17bc48..0000000000000000000000000000000000000000
--- a/packages/ledgerstate_old/transfer_output.go
+++ /dev/null
@@ -1,97 +0,0 @@
-package ledgerstate
-
-import (
-	"github.com/iotaledger/goshimmer/packages/objectstorage"
-)
-
-// region TransferOutput ///////////////////////////////////////////////////////////////////////////////////////////////
-
-type TransferOutput struct {
-	ledgerState     *LedgerState
-	realityId       RealityId
-	addressHash     AddressHash
-	transferHash    TransferHash
-	coloredBalances map[Color]*ColoredBalance
-	consumers       []TransferHash
-}
-
-func NewTransferOutput(ledgerState *LedgerState, realityId RealityId, addressHash AddressHash, transferHash TransferHash, coloredBalances ...*ColoredBalance) (result *TransferOutput) {
-	result = &TransferOutput{
-		ledgerState:     ledgerState,
-		addressHash:     addressHash,
-		transferHash:    transferHash,
-		coloredBalances: make(map[Color]*ColoredBalance),
-		realityId:       realityId,
-		consumers:       make([]TransferHash, 0),
-	}
-
-	for _, balance := range coloredBalances {
-		result.coloredBalances[balance.GetColor()] = balance
-	}
-
-	return
-}
-
-func (transferOutput *TransferOutput) GetId() []byte {
-	return nil
-}
-
-func (transferOutput *TransferOutput) Update(otherObject objectstorage.StorableObject) {
-	if otherTransferOutput, ok := otherObject.(*TransferOutput); !ok {
-		panic("Update expects the passed in object to be a valid *TransferOutput")
-	} else {
-		transferOutput.realityId = otherTransferOutput.realityId
-	}
-}
-
-func (transferOutput *TransferOutput) Marshal() ([]byte, error) {
-	return nil, nil
-}
-func (transferOutput *TransferOutput) Unmarshal(key []byte, serializedObject []byte) (objectstorage.StorableObject, error) {
-	return &TransferOutput{}, nil
-}
-
-func (transferOutput *TransferOutput) GetRealityId() RealityId {
-	return transferOutput.realityId
-}
-
-func (transferOutput *TransferOutput) GetReality(realityId RealityId) *Reality {
-	return transferOutput.ledgerState.GetReality(realityId)
-}
-
-func (transferOutput *TransferOutput) GetAddressHash() AddressHash {
-	return transferOutput.addressHash
-}
-
-func (transferOutput *TransferOutput) GetTransferHash() TransferHash {
-	return transferOutput.transferHash
-}
-
-func (transferOutput *TransferOutput) GetColoredBalances() map[Color]*ColoredBalance {
-	return transferOutput.coloredBalances
-}
-
-func (transferOutput *TransferOutput) GetConsumers() []TransferHash {
-	return transferOutput.consumers
-}
-
-func (transferOutput *TransferOutput) Exists() bool {
-	return transferOutput != nil
-}
-
-func (transferOutput *TransferOutput) String() (result string) {
-	result = "TransferOutput {\n"
-	result += "    RealityHash:  \"" + string(transferOutput.realityId[:]) + "\",\n"
-	result += "    AddressHash:  \"" + string(transferOutput.addressHash[:]) + "\",\n"
-	result += "    TransferHash: \"" + string(transferOutput.transferHash[:]) + "\",\n"
-
-	for _, coloredBalance := range transferOutput.coloredBalances {
-		result += "    " + coloredBalance.String() + ",\n"
-	}
-
-	result += "}"
-
-	return
-}
-
-// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/packages/ledgerstate_old/transfer_output_booking.go b/packages/ledgerstate_old/transfer_output_booking.go
deleted file mode 100644
index 22a77fda3301520e9e936013afc07235be8aca5d..0000000000000000000000000000000000000000
--- a/packages/ledgerstate_old/transfer_output_booking.go
+++ /dev/null
@@ -1,108 +0,0 @@
-package ledgerstate
-
-import (
-	"github.com/iotaledger/goshimmer/packages/objectstorage"
-)
-
-// region struct + constructor + public api ////////////////////////////////////////////////////////////////////////////
-
-type TransferOutputBooking struct {
-	id           [marshalTransferOutputBookingTotalLength]byte
-	realityId    RealityId
-	addressHash  AddressHash
-	spent        bool
-	transferHash TransferHash
-}
-
-func newTransferOutputBooking(realityId RealityId, addressHash AddressHash, spent bool, transferHash TransferHash) (result *TransferOutputBooking) {
-	result = &TransferOutputBooking{
-		realityId:    realityId,
-		addressHash:  addressHash,
-		spent:        spent,
-		transferHash: transferHash,
-	}
-
-	result.buildId()
-
-	return
-}
-
-func (booking *TransferOutputBooking) GetRealityId() RealityId {
-	return booking.realityId
-}
-
-func (booking *TransferOutputBooking) GetAddressHash() AddressHash {
-	return booking.addressHash
-}
-
-func (booking *TransferOutputBooking) IsSpent() bool {
-	return booking.spent
-}
-
-func (booking *TransferOutputBooking) GetTransferHash() TransferHash {
-	return booking.transferHash
-}
-
-// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-// region support object storage ///////////////////////////////////////////////////////////////////////////////////////
-
-func (booking *TransferOutputBooking) GetId() []byte {
-	return booking.id[:]
-}
-
-func (booking *TransferOutputBooking) Update(other objectstorage.StorableObject) {
-	if otherBooking, ok := other.(*TransferOutputBooking); !ok {
-		panic("Update method expects a *TransferOutputBooking")
-	} else {
-		booking.realityId = otherBooking.realityId
-		booking.addressHash = otherBooking.addressHash
-		booking.spent = otherBooking.spent
-		booking.transferHash = otherBooking.transferHash
-	}
-}
-
-func (booking *TransferOutputBooking) Marshal() ([]byte, error) {
-	return []byte{}, nil
-}
-
-func (booking *TransferOutputBooking) Unmarshal(key []byte, serializedObject []byte) (objectstorage.StorableObject, error) {
-	if len(key) < marshalTransferOutputBookingTotalLength {
-		return nil, ErrUnmarshalFailed.Derive("unmarshal failed: the length of the key is to short")
-	}
-
-	result := &TransferOutputBooking{}
-
-	copy(result.realityId[:], key[marshalTransferOutputBookingRealityIdStart:marshalTransferOutputBookingRealityIdEnd])
-	copy(result.addressHash[:], key[marshalTransferOutputBookingAddressHashStart:marshalTransferOutputBookingAddressHashEnd])
-	switch key[marshalTransferOutputBookingSpentStart] {
-	case UNSPENT_SEPARATOR_BYTE:
-		result.spent = false
-	case SPENT_SEPARATOR_BYTE:
-		result.spent = true
-	default:
-		return nil, ErrUnmarshalFailed.Derive("unmarshal failed: invalid spent separator in key")
-	}
-	copy(result.transferHash[:], key[marshalTransferOutputBookingTransferHashStart:marshalTransferOutputBookingTransferHashEnd])
-
-	result.buildId()
-
-	return result, nil
-}
-
-// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-// region private utility methods //////////////////////////////////////////////////////////////////////////////////////
-
-func (booking *TransferOutputBooking) buildId() {
-	copy(booking.id[marshalTransferOutputBookingRealityIdStart:marshalTransferOutputBookingRealityIdEnd], booking.realityId[:realityIdLength])
-	copy(booking.id[marshalTransferOutputBookingAddressHashStart:marshalTransferOutputBookingAddressHashEnd], booking.addressHash[:addressHashLength])
-	if booking.spent {
-		booking.id[marshalTransferOutputBookingSpentStart] = SPENT_SEPARATOR_BYTE
-	} else {
-		booking.id[marshalTransferOutputBookingSpentStart] = UNSPENT_SEPARATOR_BYTE
-	}
-	copy(booking.id[marshalTransferOutputBookingTransferHashStart:marshalTransferOutputBookingTransferHashEnd], booking.addressHash[:transferHashLength])
-}
-
-// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/packages/ledgerstate_old/transfer_output_reference.go b/packages/ledgerstate_old/transfer_output_reference.go
deleted file mode 100644
index 7b048d6b10cdedb7114c80d11b1d202718584a93..0000000000000000000000000000000000000000
--- a/packages/ledgerstate_old/transfer_output_reference.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package ledgerstate
-
-type TransferOutputReference struct {
-	id           [transferHashLength + addressHashLength]byte
-	transferHash TransferHash
-	addressHash  AddressHash
-}
-
-func NewTransferOutputReference(transferHash TransferHash, addressHash AddressHash) (result *TransferOutputReference) {
-	result = &TransferOutputReference{
-		transferHash: transferHash,
-		addressHash:  addressHash,
-	}
-
-	copy(result.id[0:], transferHash[:transferHashLength])
-	copy(result.id[transferHashLength:], addressHash[:addressHashLength])
-
-	return
-}
-
-func (reference *TransferOutputReference) GetId() []byte {
-	return reference.id[:]
-}
-
-func (reference *TransferOutputReference) GetTransferHash() TransferHash {
-	return reference.transferHash
-}
-
-func (reference *TransferOutputReference) GetAddressHash() AddressHash {
-	return reference.addressHash
-}
diff --git a/packages/ledgerstate_old/transfer_output_reference_old.go b/packages/ledgerstate_old/transfer_output_reference_old.go
deleted file mode 100644
index 508f26e0849ad325e5fec4f046fe9f7185be05cb..0000000000000000000000000000000000000000
--- a/packages/ledgerstate_old/transfer_output_reference_old.go
+++ /dev/null
@@ -1,27 +0,0 @@
-package ledgerstate
-
-type TransferOutputReferenceOld struct {
-	realityId    RealityId
-	addressHash  AddressHash
-	transferHash TransferHash
-}
-
-func NewTransferOutputReferenceOld(realityId RealityId, addressHash AddressHash, transferHash TransferHash) *TransferOutputReferenceOld {
-	return &TransferOutputReferenceOld{
-		realityId:    realityId,
-		addressHash:  addressHash,
-		transferHash: transferHash,
-	}
-}
-
-func (reference *TransferOutputReferenceOld) GetRealityId() RealityId {
-	return reference.realityId
-}
-
-func (reference *TransferOutputReferenceOld) GetAddressHash() AddressHash {
-	return reference.addressHash
-}
-
-func (reference *TransferOutputReferenceOld) GetTransferHash() TransferHash {
-	return reference.transferHash
-}
diff --git a/packages/ledgerstate_old/transfer_output_storage.go b/packages/ledgerstate_old/transfer_output_storage.go
deleted file mode 100644
index 0187dc67ec0770990d21b4e14afc3c8aa88000e3..0000000000000000000000000000000000000000
--- a/packages/ledgerstate_old/transfer_output_storage.go
+++ /dev/null
@@ -1,195 +0,0 @@
-package ledgerstate
-
-import (
-	"sync"
-
-	"github.com/iotaledger/goshimmer/packages/objectstorage"
-
-	"github.com/iotaledger/goshimmer/packages/errors"
-)
-
-// region TransferOutputStorage ////////////////////////////////////////////////////////////////////////////////////////
-
-type TransferOutputStorage interface {
-	LoadTransferOutput(transferOutputReference *TransferOutputReferenceOld) (result *TransferOutput, err errors.IdentifiableError)
-	StoreTransferOutput(transferOutput *TransferOutput) (err errors.IdentifiableError)
-	ForEach(callback func(transferOutput *TransferOutput), filters ...TransferOutputStorageFilter)
-}
-
-type TransferOutputStorageFactory func(id []byte) TransferOutputStorage
-
-// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-// region TransferOutputStorageFilters /////////////////////////////////////////////////////////////////////////////////
-
-type TransferOutputStorageFilters struct {
-	FilterUnspent bool
-	FilterSpent   bool
-	Realities     map[RealityId]bool
-	Addresses     map[AddressHash]bool
-}
-
-func newTransportOutputStorageFilters(optionalFilters ...TransferOutputStorageFilter) *TransferOutputStorageFilters {
-	result := &TransferOutputStorageFilters{
-		FilterUnspent: false,
-		FilterSpent:   false,
-		Realities:     make(map[RealityId]bool),
-		Addresses:     make(map[AddressHash]bool),
-	}
-
-	for _, optionalFilter := range optionalFilters {
-		optionalFilter(result)
-	}
-
-	return result
-}
-
-type TransferOutputStorageFilter func(*TransferOutputStorageFilters)
-
-func FilterSpent() TransferOutputStorageFilter {
-	return func(args *TransferOutputStorageFilters) {
-		args.FilterSpent = true
-	}
-}
-
-func FilterUnspent() TransferOutputStorageFilter {
-	return func(args *TransferOutputStorageFilters) {
-		args.FilterUnspent = true
-	}
-}
-
-func FilterRealities(realities ...RealityId) TransferOutputStorageFilter {
-	return func(args *TransferOutputStorageFilters) {
-		for _, reality := range realities {
-			args.Realities[reality] = true
-		}
-	}
-}
-
-func FilterAddresses(addresses ...AddressHash) TransferOutputStorageFilter {
-	return func(args *TransferOutputStorageFilters) {
-		for _, reality := range addresses {
-			args.Addresses[reality] = true
-		}
-	}
-}
-
-// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-// region TransportOutputStorageMemory /////////////////////////////////////////////////////////////////////////////////
-
-type TransferOutputStorageMemory struct {
-	id []byte
-	// the actual transfer outputs (prefixed by reality, address, spent/unspent, transfer hash)
-	transferOutputs        *objectstorage.ObjectStorage
-	transferOutputBookings *objectstorage.ObjectStorage
-
-	unspentTransferOutputsOld map[RealityId]map[AddressHash]map[TransferHash]bool
-	spentTransferOutputsOld   map[RealityId]map[AddressHash]map[TransferHash]bool
-	transferOutputsOld        map[AddressHash]map[TransferHash]*TransferOutput
-	mutex                     sync.RWMutex
-}
-
-func newTransferOutputStorageMemory(id []byte) TransferOutputStorage {
-	return &TransferOutputStorageMemory{
-		id:                     id,
-		transferOutputs:        objectstorage.New(string(id)+"TRANSFER_OUTPUTS", &TransferOutput{}),
-		transferOutputBookings: objectstorage.New(string(id)+"TRANSFER_OUTPUT_REFERENCES", &TransferOutputBooking{}),
-
-		unspentTransferOutputsOld: make(map[RealityId]map[AddressHash]map[TransferHash]bool),
-		spentTransferOutputsOld:   make(map[RealityId]map[AddressHash]map[TransferHash]bool),
-		transferOutputsOld:        make(map[AddressHash]map[TransferHash]*TransferOutput),
-	}
-}
-
-func (transferOutputStorage *TransferOutputStorageMemory) StoreTransferOutput(transferOutput *TransferOutput) (err errors.IdentifiableError) {
-	transferOutputStorage.transferOutputs.Store(transferOutput).Release()
-	transferOutputStorage.mutex.Lock()
-
-	var targetList map[RealityId]map[AddressHash]map[TransferHash]bool
-	if len(transferOutput.GetConsumers()) >= 1 {
-		targetList = transferOutputStorage.spentTransferOutputsOld
-	} else {
-		targetList = transferOutputStorage.unspentTransferOutputsOld
-	}
-
-	reality, realityExists := targetList[transferOutput.GetRealityId()]
-	if !realityExists {
-		reality = make(map[AddressHash]map[TransferHash]bool)
-
-		targetList[transferOutput.GetRealityId()] = reality
-	}
-
-	address, addressExists := reality[transferOutput.GetAddressHash()]
-	if !addressExists {
-		address = make(map[TransferHash]bool)
-
-		reality[transferOutput.GetAddressHash()] = address
-	}
-
-	address[transferOutput.GetTransferHash()] = true
-
-	transferOutputStorage.mutex.Unlock()
-
-	return
-}
-
-func (transferOutputStorage *TransferOutputStorageMemory) LoadTransferOutput(transferOutputReference *TransferOutputReferenceOld) (result *TransferOutput, err errors.IdentifiableError) {
-	if cachedTransferOutput, loadErr := transferOutputStorage.transferOutputs.Load([]byte{1, 2}[:]); loadErr != nil {
-		err = ErrInvalidTransfer.Derive(loadErr.Error())
-	} else if cachedTransferOutput.Exists() {
-		result = cachedTransferOutput.Get().(*TransferOutput)
-
-		cachedTransferOutput.Release()
-	}
-
-	return
-}
-
-func (transferOutputStorage *TransferOutputStorageMemory) IterateRealities(realities map[RealityId]map[AddressHash]map[TransferHash]*TransferOutput, filter *TransferOutputStorageFilters, callback func(transferOutput *TransferOutput)) {
-	if len(filter.Realities) >= 1 {
-		for realityId := range filter.Realities {
-			if reality, realityExists := realities[realityId]; realityExists {
-				transferOutputStorage.IterateAddresses(reality, filter, callback)
-			}
-		}
-	} else {
-		for _, reality := range realities {
-			transferOutputStorage.IterateAddresses(reality, filter, callback)
-		}
-	}
-}
-
-func (transferOutputStorage *TransferOutputStorageMemory) IterateAddresses(addresses map[AddressHash]map[TransferHash]*TransferOutput, filter *TransferOutputStorageFilters, callback func(transferOutput *TransferOutput)) {
-	if len(filter.Addresses) >= 1 {
-		for addressHash := range filter.Addresses {
-			if address, addressExists := addresses[addressHash]; addressExists {
-				transferOutputStorage.IterateTransferOutputs(address, filter, callback)
-			}
-		}
-	} else {
-		for _, address := range addresses {
-			transferOutputStorage.IterateTransferOutputs(address, filter, callback)
-		}
-	}
-}
-
-func (transferOutputStorage *TransferOutputStorageMemory) IterateTransferOutputs(transferOutputs map[TransferHash]*TransferOutput, filter *TransferOutputStorageFilters, callback func(transferOutput *TransferOutput)) {
-	for _, transferOutput := range transferOutputs {
-		callback(transferOutput)
-	}
-}
-
-func (transferOutputStorage *TransferOutputStorageMemory) ForEach(callback func(transferOutput *TransferOutput), filters ...TransferOutputStorageFilter) {
-	//filter := newTransportOutputStorageFilters(filters...)
-
-	/*
-		if filter.FilterUnspent || !filter.FilterUnspent && !filter.FilterSpent {
-			transferOutputStorage.IterateRealities(transferOutputStorage.unspentTransferOutputsOld, filter, callback)
-		}
-		if filter.FilterUnspent || !filter.FilterUnspent && !filter.FilterSpent {
-			transferOutputStorage.IterateRealities(transferOutputStorage.spentTransferOutputsOld, filter, callback)
-		}*/
-}
-
-// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////