RSK node on an Apple M1 chip architecture?

Following these instructions to install the RSK node on an 2021 MBP with Apple M1 Pro chip. I would like to run an RSK node locally in regtest mode. After installation, running the command to start RSKj:

java \
  -classpath ~/.rsk/rskj-core-3.1.0-IRIS-all.jar \
  -Drpc.providers.web.cors=\* \
  -Drpc.providers.web.ws.enabled=true \
  co.rsk.Start \
  --regtest

... results in the following error:

Exception in thread "main" java.lang.UnsatisfiedLinkError: Could not load library. Reasons: [no leveldbjni in java.library.path, /private/var/folders/40/k7t383452q75nkmr_5kl12_80000gn/T/libleveldbjni-64-8276576211622720497.jnilib: dlopen(/private/var/folders/40/k7t383452q75nkmr_5kl12_80000gn/T/libleveldbjni-64-8276576211622720497.jnilib, 0x0001): tried: '/private/var/folders/40/k7t383452q75nkmr_5kl12_80000gn/T/libleveldbjni-64-8276576211622720497.jnilib' (fat file, but missing compatible architecture (have 'x86_64,i386', need 'arm64e')), '/usr/lib/libleveldbjni-64-8276576211622720497.jnilib' (no such file)]
        at org.fusesource.hawtjni.runtime.Library.doLoad(Library.java:182)
        at org.fusesource.hawtjni.runtime.Library.load(Library.java:140)
        at org.fusesource.leveldbjni.JniDBFactory.<clinit>(JniDBFactory.java:48)
        at org.ethereum.datasource.LevelDbDataSource.init(LevelDbDataSource.java:104)
        at org.ethereum.datasource.LevelDbDataSource.makeDataSource(LevelDbDataSource.java:70)
        at co.rsk.RskContext.buildTrieStore(RskContext.java:1031)
        at co.rsk.RskContext.buildAbstractTrieStore(RskContext.java:951)
        at co.rsk.RskContext.getTrieStore(RskContext.java:408)
        at co.rsk.RskContext.buildRepositoryLocator(RskContext.java:1073)
        at co.rsk.RskContext.getRepositoryLocator(RskContext.java:384)
        at co.rsk.RskContext.getTransactionPool(RskContext.java:353)
        at co.rsk.RskContext.buildInternalServices(RskContext.java:844)
        at co.rsk.RskContext.buildNodeRunner(RskContext.java:836)
        at co.rsk.RskContext.getNodeRunner(RskContext.java:302)
        at co.rsk.Start.main(Start.java:34)

Looks like the most likely problem is an incompatibility of something within RSKj with my chip architecture. Is there a workaround that will allow RSKj to run with an M1 chip?


Solution 1:

You can try to use Rosetta to run x86 code on M1. Just add arch -x86_64 at the begin of your command.

arch -x86_64 java \
  -classpath ~/.rsk/rskj-core-3.1.0-IRIS-all.jar \
  -Drpc.providers.web.cors=\* \
  -Drpc.providers.web.ws.enabled=true \
  co.rsk.Start \
  --regtest

Solution 2:

You are right, the problem is with the leveldbjni dependency, which is not running on aarch64 architecture. However, one can get around this limitation by running RSK node in a Docker container. This process is described in detail in the Docker installation instructions on the RSK devportal.

Summary:

You can install Docker running

brew install --cask docker

Register a free Docker account, login to your installed desktop app and then in the terminal run

docker run rsksmart/rskj-standalone

Then you should download Dockerfile.RegTest and supervisord.conf from artifacts repo and in the same folder execute:

docker buildx build --platform linux/amd64 -t regtest -f Dockerfile.RegTest .

When the build finishes, you have a container ready to run RSK. To run the container, you should execute

docker run -d --name regtest-node-01  -p 4444:4444 -p 30305:30305 regtest

Now your local test RSK node will be running ready for testing your smart contracts.