diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml index 680bfcf..a7f27c2 100644 --- a/.github/workflows/auto-release.yml +++ b/.github/workflows/auto-release.yml @@ -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 @@ -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 diff --git a/Cargo.toml b/Cargo.toml index 6782be1..19ca89c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/VERSION b/VERSION deleted file mode 100644 index 7f20734..0000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -1.0.1 \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index c8c109d..fe05673 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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)] @@ -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> { + // 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, @@ -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)?; }