Skip to content

Commit

Permalink
feat(contracts/script): fix registerValidators script
Browse files Browse the repository at this point in the history
  • Loading branch information
mempirate committed Oct 21, 2024
1 parent 069e7f1 commit c4b3d16
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 16 deletions.
5 changes: 5 additions & 0 deletions bolt-contracts/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module bolt-contracts

go 1.22.7

require github.com/supranational/blst v0.3.11
2 changes: 2 additions & 0 deletions bolt-contracts/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4=
github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
41 changes: 41 additions & 0 deletions bolt-contracts/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package main

import (
"encoding/hex"
"fmt"
"os"
"strings"

blst "github.com/supranational/blst/bindings/go"
)

type blsPublicKey = blst.P1Affine

func main() {
if len(os.Args) != 2 {
fmt.Println("Usage: pubkey_to_g1 <pubkey>")
os.Exit(1)
}

pubkey := strings.TrimPrefix(os.Args[1], "0x")

pubkeyBytes, err := hex.DecodeString(pubkey)
if err != nil {
fmt.Println("Failed to decode pubkey:", err)
os.Exit(1)
}

if len(pubkeyBytes) != 48 {
fmt.Println("Invalid pubkey length")
os.Exit(1)
}

G1 := new(blsPublicKey).Uncompress(pubkeyBytes)

serialized := G1.Serialize()

x := serialized[0:48]
y := serialized[48:]

fmt.Printf("0x%x,0x%x\n", x, y)
}
56 changes: 40 additions & 16 deletions bolt-contracts/script/holesky/validators/RegisterValidators.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {Script, console} from "forge-std/Script.sol";
/// @notice Script to register Ethereum validators to Bolt
/// @dev this script reads from the config file in /config/holesky/register_validators.json
contract RegisterValidators is Script {
using BLS12381 for BLS12381.G1Point;

struct RegisterValidatorsConfig {
uint128 maxCommittedGasLimit;
address authorizedOperator;
Expand Down Expand Up @@ -39,41 +41,63 @@ contract RegisterValidators is Script {
return IBoltValidatorsV1(vm.parseJsonAddress(json, ".bolt.validators"));
}

function _parseConfig() public view returns (RegisterValidatorsConfig memory config) {
function _parseConfig() public returns (RegisterValidatorsConfig memory config) {
string memory root = vm.projectRoot();
string memory path = string.concat(root, "/config/holesky/validators.json");
string memory json = vm.readFile(path);

config.authorizedOperator = vm.parseJsonAddress(json, ".authorizedOperator");
config.maxCommittedGasLimit = uint128(vm.parseJsonUint(json, ".maxCommittedGasLimit"));

bytes[] memory pubkeysRaw = vm.parseJsonBytesArray(json, ".pubkeys");
string[] memory pubkeysRaw = vm.parseJsonStringArray(json, ".pubkeys");
BLS12381.G1Point[] memory pubkeys = new BLS12381.G1Point[](pubkeysRaw.length);

for (uint256 i = 0; i < pubkeysRaw.length; i++) {
bytes memory pubkey = pubkeysRaw[i];
require(pubkey.length == 96, "Invalid pubkey length");
string memory pubkey = pubkeysRaw[i];

string[] memory convertCmd = new string[](2);
convertCmd[0] = "./script/pubkey_to_g1_wrapper.sh";
convertCmd[1] = pubkey;

bytes memory output = vm.ffi(convertCmd);
string memory outputStr = string(output);
string[] memory array = vm.split(outputStr, ",");

uint256[2] memory x;
uint256[2] memory y;
uint256[2] memory x = _bytesToParts(vm.parseBytes(array[0]));
uint256[2] memory y = _bytesToParts(vm.parseBytes(array[1]));

// Assuming each coordinate is split into two 32 bytes
x[0] = uint256(bytes32(_slice(pubkey, 0, 32)));
x[1] = uint256(bytes32(_slice(pubkey, 32, 32)));
y[0] = uint256(bytes32(_slice(pubkey, 64, 32)));
y[1] = uint256(bytes32(_slice(pubkey, 96, 32)));
console.logBytes(abi.encodePacked(x));
console.logBytes(abi.encodePacked(y));

pubkeys[i] = BLS12381.G1Point(x, y);

console.log("Registering pubkey:", vm.toString(abi.encodePacked(pubkeys[i].compress())));
}

config.pubkeys = pubkeys;
}

function _slice(bytes memory data, uint256 start, uint256 length) internal pure returns (bytes memory) {
bytes memory part = new bytes(length);
for (uint256 i = 0; i < length; i++) {
part[i] = data[i + start];
function _bytesToParts(
bytes memory data
) public pure returns (uint256[2] memory out) {
require(data.length == 48, "Invalid data length");

uint256 value1;
uint256 value2;

// Load the first 32 bytes into value1
assembly {
value1 := mload(add(data, 32))
}
value1 = value1 >> 128; // Clear unwanted upper bits

// Load the next 16 bytes into value2
assembly {
value2 := mload(add(data, 48))
}
return part;
// value2 = value2 >> 128;

out[0] = value1;
out[1] = value2;
}
}
Binary file added bolt-contracts/script/pubkey_to_g1-darwin-arm64
Binary file not shown.
23 changes: 23 additions & 0 deletions bolt-contracts/script/pubkey_to_g1_wrapper.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash

# Only works on Linux
arch=$(uname -i 2>/dev/null) || arch=$(uname -p)
if [[ $OSTYPE == linux* ]]; then
if [[ $arch == x86_64 ]]; then
./script/pubkey_to_g1-linux-amd64 "$1"
elif [[ $arch == aarch64 ]]; then
./script/pubkey_to_g1-linux-arm64 "$1"
else
exit 1
fi
elif [[ $OSTYPE == darwin* ]]; then
if [[ $arch == arm* ]]; then
./script/pubkey_to_g1-darwin-arm64 "$1"
elif [[ $arch == x86_64 ]]; then
./script/pubkey_to_g1-darwin-amd64 "$1"
else
exit 1
fi
else
exit 1
fi

0 comments on commit c4b3d16

Please sign in to comment.