lotion icon indicating copy to clipboard operation
lotion copied to clipboard

Does not start if genesis is specified

Open hackable opened this issue 5 years ago • 6 comments

It wouldn't start if genesisPath and GCI is specified.

Node v11.8.0

Lotion 0.4.8

lotion({ initialState: { blockNo: 0, txCount: 0 }, ports: { abci: 58354, p2p: 58355, rpc: 58356 }, GCI: '08a5972afaf42e5751cd7f1af542c4e5e259e07dd0d45d31ffba3eaced632549', genesisPath: '/Users/admin/.lotion/networks/806f53597c1bfb8fdd9d128aca662a19/config/genesis.json' })

hackable avatar Feb 08 '19 23:02 hackable

Hey @hackable,

You might want to try enabling the Tendermint logs to debug (run with TM_LOG=true environment variable). A possible issue could be that the node isn't using the validator private key and can't sign blocks.

mappum avatar Feb 09 '19 00:02 mappum

The set home method has bug when genesisPath & keyPath as specified it hashes them and looks for node_keys etc in a different directory


private setHome() {
    /**
     * if genesis and key paths are provided,
     * home path is hash(genesisPath + keyPath)
     *
     * otherwise a random id is generated.
     */
    if (this.config.genesisPath && this.config.keyPath) {
      this.home = join(
        this.lotionHome,
        createHash('sha256')
          .update(fs.readFileSync(this.config.genesisPath))
          .update(fs.readFileSync(this.config.keyPath))
          .digest('hex')
      )
    } else {
      this.home = join(this.lotionHome, randomBytes(16).toString('hex'))
    }
  }
`

hackable avatar Feb 09 '19 01:02 hackable

Will this be fixed anytime soon?

hackable avatar Mar 13 '19 19:03 hackable

Hey @hackable, are you specifying a path to your private key on your validator? (opts.keyPath)

Also it looks like a few of the options you provided aren't valid, double check this section to make sure you're using the correct options.

keppel avatar Mar 13 '19 23:03 keppel

I'm having the same issue. An easy way to reproduce is as follows:

WORKING

const lotion = require('lotion');
const path = require('path');
const { inspect } = require('util');

const networkConfigPath = "./network/config";

async function go() {
  const config = {
    initialState: {
      count: 0,
      accounts: []
    },
    // keyPath: path.join(networkConfigPath, 'node_key_1.json'),       // path to privkey.json. generates own keys if not specified.
    // genesisPath: path.join(networkConfigPath, 'genesis.json'),      // path to genesis.json. generates new one if not specified.
    // peers: [],                                                      // array of '<host>:<p2pport>' of initial tendermint nodes to connect to. does automatic peer discovery if not specified.
    // logTendermint: false,                                           // if true, shows all output from the underlying tendermint process
    // p2pPort: 26658,                                                 // port to use for tendermint peer connections
    // rpcPort: 26657                                                  // port to use for tendermint rpc
  };

  let app = lotion(config);

  app.use(function (state, tx) {
    if (state.count === tx.nonce) {
      state.count++
    }
  });
  console.log("Starting network...");
  const appParams = await app.start();
  console.log(inspect(appParams));
}
go();

Outputs:

Starting network...
{ ports: { abci: 64019, p2p: 64020, rpc: 64021 },
  GCI:
   '25988419385b0e910c5a90ff82eea3c96833c71ec79491998b20d61be70998f4',
  genesisPath:
   '/Users/emizzle/.lotion/networks/ab2af737331159011607eed7a0b13ccf/config/genesis.json',
  home:
   '/Users/emizzle/.lotion/networks/ab2af737331159011607eed7a0b13ccf' }

NOT WORKING:

const lotion = require('lotion');
const path = require('path');
const { inspect } = require('util');

const networkConfigPath = "./network/config";

async function go() {
  const config = {
    initialState: {
      count: 0,
      accounts: []
    },
    // keyPath: path.join(networkConfigPath, 'node_key_1.json'),       // path to privkey.json. generates own keys if not specified.
    genesisPath: path.join(networkConfigPath, 'genesis.json'),      // path to genesis.json. generates new one if not specified.
    // peers: [],                                                      // array of '<host>:<p2pport>' of initial tendermint nodes to connect to. does automatic peer discovery if not specified.
    // logTendermint: false,                                           // if true, shows all output from the underlying tendermint process
    // p2pPort: 26658,                                                 // port to use for tendermint peer connections
    // rpcPort: 26657                                                  // port to use for tendermint rpc
  };

  let app = lotion(config);

  app.use(function (state, tx) {
    if (state.count === tx.nonce) {
      state.count++
    }
  });
  console.log("Starting network...");
  const appParams = await app.start();
  console.log(inspect(appParams));
}
go();

Outputs:

Starting network...

And essentially hangs.

emizzle avatar May 16 '19 11:05 emizzle

The application is hanging because it's waiting for the validators specified in the genesis to come online and start creating blocks.

The genesis says who has the authority to create blocks at the beginning of the chain. So by specifying a genesis, you've said exactly which validators can participate in consensus; they're just not online. When you don't specify a genesis or validator key, Tendermint just generates a new validator key and then makes a genesis where that key has all the authority.

If you provide a path to your validator key in opts.keyPath, the application will start as you expect. Or if you provide a running validator's address in opts.peers.

Perhaps a message explaining this would make sense when an application starts with a genesis but no validator key. (PR's welcome!)

keppel avatar May 16 '19 19:05 keppel