# Quorum Genesis Tool Review and Key Structure Analysis

**Date**: $(date)  
**References**: 
- [quorum-genesis-tool](https://github.com/ConsenSys/quorum-genesis-tool)
- [Hyperledger Besu GitHub Repository](https://github.com/hyperledger/besu)
- [Besu User Documentation](https://besu.hyperledger.org)

## Overview

The [quorum-genesis-tool](https://github.com/ConsenSys/quorum-genesis-tool) is the standard tool for generating Besu/QBFT network configuration, keys, and genesis files. This document reviews the tool's structure and compares it with our current implementation.

## Quorum Genesis Tool Structure

### Standard Output Structure

```
output/
├── besu/
│   ├── static-nodes.json           # List of static nodes for peering
│   ├── genesis.json                # Genesis file for HLF Besu nodes
│   └── permissioned-nodes.json     # Local permissions for Besu nodes
│
├── validator0/                     # Validator node keys
│   ├── nodekey                     # Node private key
│   ├── nodekey.pub                 # Node's public key (used in enode)
│   └── address                     # Validator address (used to vote validators in/out)
│
├── validator1/
│   └── [same structure]
│
├── validatorN/
│   └── [same structure]
│
├── member0/                        # Member nodes (used for Sentries and RPC)
│   ├── nodekey                     # Node private key
│   └── nodekey.pub                 # Node's public key (used in enode)
│
├── memberN/
│   └── [same structure]
│
├── bootnodeN/                      # Bootnode keys (if generated)
│   ├── nodekey
│   └── nodekey.pub
│
└── userData.json                   # Answers provided in a single map
```

### Key File Naming Conventions

**Validators**:
- `nodekey` - Private key (hex-encoded)
- `nodekey.pub` - Public key (hex-encoded, used for enode URL)
- `address` - Validator Ethereum address (used for voting)

**Members (Sentries/RPC)**:
- `nodekey` - Private key
- `nodekey.pub` - Public key

## Current Source Project Structure

### Actual Structure in `smom-dbis-138/keys/validators/`

```
keys/validators/
├── validator-1/
│   ├── address.txt                 # Validator address (161 bytes)
│   ├── key.priv                    # Private key (65 bytes, hex-encoded)
│   ├── key.pem                     # Private key (PEM format, 223 bytes)
│   └── pubkey.pem                  # Public key (PEM format, 174 bytes)
│
├── validator-2/
│   └── [same structure]
│
├── validator-3/
│   └── [same structure]
│
└── validator-4/
    └── [same structure]
```

### Key Mapping Comparison

| quorum-genesis-tool | Current Source Project | Purpose |
|---------------------|------------------------|---------|
| `nodekey` | `key.priv` | Private key (hex) |
| `nodekey.pub` | `pubkey.pem` | Public key (for enode) |
| `address` | `address.txt` | Validator address |
| N/A | `key.pem` | Private key (PEM format) |

## Differences and Compatibility

### 1. File Naming

**Current**: Uses `key.priv`, `pubkey.pem`, `address.txt`  
**quorum-genesis-tool**: Uses `nodekey`, `nodekey.pub`, `address`

**Impact**: 
- ✅ Functionally compatible (same key data, different names)
- ⚠️ Scripts need to handle both naming conventions
- ✅ PEM format in current structure is acceptable (Besu supports both hex and PEM)

### 2. File Format

**Current**:
- Private key: Hex-encoded (`key.priv`) AND PEM format (`key.pem`)
- Public key: PEM format (`pubkey.pem`)

**quorum-genesis-tool**:
- Private key: Hex-encoded (`nodekey`)
- Public key: Hex-encoded (`nodekey.pub`)

**Impact**:
- ✅ Both formats are supported by Besu
- ✅ Current structure provides more flexibility (PEM + hex)
- ✅ Deployment scripts should handle both formats

### 3. Missing 5th Validator

**Current**: 4 validators (validator-1 through validator-4)  
**Required**: 5 validators (for VMID 1000-1004)

**Solution Options**:

#### Option A: Use quorum-genesis-tool to Generate 5th Validator

```bash
# Generate single validator key
npx quorum-genesis-tool \
  --consensus qbft \
  --chainID 138 \
  --validators 1 \
  --members 0 \
  --bootnodes 0 \
  --outputPath ./temp-validator5

# Copy generated key structure
cp -r temp-validator5/validator0 keys/validators/validator-5
# Rename files to match current structure
cd keys/validators/validator-5
mv nodekey key.priv
mv nodekey.pub pubkey.pem  # Note: format conversion may be needed
mv address address.txt
```

#### Option B: Generate Key Manually Using Besu

```bash
# Using Besu Docker image
docker run --rm -v "$(pwd)/keys/validators/validator-5:/keys" \
  hyperledger/besu:latest \
  besu operator generate-blockchain-config \
  --config-file=/tmp/config.json \
  --to=/tmp/output \
  --private-key-file-name=key

# Or use OpenSSL for secp256k1 key
openssl ecparam -name secp256k1 -genkey -noout \
  -out keys/validators/validator-5/key.priv

# Extract public key
openssl ec -in keys/validators/validator-5/key.priv \
  -pubout -outform PEM \
  -out keys/validators/validator-5/pubkey.pem
```

#### Option C: Generate Using quorum-genesis-tool for All 5 Validators

```bash
# Regenerate all 5 validators with quorum-genesis-tool
npx quorum-genesis-tool \
  --consensus qbft \
  --chainID 138 \
  --blockperiod 2 \
  --epochLength 30000 \
  --validators 5 \
  --members 0 \
  --bootnodes 0 \
  --outputPath ./output-new

# Copy and convert to match current structure
```

## Recommendations

### 1. Standardize on quorum-genesis-tool Structure (LONG TERM)

**Benefits**:
- Industry standard
- Consistent with Besu documentation
- Better compatibility with tooling

**Migration Steps**:
1. Regenerate all keys using quorum-genesis-tool
2. Update deployment scripts to use `nodekey`/`nodekey.pub` naming
3. Update documentation

### 2. Generate 5th Validator Now (SHORT TERM)

**Recommended Approach**: Use Besu to generate 5th validator key in current format

**Why**:
- Maintains compatibility with existing scripts
- No need to update deployment scripts immediately
- Can migrate to quorum-genesis-tool structure later

**Steps**:
1. Generate validator-5 key using current structure
2. Ensure it matches existing validator key format
3. Add to genesis.json alloc if needed
4. Verify deployment scripts handle it correctly

### 3. Script Compatibility

Update deployment scripts to handle both naming conventions:

```bash
# Pseudo-code for key detection
if [ -f "$key_dir/nodekey" ]; then
    # quorum-genesis-tool format
    PRIVATE_KEY="$key_dir/nodekey"
    PUBLIC_KEY="$key_dir/nodekey.pub"
elif [ -f "$key_dir/key.priv" ]; then
    # Current format
    PRIVATE_KEY="$key_dir/key.priv"
    PUBLIC_KEY="$key_dir/pubkey.pem"
fi
```

## Key Generation Commands

### Using quorum-genesis-tool (Recommended for New Networks)

```bash
npx quorum-genesis-tool \
  --consensus qbft \
  --chainID 138 \
  --blockperiod 2 \
  --requestTimeout 10 \
  --epochLength 30000 \
  --validators 5 \
  --members 4 \
  --bootnodes 2 \
  --outputPath ./output
```

### Using Besu (For Single Key Generation)

**Reference**: [Hyperledger Besu GitHub](https://github.com/hyperledger/besu) | [Besu Documentation](https://besu.hyperledger.org)

```bash
# Generate private key (secp256k1)
openssl ecparam -name secp256k1 -genkey -noout \
  -out keys/validators/validator-5/key.priv

# Extract public key (PEM format)
openssl ec -in keys/validators/validator-5/key.priv \
  -pubout -outform PEM \
  -out keys/validators/validator-5/pubkey.pem

# Extract address using Besu CLI (official method)
# Reference: https://besu.hyperledger.org/Reference/CLI/CLI-Subcommands/#public-key
docker run --rm -v "$(pwd)/keys/validators/validator-5:/keys" \
  hyperledger/besu:latest \
  besu public-key export-address \
  --node-private-key-file=/keys/key.priv \
  > keys/validators/validator-5/address.txt
```

## Files Generated by quorum-genesis-tool

### besu/genesis.json
- Network genesis block configuration
- QBFT consensus parameters
- Account allocations (with balances)

### besu/static-nodes.json
- List of static peer nodes (enode URLs)
- Used for faster peering on network startup
- **Note**: IP addresses need to be updated after generation

### besu/permissioned-nodes.json
- Local permissions for Besu nodes
- Node allowlist
- **Note**: Should match static-nodes.json after IP updates

## Integration with Current Project

### Current Scripts Compatibility

**Scripts that use validator keys**:
- `scripts/copy-besu-config.sh` - Copies keys to containers
- `scripts/validate-besu-config.sh` - Validates key presence
- `scripts/fix-besu-services.sh` - Uses keys for validation

**Current Key Detection**:
- Scripts look for `key.priv` or `key.pem` files
- Need to add support for `nodekey` format

### Recommended Update Path

1. **Immediate**: Generate 5th validator key in current format
2. **Short-term**: Update scripts to support both naming conventions
3. **Long-term**: Migrate to quorum-genesis-tool structure

## References

- [quorum-genesis-tool GitHub](https://github.com/ConsenSys/quorum-genesis-tool)
- [Hyperledger Besu GitHub Repository](https://github.com/hyperledger/besu)
- [Besu User Documentation](https://besu.hyperledger.org)
- [Besu Operator Commands](https://besu.hyperledger.org/Reference/CLI/CLI-Subcommands/#operator)
- [Besu Public Key Commands](https://besu.hyperledger.org/Reference/CLI/CLI-Subcommands/#public-key)
- [Besu Key Management](https://besu.hyperledger.org/HowTo/Configure/Keys)
- [QBFT Consensus Documentation](https://besu.hyperledger.org/HowTo/Configure/Consensus-Protocols/QBFT/)

