Skip to content

Commit

Permalink
Run test & build CI
Browse files Browse the repository at this point in the history
  • Loading branch information
m-kus committed May 14, 2024
1 parent 1cb44c5 commit f9f15f6
Show file tree
Hide file tree
Showing 14 changed files with 1,660 additions and 129 deletions.
111 changes: 0 additions & 111 deletions .circleci/config.yml

This file was deleted.

4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
target/
keypair
.env
solidity/cache
56 changes: 56 additions & 0 deletions .github/workflows/packages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Packages

on:
push:
branches:
- 'master'
tags:
- '*.*.*'
pull_request:
branches:
- 'master'

jobs:
build:
name: Build and push docker images to ghcr.io
runs-on: ubuntu-latest
env:
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
DOCKER_REGISTRY: ghcr.io
DOCKER_IMAGE_BASE: ${{ github.repository_owner }}
outputs:
operator: ${{ steps.meta-tezos-operator.outputs.tags }}
steps:
- name: Check out the repo
uses: actions/checkout@v2

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Log in to the registry
uses: docker/login-action@v1
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set image tags & labels
id: meta
uses: docker/metadata-action@v3
with:
images: ${{ env.DOCKER_REGISTRY }}/${{ env.DOCKER_IMAGE_BASE }}/dkg-cli

- name: Image build & push
uses: docker/build-push-action@v2
with:
context: .
platforms: linux/amd64,linux/arm64,
file: crates/dkg-cli/Dockerfile
push: true
cache-from: type=gha
cache-to: type=gha,mode=max
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
32 changes: 32 additions & 0 deletions .github/workflows/releases.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Releases

on:
push:
tags:
- '*.*.*'
pull_request:
branches:
- 'master'

jobs:
build:
name: Build and publish static binaries
runs-on: ubuntu-latest

strategy:
matrix:
target: [x86_64-unknown-linux-gnu, arm-unknown-linux-gnueabihf]

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Setup Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: ${{ matrix.target }}
override: true

- name: Build
run: RUSTFLAGS="-C target-feature=-crt-static" NO_SOLC_BUILD=1 cargo build --release --target=${{ matrix.target }}
4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,9 @@ react-native

solidity/cache
solidity/build
solidity/artifacts
*.swp
*.bin
.DS_Store
*.json
crates/dkg-cli/src/dkg_contract.rs

keypair
dkg-output
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ run:

start:
./target/release/dkg-cli start -n $(NODE_URL) -p $(PRIVATE_KEY) -c $(CONTRACT_ADDRESS)

image:
docker build -t dkg-cli -f crates/dkg-cli/Dockerfile .
19 changes: 8 additions & 11 deletions crates/dkg-cli/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
FROM cimg/rust:1.65.0

ENV HOME=/home/circleci
ENV PATH=$HOME/bin:$PATH

RUN cd $HOME && git clone https://github.com/m-kus/threshold-bls-rs
RUN mkdir $HOME/bin && wget -q https://github.com/ethereum/solidity/releases/download/v0.6.6/solc-static-linux -O $HOME/bin/solc && chmod u+x $HOME/bin/solc && solc --version
RUN cd $HOME && cd threshold-bls-rs/crates/dkg-cli && RUSTFLAGS="-C target-feature=-crt-static" cargo build --release
FROM rust:1.76
WORKDIR /root
COPY . /root/dkg-tooling/
#RUN git clone https://github.com/trilitech/dkg-tooling
RUN cd $HOME/dkg-tooling/crates/dkg-cli \
&& RUSTFLAGS="-C target-feature=-crt-static" NO_SOLC_BUILD=1 cargo build --release

FROM ubuntu:22.04
COPY --from=0 /home/circleci/threshold-bls-rs/target/release/dkg-cli /dkgbin
WORKDIR /dkg
ENTRYPOINT [ "/dkgbin" ]
COPY --from=0 /root/dkg-tooling/target/release/dkg-cli /usr/bin/
ENTRYPOINT [ "dkg-cli" ]
1 change: 0 additions & 1 deletion crates/dkg-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ in the [Solidity docs](https://solidity.readthedocs.io/en/latest/installing-soli


Install the DKG CLI with `cargo build --release`.
We will use the Alfajores testnet for this example, which you can access by using `https://alfajores-forno.celo-testnet.org` as a `NODE_URL`. You can fund your account by inserting your `address` to the [Alfajores faucet](https://celo.org/developers/faucet).

1. `dkg-cli keygen --path ./keypair`

Expand Down
1 change: 1 addition & 0 deletions crates/dkg-cli/artifacts/dkg.bin

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions crates/dkg-cli/artifacts/dkg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"language":"Solidity","sources":{"contracts/DKG.sol":{"content":"// Using the ABIEncoderV2 poses little risk here because we only use it for fetching the byte arrays\n// of shares/responses/justifications\npragma experimental ABIEncoderV2;\npragma solidity ^0.8;\n\ncontract DKG {\n enum UserState {\n CannotRegister,\n CanRegister,\n Registered\n }\n\n /// Mapping of Ethereum Address => UserState for the actions a user can do\n mapping(address => UserState) public userState;\n\n /// Mapping of Ethereum Address => BLS public keys\n mapping(address => bytes) public keys;\n\n /// Mapping of Ethereum Address => DKG Phase 1 Shares\n mapping(address => bytes) public shares;\n\n /// Mapping of Ethereum Address => DKG Phase 2 Responses\n mapping(address => bytes) public responses;\n\n /// Mapping of Ethereum Address => DKG Phase 3 Justifications\n mapping(address => bytes) public justifications;\n\n /// List of registered Ethereum keys (used for conveniently fetching data)\n address[] public participants;\n\n /// The duration of each phase\n uint256 public immutable PHASE_DURATION;\n\n /// The threshold of the DKG\n uint256 public immutable THRESHOLD;\n\n /// If it's 0 then the DKG is still pending start. If >0, it is the DKG's start block\n uint256 public startBlock = 0;\n\n /// The owner of the DKG is the address which can call the `start` function\n address public owner;\n\n /// A registered participant is one whose pubkey's length > 0\n modifier onlyRegistered() {\n require(userState[msg.sender] == UserState.Registered, \"you are not registered!\");\n _;\n }\n\n /// The DKG starts when startBlock > 0\n modifier onlyWhenNotStarted() {\n require(startBlock == 0, \"DKG has already started\");\n _;\n }\n\n constructor(uint256 threshold, uint256 duration) public {\n PHASE_DURATION = duration;\n THRESHOLD = threshold;\n owner = msg.sender;\n }\n\n /// Kickoff function which starts the counter\n function start() external onlyWhenNotStarted {\n require(msg.sender == owner, \"only owner may start the DKG\");\n startBlock = block.number;\n }\n\n /// The administrator must allowlist an addrss for participation in the DKG\n function allowlist(address user) external onlyWhenNotStarted {\n require(msg.sender == owner, \"only owner may allowlist users\");\n\n require(userState[user] == UserState.CannotRegister, \"user is already allowlisted\");\n userState[user] = UserState.CanRegister;\n }\n\n /// This function ties a DKG participant's on-chain address with their BLS Public Key\n function register(bytes calldata blsPublicKey) external onlyWhenNotStarted {\n require(userState[msg.sender] == UserState.CanRegister, \"user is not allowlisted or has already registered\");\n\n participants.push(msg.sender);\n keys[msg.sender] = blsPublicKey;\n\n // the user is now registered\n userState[msg.sender] = UserState.Registered;\n }\n\n /// Participant publishes their data and depending on the phase the data gets inserted\n /// in the shares, responses or justifications mapping. Reverts if the participant\n /// has already published their data for a phase or if the DKG has ended.\n function publish(bytes calldata value) external onlyRegistered {\n uint256 blocksSinceStart = block.number - startBlock;\n\n if (blocksSinceStart <= PHASE_DURATION) {\n require(\n shares[msg.sender].length == 0,\n \"you have already published your shares\"\n );\n shares[msg.sender] = value;\n } else if (blocksSinceStart <= 2 * PHASE_DURATION) {\n require(\n responses[msg.sender].length == 0,\n \"you have already published your responses\"\n );\n responses[msg.sender] = value;\n } else if (blocksSinceStart <= 3 * PHASE_DURATION) {\n require(\n justifications[msg.sender].length == 0,\n \"you have already published your justifications\"\n );\n justifications[msg.sender] = value;\n } else {\n revert(\"DKG has ended\");\n }\n }\n\n // Helpers to fetch data in the mappings. If a participant has registered but not\n // published their data for a phase, the array element at their index is expected to be 0\n\n /// Gets the participants' shares\n function getShares() external view returns (bytes[] memory) {\n bytes[] memory _shares = new bytes[](participants.length);\n for (uint256 i = 0; i < participants.length; i++) {\n _shares[i] = shares[participants[i]];\n }\n\n return _shares;\n }\n\n /// Gets the participants' responses\n function getResponses() external view returns (bytes[] memory) {\n bytes[] memory _responses = new bytes[](participants.length);\n for (uint256 i = 0; i < participants.length; i++) {\n _responses[i] = responses[participants[i]];\n }\n\n return _responses;\n }\n\n /// Gets the participants' justifications\n function getJustifications() external view returns (bytes[] memory) {\n bytes[] memory _justifications = new bytes[](participants.length);\n for (uint256 i = 0; i < participants.length; i++) {\n _justifications[i] = justifications[participants[i]];\n }\n\n return _justifications;\n }\n\n /// Gets the participants' ethereum addresses\n function getParticipants() external view returns (address[] memory) {\n return participants;\n }\n\n /// Gets the participants' BLS keys along with the thershold of the DKG\n function getBlsKeys() external view returns (uint256, bytes[] memory) {\n bytes[] memory _keys = new bytes[](participants.length);\n for (uint256 i = 0; i < participants.length; i++) {\n _keys[i] = keys[participants[i]];\n }\n\n return (THRESHOLD, _keys);\n }\n\n /// Returns the current phase of the DKG.\n function inPhase() public view returns (uint256) {\n if (startBlock == 0) {\n return 0;\n }\n\n uint256 blocksSinceStart = block.number - startBlock;\n\n if (blocksSinceStart <= PHASE_DURATION) {\n return 1;\n }\n\n if (blocksSinceStart <= 2 * PHASE_DURATION) {\n return 2;\n }\n\n if (blocksSinceStart <= 3 * PHASE_DURATION) {\n return 3;\n }\n\n revert(\"DKG Ended\");\n }\n}\n"}},"settings":{"optimizer":{"enabled":false,"runs":200},"outputSelection":{"*":{"":["ast"],"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers"]}},"evmVersion":"shanghai","libraries":{}}}
8 changes: 6 additions & 2 deletions crates/dkg-cli/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ const CONTRACT_PATH: &str = "../../solidity/contracts/DKG.sol";
const CONTRACT_NAME: &str = "DKG";
// Generates the bindings under `src/`
fn main() {
if option_env!("NO_SOLC_BUILD").is_some() {
return;
}

// Only re-run the builder script if the contract changes
println!("cargo:rerun-if-changed={}", PATH);

Expand All @@ -25,7 +29,7 @@ fn main() {
let compiler_output = project.compile().unwrap();
let contract = compiler_output.find(full_path, CONTRACT_NAME).unwrap();

let mut f = File::create("dkg.bin").expect("could not create DKG bytecode file");
let mut f = File::create("artifacts/dkg.bin").expect("could not create DKG bytecode file");
let bytecode: String = contract.bytecode.clone().unwrap().object.encode_hex();

f.write_all(bytecode.as_bytes())
Expand All @@ -46,7 +50,7 @@ fn main() {
let verification_input = project
.standard_json_input(project.sources_path().join("DKG.sol"))
.unwrap();
let mut j = File::create("dkg.json").expect("could not create DKG standard sol input file");
let mut j = File::create("artifacts/dkg.json").expect("could not create DKG standard sol input file");

j.write_all(
serde_json::to_string(&verification_input)
Expand Down
Loading

0 comments on commit f9f15f6

Please sign in to comment.