diff --git a/node/Node.cpp b/node/Node.cpp
index e77a977eb..1661e9d1a 100644
--- a/node/Node.cpp
+++ b/node/Node.cpp
@@ -59,7 +59,8 @@ Node::Node(
 	ZT1_VirtualNetworkConfigFunction virtualNetworkConfigFunction,
 	ZT1_EventCallback eventCallback,
 	const char *overrideRootTopology) :
-	RR(new RuntimeEnvironment(this)),
+	_RR(this),
+	RR(&_RR),
 	_uPtr(uptr),
 	_dataStoreGetFunction(dataStoreGetFunction),
 	_dataStorePutFunction(dataStorePutFunction),
@@ -86,19 +87,18 @@ Node::Node(
 		TRACE("identity.secret not found, generating...");
 		RR->identity.generate();
 		idtmp = RR->identity.toString(true);
-		if (!dataStorePut("identity.secret",idtmp,true)) {
-			delete RR;
+		if (!dataStorePut("identity.secret",idtmp,true))
 			throw std::runtime_error("unable to write identity.secret");
-		}
-		idtmp = RR->identity.toString(false);
-		if (!dataStorePut("identity.public",idtmp,false)) {
-			delete RR;
-			throw std::runtime_error("unable to write identity.public");
-		}
 	}
 	RR->publicIdentityStr = RR->identity.toString(false);
 	RR->secretIdentityStr = RR->identity.toString(true);
 
+	idtmp = dataStoreGet("identity.public");
+	if (idtmp != RR->publicIdentityStr) {
+		if (!dataStorePut("identity.public",RR->publicIdentityStr,false))
+			throw std::runtime_error("unable to write identity.public");
+	}
+
 	try {
 		RR->prng = new CMWC4096();
 		RR->sw = new Switch(RR);
@@ -113,7 +113,6 @@ Node::Node(
 		delete RR->mc;
 		delete RR->sw;
 		delete RR->prng;
-		delete RR;
 		throw;
 	}
 
@@ -138,14 +137,13 @@ Node::Node(
 Node::~Node()
 {
 	Mutex::Lock _l(_networks_m);
-	_networks.clear(); // delete these before we delete RR
+	_networks.clear();
 	delete RR->sa;
 	delete RR->topology;
 	delete RR->antiRec;
 	delete RR->mc;
 	delete RR->sw;
 	delete RR->prng;
-	delete RR;
 }
 
 ZT1_ResultCode Node::processWirePacket(
diff --git a/node/Node.hpp b/node/Node.hpp
index 396e04c0f..70531bf85 100644
--- a/node/Node.hpp
+++ b/node/Node.hpp
@@ -38,6 +38,7 @@
 
 #include "../include/ZeroTierOne.h"
 
+#include "RuntimeEnvironment.hpp"
 #include "InetAddress.hpp"
 #include "Mutex.hpp"
 #include "MAC.hpp"
@@ -52,8 +53,6 @@
 
 namespace ZeroTier {
 
-class RuntimeEnvironment;
-
 /**
  * Implementation of Node object as defined in CAPI
  *
@@ -229,6 +228,7 @@ public:
 #endif
 
 private:
+	RuntimeEnvironment _RR;
 	RuntimeEnvironment *RR;
 
 	void *_uPtr; // _uptr (lower case) is reserved in Visual Studio :P
diff --git a/root-topology/test/README.md b/root-topology/test/README.md
new file mode 100644
index 000000000..332f8297f
--- /dev/null
+++ b/root-topology/test/README.md
@@ -0,0 +1,6 @@
+Test Root Topology Script
+======
+
+This builds a test-root-topology from any number of running test-supernode-# Docker containers. This can then be used with the (undocumented) -T (override root topology) option to run test networks under Docker.
+
+Once you have a local Docker test network running you can use iptables rules to simulate a variety of network pathologies, or you can just use it to test any new changes to the protocol or node behavior at some limited scale.
diff --git a/root-topology/test/create-test-root-topology.sh b/root-topology/test/create-test-root-topology.sh
new file mode 100755
index 000000000..032d9c2e5
--- /dev/null
+++ b/root-topology/test/create-test-root-topology.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+if [ ! -e ../mktopology ]; then
+	echo 'Build ../mktopology first!'
+	exit 1
+fi
+
+echo 'Populating supernodes/* with all Docker test-supernode-* container IPs and identities...'
+
+rm -rf supernodes
+mkdir supernodes
+
+for cid in `docker ps -f 'name=test-supernode-*' -q`; do
+	id=`docker exec $cid cat /var/lib/zerotier-one/identity.public`
+	ztaddr=`echo $id | cut -d : -f 1`
+	ip=`docker exec $cid ifconfig | sed -En 's/127.0.0.1//;s/.*inet (addr:)?(([0-9]*\.){3}[0-9]*).*/\2/p'`
+	echo $cid $ztaddr $id $ip
+	echo "id=$id" >supernodes/$ztaddr
+	echo "udp=$ip/9993" >>supernodes/$ztaddr
+done
+
+echo 'Creating test-root-topology...'
+
+rm -f test-root-topology
+../mktopology >test-root-topology
+
+echo 'Done!'
+echo
+cat test-root-topology
+
+exit 0