Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

csc easy deploy with docker #49

Merged
merged 5 commits into from
Jul 31, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,5 @@ jobs:

- name: Build and push image
run: |
docker build . --file docker/Dockerfile --tag ${{ steps.image.outputs.name }}
docker build . --file cicd/Dockerfile --tag ${{ steps.image.outputs.name }}
docker push ${{ steps.image.outputs.name }}
4 changes: 2 additions & 2 deletions .github/workflows/pr_build.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Build custom branch
on:
pull_request_target:
pull_request:
branches:
- master

Expand Down Expand Up @@ -47,5 +47,5 @@ jobs:

- name: Build and push image
run: |
docker build . --file docker/Dockerfile --tag ${{ steps.image.outputs.name }}
docker build . --file cicd/Dockerfile --tag ${{ steps.image.outputs.name }}
docker push ${{ steps.image.outputs.name }}
4 changes: 4 additions & 0 deletions cicd/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
PARENTNET_URL=
SUBNET_URL=
PARENTNET_WALLET_PK=0x2222222222222222222222222222222222222222222222222222222222222222
SUBNET_WALLET_PK=0x1111111111111111111111111111111111111111111111111111111111111111
7 changes: 7 additions & 0 deletions cicd/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules
.env
package-lock.json
mount/*
!mount/placeholder.txt
yarn.lock
other
11 changes: 11 additions & 0 deletions cicd/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM node:20-alpine

COPY . /app

WORKDIR /app
RUN yarn
RUN npx hardhat compile
WORKDIR /app/cicd
RUN yarn

ENTRYPOINT ["node"]
2 changes: 2 additions & 0 deletions cicd/Dockerfile.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
**node_modules
**package-lock.json
70 changes: 70 additions & 0 deletions cicd/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# XDC CSC CICD

## Deploy XDC CSC

#### Step 1: Create a `.env` File

Based on the provided `.env.example`, create your own `.env` file with the following details:

- **`PARENTNET_URL`**: RPC URL for the parentnet endpoint.
- **`SUBNET_URL`**: RPC URL for the subnet.
- **`PARENTNET_WALLET_PK`**: Private key used for CSC deployment, there should be some funds.
- **`SUBNET_WALLET_PK`**: Private key for subnet deployment. (only required for reverse CSC)

#### Step 2: Deploy CSC
You have a choice to deploy one of three types of CSC

Full CSC:

```shell
docker run --env-file .env xinfinorg/csc:latest full.js
```

Reverse CSC:

```shell
docker run --env-file .env xinfinorg/csc:latest reversefull.js
```

Lite CSC:

```shell
docker run --env-file .env xinfinorg/csc:latest lite.js
```


## Deploy XDC CSC at Custom Block Height
#### Step 1: Create a `.env` File to cicd/mount

Based on the provided `.env.example`, create your own `.env` file with the following details:

- **`PARENTNET_URL`**: RPC URL for the parentnet endpoint.
- **`SUBNET_URL`**: RPC URL for the subnet.
- **`PARENTNET_WALLET_PK`**: Private key used for CSC deployment, there should be some funds.
- **`SUBNET_WALLET_PK`**: Private key for subnet deployment. (only required for reverse CSC)

#### Step 2: Create a `deployment.config.json` File to cicd/mount

Check the main README in upper directory and deployment.config.json.example to understand the configurations

#### Step 3: Deploy CSC

You have a choice to deploy one of three types of CSC

Full CSC:

```shell
docker run -v $(pwd)/mount:/app/cicd/mount xinfinorg/csc:latest full.js
```

Reverse CSC:

```shell
docker run -v $(pwd)/mount:/app/cicd/mount xinfinorg/csc:latest reversefull.js
```

Lite CSC:

```shell
docker run -v $(pwd)/mount:/app/cicd/mount xinfinorg/csc:latest lite.js
```
133 changes: 133 additions & 0 deletions cicd/full.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
process.chdir(__dirname);
const { execSync } = require("child_process");
const fs = require("node:fs");
const env = require("dotenv").config({ path: "mount/.env" });
const config = {
relativePath: "../",
};
const u = require("./util.js");

main();

async function main() {
console.log("start deploying full CSC");
initDeployFull();
await configureFiles();
deployFull();
exportFull();
}

function initDeployFull() {
const reqENV = ["PARENTNET_URL", "SUBNET_URL", "PARENTNET_WALLET_PK"];
const isEnabled = reqENV.every((envVar) => envVar in process.env);
if (!isEnabled) {
throw Error(
"incomplete ENVs, require PARENTNET_URL, SUBNET_URL, PARENTNET_WALLET_PK"
);
}
parentnetPK = process.env.PARENTNET_WALLET_PK.startsWith("0x")
? process.env.PARENTNET_WALLET_PK
: `0x${process.env.PARENTNET_WALLET_PK}`;
config["parentnetPK"] = parentnetPK;
config["parentnetURL"] = process.env.PARENTNET_URL;
config["subnetURL"] = process.env.SUBNET_URL;
}

async function configureFiles() {
u.writeEnv(config.parentnetPK, config.relativePath);
u.writeNetworkJson(config);

if (fs.existsSync("./mount/deployment.config.json")) {
const dpjs = JSON.parse(
fs.readFileSync("./mount/deployment.config.json", "utf8")
);
console.log(
"copying mounted deployment.config.json, start subnet block:",
dpjs.subnet.gsbn
);

fs.copyFile(
"mount/deployment.config.json",
`${config.relativePath}/deployment.config.json`,
(err) => {
if (err) {
throw Error("error writing deployment.config.json, " + err);
}
}
);
} else {
gap = await u.getGapSubnet(config);
writeFullDeployJson(gap);
}
}

function deployFull() {
console.log("deploying full csc");
fullDeployOut = u.callExec(
`
cd ${config.relativePath};
npx hardhat run scripts/FullCheckpointDeploy.js --network xdcparentnet
`
);
fullCSC = parseFullOut(fullDeployOut);
config["fullCSC"] = fullCSC;
}

function exportFull() {
console.log(
"SUCCESS deploy full csc, please include the following line in your common.env"
);
console.log(`CHECKPOINT_CONTRACT=${config.fullCSC}\n`);
fs.appendFileSync(
"mount/csc.env",
`\nFULL_CSC=${config.fullCSC}\n`,
"utf-8",
(err) => {
if (err) {
throw Error("error writing mount/csc.env, " + err);
}
}
);
}

function parseFullOut(outString) {
strArr = outString.split("\n");
lastLine = strArr[strArr.length - 1];
if (lastLine == "") {
strArr.pop();
lastLine = strArr[strArr.length - 1];
}
if (lastLine.includes("0x")) {
idx = lastLine.indexOf("0x");
address = lastLine.slice(idx, idx + 42);
return address;
} else {
throw Error("invalid output string: " + outString);
}
}

function writeFullDeployJson(gsbn) {
console.log("writing deployment configuration, start subnet block:", gsbn);
deployJson = {
subnet: {
gap: 450,
epoch: 900,
gsbn: gsbn,
},
};
fs.writeFileSync(
`${config.relativePath}/deployment.config.json`,
JSON.stringify(deployJson, null, 2),
"utf-8",
(err) => {
if (err) {
throw Error("error writing deployment.config.json, " + err);
}
}
);
// "subnet": {
// "gap": 450,
// "epoch": 900,
// "gsbn": 1500751
// },
}
129 changes: 129 additions & 0 deletions cicd/lite.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
process.chdir(__dirname);
const { execSync } = require("child_process");
const fs = require("node:fs");
const env = require("dotenv").config({ path: "mount/.env" });
const config = {
relativePath: "../",
};
const u = require("./util.js");

main();

async function main() {
console.log("start deploying lite CSC");
initDeployLite();
await configureFiles();
deployLite();
exportLite();
}

function initDeployLite() {
const reqENV = ["PARENTNET_URL", "SUBNET_URL", "PARENTNET_WALLET_PK"];
const isEnabled = reqENV.every((envVar) => envVar in process.env);
if (!isEnabled) {
throw Error(
"incomplete ENVs, require PARENTNET_URL, SUBNET_URL, PARENTNET_WALLET_PK"
);
}
parentnetPK = process.env.PARENTNET_WALLET_PK.startsWith("0x")
? process.env.PARENTNET_WALLET_PK
: `0x${process.env.PARENTNET_WALLET_PK}`;
config["parentnetPK"] = parentnetPK;
config["parentnetURL"] = process.env.PARENTNET_URL;
config["subnetURL"] = process.env.SUBNET_URL;
}

async function configureFiles() {
u.writeEnv(config.parentnetPK, config.relativePath);
u.writeNetworkJson(config);

if (fs.existsSync("./mount/deployment.config.json")) {
const dpjs = JSON.parse(
fs.readFileSync("./mount/deployment.config.json", "utf8")
);
console.log(
"copying mounted deployment.config.json, start subnet block:",
dpjs.subnet.gsbn
);

fs.copyFile(
"mount/deployment.config.json",
`${config.relativePath}/deployment.config.json`,
(err) => {
if (err) {
throw Error("error writing deployment.config.json, " + err);
}
}
);
} else {
gap = await u.getGapSubnet(config);
writeLiteDeployJson(gap);
}
}

function deployLite() {
console.log("deploying lite csc");
liteDeployOut = u.callExec(
`
cd ${config.relativePath};
npx hardhat run scripts/LiteCheckpointDeploy.js --network xdcparentnet
`
);
liteCSC = parseLiteOut(liteDeployOut);
config["liteCSC"]=liteCSC
}

function exportLite() {
console.log(
"SUCCESS deploy lite csc, please include the following line in your common.env"
);
console.log(`CHECKPOINT_CONTRACT=${config.liteCSC}\n`);
fs.appendFileSync(
"mount/csc.env",
`\nLITE_CSC=${config.liteCSC}\n`,
"utf-8",
(err) => {
if (err) {
throw Error("error writing mount/csc.env, " + err);
}
}
);
}


function parseLiteOut(outString) {
strArr = outString.split("\n");
lastLine = strArr[strArr.length - 1];
if (lastLine == "") {
strArr.pop();
lastLine = strArr[strArr.length - 1];
}
if (lastLine.includes("0x")) {
idx = lastLine.indexOf("0x");
address = lastLine.slice(idx, idx + 42);
return address;
} else {
throw Error("invalid output string: " + outString);
}
}

function writeLiteDeployJson(gsbn) {
console.log("writing deployment configuration, start subnet block:", gsbn);
deployJson = {
subnet: {
gap: 450,
epoch: 900,
gsbn: gsbn,
},
};
fs.writeFileSync(
`${config.relativePath}/deployment.config.json`,
JSON.stringify(deployJson, null, 2),
"utf-8",
(err) => {
if (err) {
throw Error("error writing deployment.config.json, " + err);
}
}
);
}
Empty file added cicd/mount/placeholder.txt
Empty file.
8 changes: 8 additions & 0 deletions cicd/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "csc-cicd",
"dependencies": {
"dotenv": "^16.3.1",
"ethers": "^5.7.2",
"axios": "^1.7.2"
}
}
Loading
Loading