Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 58 additions & 5 deletions .github/workflows/auto-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,64 @@ jobs:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Read VERSION file
id: get_version
- name: Extract tags from PR labels
id: get_tags_labels
run: |
VERSION=$(cat VERSION)
# Get PR labels and extract version
LABELS='${{ toJson(github.event.pull_request.labels.*.name) }}'
echo "PR Labels: $LABELS"

# Look for version label (e.g., "v1.0.0", "version:1.0.0", etc.)
VERSION=$(echo $LABELS | jq -r '.[] | select(test("^(v|version:)?[0-9]+\\.[0-9]+\\.[0-9]+")) | gsub("^(v|version:)"; "")')

# Look for zeam network tags (devnet0, devnet1, testnet, mainnet)
ZEAM_TAG=$(echo $LABELS | jq -r '.[] | select(test("^(devnet[0-9]+|testnet[0-9]*|mainnet)$"))')

if [ -z "$VERSION" ] || [ "$VERSION" = "null" ]; then
echo "❌ No version label found! Please add a label like 'v1.0.0' or 'version:1.0.0'"
exit 1
fi

# Set outputs
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "tag=v$VERSION" >> $GITHUB_OUTPUT
echo "git_tag=v$VERSION" >> $GITHUB_OUTPUT

if [ -n "$ZEAM_TAG" ] && [ "$ZEAM_TAG" != "null" ]; then
echo "zeam_tag=$ZEAM_TAG" >> $GITHUB_OUTPUT
echo "has_network_tag=true" >> $GITHUB_OUTPUT
echo "✅ Found network tag: $ZEAM_TAG"
else
echo "has_network_tag=false" >> $GITHUB_OUTPUT
echo "ℹ️ No network tag found (optional)"
fi

echo "✅ Version found: $VERSION"

- name: Create and push git tags
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

# Create version tag
if git rev-parse "${{ steps.get_tags_labels.outputs.git_tag }}" >/dev/null 2>&1; then
echo "⚠️ Tag ${{ steps.get_tags_labels.outputs.git_tag }} already exists, skipping"
else
git tag -a "${{ steps.get_tags_labels.outputs.git_tag }}" -m "Release version ${{ steps.get_tags_labels.outputs.version }}"
git push origin "${{ steps.get_tags_labels.outputs.git_tag }}"
echo "✅ Created version tag ${{ steps.get_tags_labels.outputs.git_tag }}"
fi

# Create zeam network tag if network label exists
if [ "${{ steps.get_tags_labels.outputs.has_network_tag }}" = "true" ]; then
ZEAM_GIT_TAG="${{ steps.get_tags_labels.outputs.zeam_tag }}"
if git rev-parse "$ZEAM_GIT_TAG" >/dev/null 2>&1; then
echo "⚠️ Zeam tag $ZEAM_GIT_TAG already exists, skipping"
else
git tag -a "$ZEAM_GIT_TAG" -m "Zeam network tag for ${{ steps.get_tags_labels.outputs.zeam_tag }}"
git push origin "$ZEAM_GIT_TAG"
echo "✅ Created zeam tag $ZEAM_GIT_TAG"
fi
fi

- name: Extract metadata
id: meta
Expand All @@ -48,7 +100,8 @@ jobs:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=latest
type=raw,value=${{ steps.get_version.outputs.version }}
type=raw,value=${{ steps.get_tags_labels.outputs.version }}
type=raw,value=${{ steps.get_tags_labels.outputs.zeam_tag }},enable=${{ steps.get_tags_labels.outputs.has_network_tag }}

- name: Build and push Docker image
uses: docker/build-push-action@v5
Expand Down
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ clap = { version = "4.5", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

# Hex encoding
hex = "0.4"

# Random number generation
rand = "0.9"

1 change: 0 additions & 1 deletion VERSION

This file was deleted.

51 changes: 49 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use hashsig::signature::{
generalized_xmss::instantiations_poseidon_top_level::lifetime_2_to_the_32::hashing_optimized::SIGTopLevelTargetSumLifetime32Dim64Base8,
SignatureScheme,
};
use serde_json::Value;

/// A CLI tool to generate cryptographic keys for hash-based signatures.
#[derive(Parser, Debug)]
Expand Down Expand Up @@ -109,6 +110,44 @@ fn generate_keys(
Ok(())
}

/// Convert pubkey JSON file to hex string
/// Reads the JSON file, extracts root and parameter arrays,
/// converts each u32 to 4 bytes (little-endian), concatenates,
/// and returns hex string with "0x" prefix
fn pubkey_json_to_hex(pk_file_path: &PathBuf) -> Result<String, Box<dyn std::error::Error>> {
// Read JSON file
let json_content = fs::read_to_string(pk_file_path)?;
let json: Value = serde_json::from_str(&json_content)?;

// Extract root array (8 u32 integers)
let root_array = json["root"]
.as_array()
.ok_or("Missing or invalid 'root' array")?;

// Extract parameter array (5 u32 integers)
let param_array = json["parameter"]
.as_array()
.ok_or("Missing or invalid 'parameter' array")?;

// Convert root array to bytes (little-endian)
let mut pubkey_bytes = Vec::new();
for val in root_array {
let num = val.as_u64().ok_or("Invalid number in root array")? as u32;
pubkey_bytes.extend_from_slice(&num.to_le_bytes());
}

// Convert parameter array to bytes (little-endian)
for val in param_array {
let num = val.as_u64().ok_or("Invalid number in parameter array")? as u32;
pubkey_bytes.extend_from_slice(&num.to_le_bytes());
}

// Convert bytes to hex string with "0x" prefix
let hex_string = format!("0x{}", hex::encode(&pubkey_bytes));

Ok(hex_string)
}

fn create_validator_manifest(
output_dir: &PathBuf,
num_validators: usize,
Expand All @@ -132,9 +171,17 @@ fn create_validator_manifest(
writeln!(manifest_file, "validators:")?;

for i in 0..num_validators {
// Read the pubkey JSON file and convert to hex
let pk_file_path = output_dir.join(format!("validator_{}_pk.json", i));
let pubkey_hex = pubkey_json_to_hex(&pk_file_path)
.map_err(|e| std::io::Error::new(
std::io::ErrorKind::Other,
format!("Failed to convert pubkey to hex for validator {}: {}", i, e)
))?;

writeln!(manifest_file, " - index: {}", i)?;
writeln!(manifest_file, " public_key_file: validator_{}_pk.json", i)?;
writeln!(manifest_file, " secret_key_file: validator_{}_sk.json", i)?;
writeln!(manifest_file, " pubkey_hex: {}", pubkey_hex)?;
writeln!(manifest_file, " privkey_file: validator_{}_sk.json", i)?;
if i < num_validators - 1 {
writeln!(manifest_file)?;
}
Expand Down