Nightfall configuration

Nightfall keeps its configurable items in a file config/default.js`. The only exception is some configuration associated with deployment of contracts. Nightfall uses Truffle for deployment and those config items are in nightfall-deployer/truffle-config.js.

Unless you are doing something fairly drastic, such as deploying to a new blockchain or adding a new x509 trust root, there is normally no need to adjust default.js. Most config items work fine with their default values but in any case most can be accessed by setting an environment variable in the container. If you are using the docker-compose scripts, these are designed to pass through any local environment variables into the container, so you can just export whatever variable you want to change. We don't recommend this approach for production but it's a useful test feature.

Here are the main environment variables that you may want to export, for others, please take a look at default.js:

Configuration needed to run a Nightfall node

BLOCKCHAIN_URL: This is the URL of the ws:// RPC port of the Ethereum node that Nightfall should connect to. Something like 'ws://my.geth.node:8546'. Don't use an http:// or any other provider that doesn't support websockets. Nightfall relies on being able to subscribe to blockchain events.

NF_SERVICES_TO_START If you are running a Nightfall node then this environment variable can be used to determine which containers you actually run (running them all results in a very slow start on most machines). A standard node would look like this:

export NF_SERVICES_TO_START='client,optimist,worker'

If you are running a test setup locally, you might want a Ganache blockchain simulator and to deploy contracts. In this case you'd do:

export NF_SERVICES_TO_START='client,optimist,worker,blockchain,deployer'

ENVIRONMENT: This lets you select from a set of pre-defined endpoints for Nightfall in the default.js config file. For example you might want to run on Mumbai with the Nightfall containers hosted on your laptop. ENVIRONMENT will set the endpoints for the containers that you need in one go. It's easy to add new ones if you wish, take a look at the syntax in default.js.

If you wish, you can tweak certain parts of anENVIRONMENT. For example, you could change the proposer URL that is used but keep everything else unchanged, because that value is separately available as an environment variable.

USE_EXTERNAL_NODE If this environment variable is set (to anything other than a null string), Nightfall will assume that there is an Ethereum node up and ready for it to use, and error if this is not the case. It will also attempt to find the Gas price from the node. If not set it will enter a wait loop, polling to see if the Ethereum node has come up. This can be useful if you are starting a node as part of a Nightfall deployment.

PROPOSER_KEY: If running the Proposer app that is provide with the repository, this will set the Ethereum private key that the Proposer uses. It actually sets nf3.ethereumSigningKey in the Proposer's Nf3 instance.

CHALLENGER_KEY: If running the Challenger app that is provide with the repository, this will set the Ethereum private key that the Challenger uses. It actually sets nf3.ethereumSigningKey in the Challenger's Nf3 instance.

FEE_L2_TOKEN_ID : This sets the ERC20 token that users pay fees to Proposers in. It is set at contract deployment. For Mumbai and Polygon PoS it is WMATIC.

ETH_NETWORK : This tells Nightfall which blockchain network it should use in truffle-config.js . It is also used within Nightfall when it's necessary for the application to know what blockchain it is dealing with. Examples are 'mumbai', 'polygonpos', 'blockchain'. The latter is used for a local Ganache instance.

STATE_GENESIS_BLOCK : If either the Client or Optimist containers die then, when they are brought back up, they will resync to Nightfall's Layer 2 transactions, adding any they don't already have. This is exactly analagous to what happens when an Ethereum node is started. They need to search the blockchain calldata history to do this, so it isn't a fast process. We can speed it up a bit (the difference isn't that big actually) by telling Nightfall the number of the Layer 1 block where Nightfall's contracts were first deployed. Obviously there can't be any Nightfall transactions before that point, so we can save time by not searching prior blocks. Setting this variable to the block number at which deployment happened achieves that.

CONFIRMATIONS : Nightfall is reliant on the Layer 1 transactions being final. If a chain-reorg happens and that causes some Nightfall transactions to be lost, then Nightfall's internal state will become invalid beyond that point, and a full resynchronisation of the Nightfall node will be needed. This isn't something we want to happen often. Therefore, Nightfall can be told to wait for a Layer 1 transaction to be confirmed CONFIRMATIONS times before it will treat it as finalised. The default is 12 confirmations.

Additional configuration needed for full deployment of Nightfall

These configuration items would be needed if you are actually deploying Nightfall's smart contracts, i.e. you are creating a new, independent instance of Nightfall. This isn't normally a great idea because you'll limit the anonymity pool that you have access to; but it is useful for testing. Note that you also need some of the above configuration items as they will be applicable in both scenarios.

ETH_PRIVATE_KEY: This is Ethereum signing key that is used to deploy Nightfall's contracts. To maximise security it's best not to reuse it for something else. It's a hex string, but without the leading 0x. This is an exception - Nightfall hex strings should normally begin with 0x.

DEPLOY_MOCKED_SANCTIONS_CONTRACT : Nightfall checks the Chainalysis sanctions-list contract when an account tries to move tokens in or out of Nightfall's Layer 2. It will disallow the transaction if the account's address is on the sanctions list. Of course, that can only work if there actually is a sanctions-list contract on the blockchain that Nightfall is being use on. If there isn't, then it needs to be told that at deployment of its smart contracts and it will then deploy its own mock contract. This will keep Nightfall working but obviously there will be no real sanctions check.

MULTISIG_APPROVERS : As a final act of contract deployment, Nightfall's Deployer container will hand off ownership of the smart contracts from the account associated with ETH_PRIVATE_KEY to a multisig contract SimpleMultiSig.sol. At this point, any function protected by the onlyOwner modifier can only be called by the multisig, with the approval of a set of accounts defined by MULTISIG_APPROVERS. It's used like this:

export MULTISIG_APPROVERS='0x0000000000000000000000000000000000000001,0x0000000000000000000000000000000000000002,0x0000000000000000000000000000000000000003,0x0000000000000000000000000000000000000004'

The publicly deployed Nightfall contracts have MULTISIG_APPROVERS set exactly as above, which makes it impossible to call the onlyOwner protected functions, resulting in a full decentralised deployment.

GAS_PRICE : This is the gas Price that Truffle should use to deploy the Nightfall contracts.

RESTRICT_TOKENS : Nightfall has the ability to restrict both the token (ERC address) and the amount of each token that can be Deposited or Withdrawn in a single transaction (the details are set in default.js). Setting this variable to disable will turn the restriction feature off.

Container URLs

The client and optimist containers (the only ones that an application would connect directly to) expose http:// endpoints on port 80; additionally, Optimist has a websocket port on :8080, which Proposers and Challengers connect to, to receive transactions that they need to sign and post to the blockchain.

These container URLs are mapped to localhost ports in the bin/docker-compose.yml file and can be changed here if you are using docker compose, which you probably shouldn't do in a production situation.

The application that is going to connect to these ports needs, of course, to know about any changes you make. This requires changing the environment object that you pass in when you instantiate the Nf3 class.

There are a number of pre-populated environments in the config/default.js file. You don't have to use these but the default Proposer and Challenger application, and the tests do. In this case the environment object is selected by the ENVIRONMENT environment variable. For example the tests will use localhost but if you run a Nightfall node against Mumbai then mumbai is selected. Here is an example for the localhost environment taken from config/default.js:

  localhost: {
      name: 'Localhost',
      chainId: 1337,
      clientApiUrl: process.env.CLIENT_HOST
        ? `http://${process.env.CLIENT_HOST}:${process.env.CLIENT_PORT}`
        : 'http://localhost:8080',
      optimistApiUrl: process.env.OPTIMIST_HOST
        ? `http://${process.env.OPTIMIST_HOST}:${process.env.OPTIMIST_PORT}`
        : 'http://localhost:8081',
      optimistWsUrl: process.env.OPTIMIST_HOST
        ? `ws://${process.env.OPTIMIST_HOST}:${process.env.OPTIMIST_WS_PORT}`
        : 'ws://localhost:8082',
      proposerBaseUrl: process.env.PROPOSER_HOST
        ? `http://${process.env.PROPOSER_HOST}:${process.env.PROPOSER_PORT}`
        : 'http://localhost:8092',

Specific situations

In the bin/ directory there are a number of .env files that set multiple environment variables. These cover the situation where a Nightfall node is being run locally and connecting to either the Mumbai testnet or the Polygon PoS network. They may be useful as a starting point for other configurations.

Last updated