You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

354 lines
12 KiB
JavaScript

const { web3 } = require("hardhat");
const { expect } = require("chai");
const { ethers } = require("hardhat");
const { defaultAbiCoder } = require("ethers/lib/utils");
const { isConstructorDeclaration } = require("typescript");
var ToBig = (x) => ethers.BigNumber.from(x);
let ETH = ethers.BigNumber.from(10).pow(18);
describe("Git3 Test", function () {
it("Check Upgradeable", async function () {
let repoName = Buffer.from("test");
let [operator, acc1, acc2] = await ethers.getSigners();
const Git3 = await ethers.getContractFactory("Git3Hub");
const git3 = await Git3.deploy();
await git3.deployed();
let git3Upgraded = await Git3.connect(acc2).deploy();
await git3Upgraded.deployed();
let factory1 = await ethers.getContractFactory("UpgradeableProxy");
// Proxy don't need to init Git3 contract because the constructor is empty.
let initSelector = "0x";
let proxyInstance = await factory1
.connect(operator)
.deploy(git3.address, acc1.address, initSelector);
await proxyInstance.deployed();
let git3Proxy = await ethers.getContractAt(
"Git3Hub",
proxyInstance.address
);
await git3Proxy.createRepo(repoName);
await git3Proxy.upload(repoName, "0x616263", "0x112233");
expect(await git3Proxy.download(repoName, "0x616263")).to.eql([
"0x112233",
true,
]);
const adminSlot =
"0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103";
let actualAdmin = await web3.eth.getStorageAt(
proxyInstance.address,
adminSlot
);
let actualA = web3.utils.toBN(actualAdmin).toString();
let expectA = web3.utils.toBN(acc1.address).toString();
expect(actualA).to.equal(expectA);
await proxyInstance.connect(acc1).changeAdmin(acc2.address);
actualAdmin = await web3.eth.getStorageAt(proxyInstance.address, adminSlot);
actualA = web3.utils.toBN(actualAdmin).toString();
expectA = web3.utils.toBN(acc2.address).toString();
expect(actualA).to.equal(expectA);
const ImplementationSlot =
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc";
let actualImplement = await web3.eth.getStorageAt(
proxyInstance.address,
ImplementationSlot
);
let actualI = web3.utils.toBN(actualImplement).toString();
let expectI = web3.utils.toBN(git3.address).toString();
expect(actualI).to.equal(expectI);
//****upgrade contract***//
// await expect(proxyInstance.connect(acc2).upgradeToAndCall(git3Upgraded.address,initSelector)).to.be.revertedWith("Initializable: contract is already initialized")
await proxyInstance.connect(acc2).upgradeTo(git3Upgraded.address);
actualImplement = await web3.eth.getStorageAt(
proxyInstance.address,
ImplementationSlot
);
actualI = web3.utils.toBN(actualImplement).toString();
expectI = web3.utils.toBN(git3Upgraded.address).toString();
expect(actualI).to.equal(expectI);
expect(await git3Proxy.download(repoName, "0x616263")).to.eql([
"0x112233",
true,
]);
});
it("upload/download/remove", async function () {
const Git3 = await ethers.getContractFactory("Git3Hub");
const git3 = await Git3.deploy();
await git3.deployed();
let singer;
[singer] = await ethers.getSigners();
const repoName = Buffer.from("test");
await git3.createRepo(repoName);
await git3.upload(repoName, "0x616263", "0x112233");
expect(await git3.download(repoName, "0x616263")).to.eql([
"0x112233",
true,
]);
let data = Array.from({ length: 40 }, () =>
Math.floor(Math.random() * 256)
);
await git3.upload(repoName, "0x616263", data);
expect(await git3.download(repoName, "0x616263")).to.eql([
ethers.utils.hexlify(data),
true,
]);
expect(await git3.size(repoName, "0x616263")).to.eql([ToBig(40), ToBig(1)]);
await git3.remove(repoName, "0x616263");
expect(await git3.size(repoName, "0x616263")).to.eql([ToBig(0), ToBig(0)]);
});
it("upload/download/remove chunks", async function () {
const Git3 = await ethers.getContractFactory("Git3Hub");
const git3 = await Git3.deploy();
await git3.deployed();
const repoName = Buffer.from("test");
await git3.createRepo(repoName);
expect(await git3.countChunks(repoName, "0x616263")).to.eql(ToBig(0));
let data0 = Array.from({ length: 10 }, () =>
Math.floor(Math.random() * 256)
);
await git3.uploadChunk(repoName, "0x616263", 0, data0);
expect(await git3.download(repoName, "0x616263")).to.eql([
ethers.utils.hexlify(data0),
true,
]);
let data1 = Array.from({ length: 20 }, () =>
Math.floor(Math.random() * 256)
);
await git3.uploadChunk(repoName, "0x616263", 1, data1);
expect(await git3.download(repoName, "0x616263")).to.eql([
ethers.utils.hexlify(data0.concat(data1)),
true,
]);
await git3.remove(repoName, "0x616263"); // should succeed
expect(await git3.size(repoName, "0x616263")).to.eql([ToBig(0), ToBig(0)]);
expect(await git3.download(repoName, "0x616263")).to.eql(["0x", false]);
expect(await git3.countChunks(repoName, "0x616263")).to.eql(ToBig(0));
});
it("set/update/list/remove Reference", async function () {
const Git3 = await ethers.getContractFactory("Git3Hub");
const git3 = await Git3.deploy();
await git3.deployed();
let repoName = Buffer.from("test");
await git3.createRepo(repoName);
function concatHexStr(s1, s2) {
return "0x" + Buffer.concat([s1, Buffer.from("/"), s2]).toString("hex");
}
let key0 = Buffer.from("refs/heads/master");
let data0 = "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
await git3.setRef(repoName, key0, data0);
let key1 = Buffer.from("refs/heads/dev");
let data1 = "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
await git3.setRef(repoName, key1, data1);
let key2 = Buffer.from("refs/heads/main");
let data2 = "0xcccccccccccccccccccccccccccccccccccccccc";
await git3.setRef(repoName, key2, data2);
let refs = await git3.listRefs(repoName);
expect(refs[0]).to.eql([data0, concatHexStr(repoName, key0)]);
expect(refs[1]).to.eql([data1, concatHexStr(repoName, key1)]);
expect(refs[2]).to.eql([data2, concatHexStr(repoName, key2)]);
expect(refs.length).to.eql(3);
// check delRef
await git3.delRef(repoName, key0);
refs = await git3.listRefs(repoName);
expect(refs[0]).to.eql([data2, concatHexStr(repoName, key2)]);
expect(refs[1]).to.eql([data1, concatHexStr(repoName, key1)]);
expect(refs.length).to.eql(2);
await git3.delRef(repoName, key1);
refs = await git3.listRefs(repoName);
expect(refs[0]).to.eql([data2, concatHexStr(repoName, key2)]);
expect(refs.length).to.eql(1);
// check update
let data3 = "0xdddddddddddddddddddddddddddddddddddddddd";
await git3.setRef(repoName, key2, data3);
refs = await git3.listRefs(repoName);
expect(refs[0]).to.eql([data3, concatHexStr(repoName, key2)]);
});
it("Access Control", async function () {
const Git3 = await ethers.getContractFactory("Git3Hub");
const git3 = await Git3.deploy();
await git3.deployed();
let singer;
let user1;
[singer, user1] = await ethers.getSigners();
const repoName = Buffer.from("test");
await git3.connect(singer).createRepo(repoName);
await expect(
git3.connect(user1).upload(repoName, "0x616263", "0x112233")
).to.be.revertedWith("only owner");
await expect(
git3.connect(user1).uploadChunk(repoName, "0x616263", 0, "0x112233")
).to.be.revertedWith("only owner");
await expect(
git3
.connect(user1)
.setRef(
repoName,
"0x616263",
"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
)
).to.be.revertedWith("only owner");
await git3.connect(singer).upload(repoName, "0x616263", "0x112233");
expect(await git3.download(repoName, "0x616263")).to.eql([
"0x112233",
true,
]);
await git3
.connect(singer)
.setRef(
repoName,
"0x616263",
"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
);
await expect(
git3.connect(user1).remove(repoName, "0x616263")
).to.be.revertedWith("only owner");
await expect(
git3.connect(user1).delRef(repoName, "0x616263")
).to.be.revertedWith("only owner");
});
it("RepoName Check", async function () {
const Git3 = await ethers.getContractFactory("Git3Hub");
const git3 = await Git3.deploy();
await git3.deployed();
let repoName = Buffer.from(
"abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ.-_"
);
await git3.createRepo(repoName);
await expect(git3.createRepo(repoName)).to.be.revertedWith(
"RepoName already exist"
);
await expect(git3.createRepo(Buffer.from("a/b"))).to.be.revertedWith(
"RepoName must be alphanumeric or -._"
);
await expect(
git3.createRepo(Buffer.from("a".repeat(101)))
).to.be.revertedWith("RepoName length must be 1-100");
});
it("Get the stake number of chunks", async function () {
const Git3 = await ethers.getContractFactory("Git3Hub");
const git3 = await Git3.deploy();
await git3.deployed();
const repoName = Buffer.from("test");
await git3.createRepo(repoName);
let stakeNum1 = ETH;
let stakeNum2 = ToBig(2).mul(ETH);
let data0 = Array.from({ length: 1024 }, () =>
Math.floor(Math.random() * 256)
);
await git3.uploadChunk(repoName, "0x616263", 0, data0, {
value: stakeNum1,
});
expect(await git3.download(repoName, "0x616263")).to.eql([
ethers.utils.hexlify(data0),
true,
]);
let data1 = Array.from({ length: 1024 }, () =>
Math.floor(Math.random() * 256)
);
await git3.uploadChunk(repoName, "0x616263", 1, data1, {
value: stakeNum2,
});
expect(await git3.download(repoName, "0x616263")).to.eql([
ethers.utils.hexlify(data0.concat(data1)),
true,
]);
let stakeNum = await git3.stakeTokens(repoName, "0x616263");
expect(stakeNum).to.equal(stakeNum1.add(stakeNum2));
let actualStakeNum1 = await git3.chunkStakeTokens(repoName, "0x616263", 0);
let actualStakeNum2 = await git3.chunkStakeTokens(repoName, "0x616263", 1);
expect(actualStakeNum1).to.equal(stakeNum1);
expect(actualStakeNum2).to.equal(stakeNum2);
// check that the stake numer of chunk after removing chunks
await git3.remove(repoName, "0x616263"); // should succeed
stakeNum = await git3.stakeTokens(repoName, "0x616263");
actualStakeNum1 = await git3.chunkStakeTokens(repoName, "0x616263", 0);
actualStakeNum2 = await git3.chunkStakeTokens(repoName, "0x616263", 1);
expect(stakeNum).to.equal(ToBig(0));
expect(actualStakeNum1).to.equal(ToBig(0));
expect(actualStakeNum2).to.equal(ToBig(0));
});
it("Refund to user directly after removing chunk", async function () {
const Git3 = await ethers.getContractFactory("Git3Hub");
const git3 = await Git3.deploy();
await git3.deployed();
let signer;
[signer] = await ethers.getSigners();
const repoName = Buffer.from("test");
await git3.createRepo(repoName);
stakeNum1 = ETH;
stakeNum2 = ToBig(2).mul(ETH);
let data0 = Array.from({ length: 2 }, () =>
Math.floor(Math.random() * 256)
);
await git3.connect(signer).uploadChunk(repoName, "0x616263", 0, data0, {
value: stakeNum1,
});
// check that the stake numer of chunk after removing chunks
let balBefore = await signer.getBalance();
let tx1 = await git3.removeChunk(repoName, "0x616263", 0); // should succeed
let rec1 = await tx1.wait();
let removeTxCost = rec1.gasUsed.mul(rec1.effectiveGasPrice);
let balAfter = await signer.getBalance();
// check balance after refunding
expect(balBefore.add(stakeNum1).sub(removeTxCost)).to.eq(balAfter);
});
});