From 489eb434f7bf5d192ceceb62ab9ebfc4f23f2aad Mon Sep 17 00:00:00 2001 From: Leigh <351529+leighmcculloch@users.noreply.github.com> Date: Wed, 25 Mar 2026 08:23:51 +1000 Subject: [PATCH 1/6] add libfaketime support to container image --- Dockerfile | 5 ++++ README.md | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++ dependencies | 3 +- faketimerc | 1 + start | 4 ++- 5 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 faketimerc diff --git a/Dockerfile b/Dockerfile index f279a02e8..ccbc8c199 100644 --- a/Dockerfile +++ b/Dockerfile @@ -265,4 +265,9 @@ ADD futurenet /opt/stellar-default/futurenet ADD start / RUN ["chmod", "+x", "start"] +RUN ln -s /usr/lib/*/faketime/libfaketime.so.1 /usr/lib/libfaketime.so.1 +RUN echo "+0" > /etc/faketimerc +RUN echo /usr/lib/libfaketime.so.1 > /etc/ld.so.preload +ENV FAKETIME_NO_CACHE=1 + ENTRYPOINT ["/start"] diff --git a/README.md b/README.md index 19c0bdfb1..0fe51e2a2 100644 --- a/README.md +++ b/README.md @@ -409,6 +409,87 @@ image then build that image specifying its tag name: make build TAG=mytag ``` +### Modifying Time + +The image includes [libfaketime](https://github.com/wolfcw/libfaketime) which allows modifying the time seen by all processes in the container without affecting the host system. Time modifications are controlled by writing values to the `/etc/faketimerc` file inside the container. Changes take effect immediately for all services. + +By default the file contains `+0` which means no time modification. + +> [!WARNING] +> Only move time forward. Moving time backwards will cause unexpected behavior in services that depend on monotonically increasing timestamps, such as ledger close times. + +#### Modifying time of a running container + +Mount a file from the host to `/etc/faketimerc` so that time can be changed by editing the file on the host: + +```shell +$ echo "+0" > faketimerc +$ docker run -d -p "8000:8000" -v "$(pwd)/faketimerc:/etc/faketimerc" --name stellar stellar/quickstart --local +``` + +Then modify time by writing to the file on the host: + +```shell +$ echo "+24h" > faketimerc +``` + +#### Example values + +| Value | Effect | +| --- | --- | +| `+0` | No modification (default) | +| `+24h` | 24 hours in the future | +| `+7d` | 7 days in the future | +| `+1y` | 1 year in the future | +| `+10m` | 10 minutes in the future | +| `+120` | 120 seconds in the future | +| `+0 x2` | No offset, but time passes twice as fast | +| `+0 x0.5` | No offset, but time passes at half speed | +| `+0 x10` | No offset, but time passes 10x faster | +| `+24h x2` | 24 hours in the future, clock running at double speed | + +#### Progressive jumps + +Write successively larger offsets to move time forward in steps: + +```shell +# Jump 24 hours forward +$ docker exec stellar bash -c 'echo "+24h" > /etc/faketimerc' + +# Jump another 24 hours forward (48 hours total) +$ docker exec stellar bash -c 'echo "+48h" > /etc/faketimerc' + +# Jump another 24 hours forward (72 hours total) +$ docker exec stellar bash -c 'echo "+72h" > /etc/faketimerc' + +# Reset to real time +$ docker exec stellar bash -c 'echo "+0" > /etc/faketimerc' +``` + +Note: offsets are always relative to real time, so to move forward in increments you must increase the total offset each time. + +#### Speeding up time + +To make time pass faster without jumping: + +```shell +# Time passes 10x faster +$ docker exec stellar bash -c 'echo "+0 x10" > /etc/faketimerc' + +# Time passes 100x faster +$ docker exec stellar bash -c 'echo "+0 x100" > /etc/faketimerc' + +# Back to normal speed +$ docker exec stellar bash -c 'echo "+0" > /etc/faketimerc' +``` + +Combine an offset with a speed multiplier to jump forward and then continue at an accelerated rate: + +```shell +# Jump 24 hours ahead, then continue at 5x speed +$ docker exec stellar bash -c 'echo "+24h x5" > /etc/faketimerc' +``` + ### Background vs. Interactive containers Docker containers can be run interactively (using the `-it` flags) or in a detached, background state (using the `-d` flag). Many of the example commands below use the `-it` flags to aid in debugging but in many cases you will simply want to run a node in the background. It's recommended that you use the use [the tutorials at docker](https://docs.docker.com/engine/tutorials/usingdocker/) to familiarize yourself with using docker. diff --git a/dependencies b/dependencies index 98d480e1d..1983d2761 100755 --- a/dependencies +++ b/dependencies @@ -15,7 +15,8 @@ apt-retry sh -c 'apt-get update && apt-get install -y curl apt-transport-https \ postgresql-client-14 postgresql-14 postgresql-contrib \ sudo supervisor psmisc \ nginx rsync jq golang-github-pelletier-go-toml netcat-openbsd \ - libunwind8 sqlite3 libc++abi1-20 libc++1-20' + libunwind8 sqlite3 libc++abi1-20 libc++1-20 \ + faketime' apt-get clean rm -rf /var/lib/apt/lists/* diff --git a/faketimerc b/faketimerc new file mode 100644 index 000000000..c13c58b6d --- /dev/null +++ b/faketimerc @@ -0,0 +1 @@ ++0h x1 diff --git a/start b/start index 2ee576b40..1687712bb 100755 --- a/start +++ b/start @@ -816,7 +816,9 @@ function exec_supervisor() { # inherits the env vars of its environment for all subprocesses that get # started. This is problematic for services that use the same environment # variable name for things that the start script does, like NETWORK. - exec env -i supervisord -n -c $SUPHOME/etc/supervisord.conf \ + exec env -i \ + FAKETIME_NO_CACHE="$FAKETIME_NO_CACHE" \ + supervisord -n -c $SUPHOME/etc/supervisord.conf \ > >(sed -u 's/^/supervisor: /') \ 2> >(sed -u 's/^/supervisor: /' >&2) } From f452a2b9abac450a6a7319ce8f55863e7c4dfdc2 Mon Sep 17 00:00:00 2001 From: Leigh <351529+leighmcculloch@users.noreply.github.com> Date: Wed, 25 Mar 2026 11:15:03 +1000 Subject: [PATCH 2/6] merge faketime into apt package list line --- dependencies | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dependencies b/dependencies index 1983d2761..11b35ea6e 100755 --- a/dependencies +++ b/dependencies @@ -15,8 +15,7 @@ apt-retry sh -c 'apt-get update && apt-get install -y curl apt-transport-https \ postgresql-client-14 postgresql-14 postgresql-contrib \ sudo supervisor psmisc \ nginx rsync jq golang-github-pelletier-go-toml netcat-openbsd \ - libunwind8 sqlite3 libc++abi1-20 libc++1-20 \ - faketime' + libunwind8 sqlite3 libc++abi1-20 libc++1-20 faketime' apt-get clean rm -rf /var/lib/apt/lists/* From db82629abfa9ab6c46cbc5860d136bcb0d7e8f31 Mon Sep 17 00:00:00 2001 From: Leigh <351529+leighmcculloch@users.noreply.github.com> Date: Wed, 25 Mar 2026 11:23:19 +1000 Subject: [PATCH 3/6] copy faketimerc into container instead of echo --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index ccbc8c199..2b1cb4b90 100644 --- a/Dockerfile +++ b/Dockerfile @@ -266,7 +266,7 @@ ADD start / RUN ["chmod", "+x", "start"] RUN ln -s /usr/lib/*/faketime/libfaketime.so.1 /usr/lib/libfaketime.so.1 -RUN echo "+0" > /etc/faketimerc +COPY faketimerc /etc/faketimerc RUN echo /usr/lib/libfaketime.so.1 > /etc/ld.so.preload ENV FAKETIME_NO_CACHE=1 From 7e2e4a98af9392956081cb12827f78361aa9f8b4 Mon Sep 17 00:00:00 2001 From: Leigh <351529+leighmcculloch@users.noreply.github.com> Date: Wed, 25 Mar 2026 11:30:41 +1000 Subject: [PATCH 4/6] add stability warning to libfaketime docs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0fe51e2a2..db682438d 100644 --- a/README.md +++ b/README.md @@ -411,7 +411,7 @@ make build TAG=mytag ### Modifying Time -The image includes [libfaketime](https://github.com/wolfcw/libfaketime) which allows modifying the time seen by all processes in the container without affecting the host system. Time modifications are controlled by writing values to the `/etc/faketimerc` file inside the container. Changes take effect immediately for all services. +The image includes [libfaketime](https://github.com/wolfcw/libfaketime) which allows modifying the time seen by all processes in the container without affecting the host system. Time modifications are controlled by writing values to the `/etc/faketimerc` file inside the container. Changes take effect immediately for all services. Modifying time can be unpredictable or unstable, for example very large changes in speed may not be handled well by all services, so this feature is intended for development and testing only. By default the file contains `+0` which means no time modification. From 15f266f6b415985f87a639af0474403383c0e71a Mon Sep 17 00:00:00 2001 From: Leigh <351529+leighmcculloch@users.noreply.github.com> Date: Wed, 25 Mar 2026 11:50:25 +1000 Subject: [PATCH 5/6] replace FAKETIME_NO_CACHE with FAKETIME_CACHE_DURATION --- Dockerfile | 2 +- start | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2b1cb4b90..62e9aad69 100644 --- a/Dockerfile +++ b/Dockerfile @@ -268,6 +268,6 @@ RUN ["chmod", "+x", "start"] RUN ln -s /usr/lib/*/faketime/libfaketime.so.1 /usr/lib/libfaketime.so.1 COPY faketimerc /etc/faketimerc RUN echo /usr/lib/libfaketime.so.1 > /etc/ld.so.preload -ENV FAKETIME_NO_CACHE=1 +ENV FAKETIME_CACHE_DURATION=1 ENTRYPOINT ["/start"] diff --git a/start b/start index 1687712bb..3922fae54 100755 --- a/start +++ b/start @@ -817,7 +817,7 @@ function exec_supervisor() { # started. This is problematic for services that use the same environment # variable name for things that the start script does, like NETWORK. exec env -i \ - FAKETIME_NO_CACHE="$FAKETIME_NO_CACHE" \ + FAKETIME_CACHE_DURATION="$FAKETIME_CACHE_DURATION" \ supervisord -n -c $SUPHOME/etc/supervisord.conf \ > >(sed -u 's/^/supervisor: /') \ 2> >(sed -u 's/^/supervisor: /' >&2) From 59925a56a81d4a56d4bf20ad3dba1409b938aecf Mon Sep 17 00:00:00 2001 From: Leigh <351529+leighmcculloch@users.noreply.github.com> Date: Wed, 25 Mar 2026 12:00:05 +1000 Subject: [PATCH 6/6] replace faketime with libfaketime in apt dependencies --- dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies b/dependencies index 11b35ea6e..de047ef12 100755 --- a/dependencies +++ b/dependencies @@ -15,7 +15,7 @@ apt-retry sh -c 'apt-get update && apt-get install -y curl apt-transport-https \ postgresql-client-14 postgresql-14 postgresql-contrib \ sudo supervisor psmisc \ nginx rsync jq golang-github-pelletier-go-toml netcat-openbsd \ - libunwind8 sqlite3 libc++abi1-20 libc++1-20 faketime' + libunwind8 sqlite3 libc++abi1-20 libc++1-20 libfaketime' apt-get clean rm -rf /var/lib/apt/lists/*